hi,
i am going to the FOSSASIA conference next week, and i wonder if there is
anyone here going too? would be nice to meet and chat...
see fossasia.org for details.
btw: i'll do a workshop about building a REST api in smalltalk at the conference.
greetings, martin.
--
eKita - the online platform for your entire academic life
--
chief engineer eKita.co
pike programmer pike.lysator.liu.se caudium.netsocietyserver.org
secretary beijinglug.org
mentor fossasia.org
foresight developer foresightlinux.orgrealss.com
unix sysadmin
Martin Bähr working in china http://societyserver.org/mbaehr/
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.770.mcz
==================== Summary ====================
Name: Morphic-mt.770
Author: mt
Time: 6 March 2015, 8:44:10.825 am
UUID: c8483e78-e2d0-9747-9517-7b4b51ae1b6d
Ancestors: Morphic-mt.769
Convenience items added to "Windows" menu in world main docking bar to close multiple or all windows at once.
Idea: Clean up the whole world and start a new task with few clicks.
=============== Diff against Morphic-mt.769 ===============
Item was added:
+ ----- Method: TheWorldMainDockingBar>>closeAllWindows (in category 'submenu - windows') -----
+ closeAllWindows
+ self allVisibleWindows do: [:each |
+ each model canDiscardEdits ifTrue: [each delete]]!
Item was added:
+ ----- Method: TheWorldMainDockingBar>>closeAllWindowsButWorkspaces (in category 'submenu - windows') -----
+ closeAllWindowsButWorkspaces
+
+ (UserDialogBoxMorph
+ confirm: 'There might be unsaved changes.\Do you really want to close all windows\that are no workspaces?' withCRs
+ title: 'Only keep workspaces') ifTrue: [
+ self allVisibleWindows
+ reject: [:each | each model isKindOf: Workspace]
+ thenDo: [:each | [each delete] valueSupplyingAnswer: true]].!
Item was added:
+ ----- Method: TheWorldMainDockingBar>>closeAllWindowsUnsafe (in category 'submenu - windows') -----
+ closeAllWindowsUnsafe
+
+ (UserDialogBoxMorph
+ confirm: 'There might be unsaved changes.\Do you really want to close all windows?' withCRs
+ title: 'Close All Windows') ifTrue: [
+ self allVisibleWindows do: [:each | [each delete] valueSupplyingAnswer: true]].!
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;
+ add: 'Close all windows w/o changes' target: self selector: #closeAllWindows;
+ add: 'Close all windows but workspaces' target: self selector: #closeAllWindowsButWorkspaces.!
- action: [ each activateAndForceLabelToShow; expand ] ] ].!
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: 5 March 2015, 12:48:08.103 pm
UUID: 035cb2d1-2807-44b2-8f8e-71c8681c2c97
Ancestors: System-mt.707, System.spur-mt.706
System-mt.707 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.240
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."
+ <primitive: 180>
+ (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."
+ <primitive: 176>
+ ^self primitiveFailed!
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."
+ <primitive: 180>
+ ^(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."
+ <primitive: 176>
+ ^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."
+ <primitive: 178>
+ ^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."
+ <primitive: 178>
+ ^nil!
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: 5 March 2015, 12:48:06.3 pm
UUID: d9900bb6-7097-4d55-9b03-8433d15a53d6
Ancestors: System-mt.706, System.spur-mt.705
System-mt.706 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.240
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."
+ <primitive: 180>
+ (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."
+ <primitive: 176>
+ ^self primitiveFailed!
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."
+ <primitive: 180>
+ ^(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."
+ <primitive: 176>
+ ^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."
+ <primitive: 178>
+ ^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."
+ <primitive: 178>
+ ^nil!
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: 5 March 2015, 12:48:04.493 pm
UUID: aea1ffb7-3847-4aa5-b284-48e9f4589e38
Ancestors: System-mt.705, System.spur-topa.704
System-mt.705 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.240
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."
+ <primitive: 180>
+ (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."
+ <primitive: 176>
+ ^self primitiveFailed!
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."
+ <primitive: 180>
+ ^(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."
+ <primitive: 176>
+ ^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."
+ <primitive: 178>
+ ^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."
+ <primitive: 178>
+ ^nil!
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: 5 March 2015, 12:44:47.947 pm
UUID: ce615558-ce9e-42de-b34c-41301246071d
Ancestors: System-topa.704, System.spur-eem.703
System-topa.704 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.240
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."
+ <primitive: 180>
+ (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."
+ <primitive: 176>
+ ^self primitiveFailed!
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."
+ <primitive: 180>
+ ^(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."
+ <primitive: 176>
+ ^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."
+ <primitive: 178>
+ ^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."
+ <primitive: 178>
+ ^nil!
[Please accept our apologies if you receive multiple copies of this call]
[Please send to interested colleagues / mailing-lists]
************************************************************************************************************
CALL FOR PAPERS
IWST15 — International Workshop on Smalltalk Technologies
Brescia, Italy; July 15, 2015
http://www.esug.org/wiki/pier/Conferences/2015/International-Workshop-IWST_…
************************************************************************************************************
-------------------
Goals and scopes
-------------------
The goals of the workshop is to create a forum around advances or
experience in Smalltalk and to trigger discussions and exchanges of ideas.
The topics of your paper can be on all aspect of Smalltalk, theoretical as
well as practical. Participants are invited to submit research articles or
industrial papers. This year we want to open two different tracks: one
research track and one industrial track with less scientific constraints.
We expect papers of three kinds:
Short position papers describing emerging ideas
Long research papers with deeper description of experiments and of research
results.
Industrial papers with presentation of real and innovative Smalltalk
applications; this kind of paper should enlighten why Smalltalk is really
appropriate for your application.
We will not enforce any length restriction.
--------------------
Important Dates
--------------------
*Submission deadline: April 10th, 2015*
Notification deadline: May 20th, 2015
Workshop : July 15th, 2015
All accepted papers will be published in ACM DL
-------------------
Topics
-------------------
We welcome contributions on all aspects, theoretical as well as practical,
of Smalltalk related topics such as:
-Aspect-oriented programming,
-Design patterns,
-Experience reports,
-Frameworks,
-Implementation, new dialects or languages implemented in Smalltalk,
-Interaction with other languages,
-Meta-programming and Meta-modeling,
-Tools
-------------------
Best Paper Award
-------------------
To encourage the submission of high-quality papers, the IWST organizing
committee is very proud to announce a Best Paper Award for this edition of
IWST.
We thank the Lam Research Corporation for its financial contribution which
makes it possible for prizes for the three best papers: 1000 USD for first
place, 600 USD for second place and 400 USD for third place.
The ranking will be decided by the program committee during the review
process. The awards will be given during the ESUG conference social event.
The Best Paper Award will take place only with a minimum of six
submissions. Notice also that to be eligible, a paper must be presented at
the workshop by one of the author and that the presenting author must be
registered at the ESUG conference.
-------------------
Publication
-------------------
Both submissions and final papers must be prepared using the ACM SIGPLAN 10
point format. Templates for Word and LaTeX are available at
http://www.acm.org/sigs/sigplan/authorInformation.htm. This site also
contains links to useful informations on how to write effective submissions.
-------------------
Submission
-------------------
All submissions must be sent via easychair:
https://easychair.org/conferences/?conf=iwst2015
-------------------
Program chairs
-------------------
Anne Etien (Université de Lille 1, France)
Jannik Laval (Ecole des Mines de Douai, France)
--
~~Jannik Laval~~
École des Mines de Douai
Enseignant-chercheur
http://www.jannik-laval.euhttp://www.phratch.comhttp://www.approchealpes.infohttp://car.mines-douai.fr/
\o/
On 05.03.2015, at 10:44, commits(a)source.squeak.org wrote:
> Marcel Taeumel uploaded a new version of Tools to project The Trunk:
> http://source.squeak.org/trunk/Tools-mt.539.mcz
>
> ==================== Summary ====================
>
> Name: Tools-mt.539
> Author: mt
> Time: 5 March 2015, 11:44:32.854 am
> UUID: 5639bb02-c299-6f46-b201-1251937cc8a3
> Ancestors: Tools-mt.537
>
> Add icons to class list and message list in browsers. Can be turned off in preferences. Icons are stored in ToolIcons (like MenuIcons and HelpIcons do).
>
> =============== Diff against Tools-mt.537 ===============
>
> Item was changed:
> CodeHolder subclass: #Browser
> instanceVariableNames: 'environment systemOrganizer classOrganizer metaClassOrganizer editSelection metaClassIndicated selectedSystemCategory selectedClassName selectedMessageName selectedMessageCategoryName'
> + classVariableNames: 'ListClassesHierarchically RecentClasses ShowClassIcons ShowMessageIcons SortMessageCategoriesAlphabetically'
> - classVariableNames: 'ListClassesHierarchically RecentClasses SortMessageCategoriesAlphabetically'
> poolDictionaries: ''
> category: 'Tools-Browser'!
>
> !Browser commentStamp: 'cwp 12/27/2012 11:09' prior: 0!
> I represent a query path into the class descriptions, the software of the system.!
>
> Item was added: