lists.squeakfoundation.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Vm-dev
September 2018
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
vm-dev@lists.squeakfoundation.org
19 participants
41 discussions
Start a n
N
ew thread
VM Maker: VMMaker.oscog-eem.2438.mcz
by commits@source.squeak.org
09 Sep '18
09 Sep '18
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2438.mcz
==================== Summary ==================== Name: VMMaker.oscog-eem.2438 Author: eem Time: 9 September 2018, 9:16:27.338139 am UUID: 17aec2b1-c603-430a-bd37-c283e35e864f Ancestors: VMMaker.oscog-eem.2437 General robustness, compatibility and cleanups. Make localNameFor: a self send implemented for compatiblity above FileDirectory and FileSystem. Analogously so for uiProcess & vmPath[Size] above Pharo & Squeak. A few fewer isKindOf:s. Fix some receiuvers in NewObjectMemory (can it be that long since we've simulated a V3 image?? Yes :-)) FIx a C compiler warning in returnAs:ThroughCallback:Context:. Fix an MNU in printing incomplete TSend nodes that broke the Pharo6 debugger. =============== Diff against VMMaker.oscog-eem.2437 =============== Item was changed: ----- Method: CCodeGenerator>>isCLiteral: (in category 'C code generator') ----- isCLiteral: anObject + anObject isInteger ifTrue: [^true]. + anObject isString ifTrue: [^true]. + anObject isFloat ifTrue: [^true]. - (anObject isKindOf: Integer) ifTrue: [^true]. - (anObject isKindOf: String) ifTrue: [^true]. - (anObject isKindOf: Float) ifTrue: [^true]. anObject == nil ifTrue: [^true]. anObject == true ifTrue: [^true]. "ikp" anObject == false ifTrue: [^true]. "ikp" + anObject isCharacter ifTrue:[^true]. "ar" - (anObject isKindOf: Character) ifTrue:[^true]. "ar" ^false! Item was changed: ----- Method: CogMethodSurrogate>>+ (in category 'arithmetic') ----- + + anInteger + "N.B. Mimic C semantics so that aCogMethod + 1 is a pointer to the byte past the CogMethod header." + ^address + (anInteger * self class alignedByteSize)! - + aCogMethodOrAddress - ^address + aCogMethodOrAddress asInteger! Item was changed: ----- Method: CogVMSimulator>>imageNamePut:Length: (in category 'file primitives') ----- imageNamePut: p Length: sz | newName window | newName := ByteString new: sz. 1 to: sz do: [:i | newName at: i put: (Character value: (objectMemory byteAt: p + i - 1))]. imageName := newName. (displayView notNil and: [(window := displayView containingWindow) notNil]) ifTrue: [window setLabel: (window label copyReplaceFrom: (window label lastIndexOf: Character space) + 1 to: window label size + with: (self localNameFor: imageName))]! - with: (FileDirectory localNameFor: imageName))]! Item was changed: ----- Method: CogVMSimulator>>openAsMorph (in category 'UI') ----- openAsMorph "Open a morphic view on this simulation." | localImageName borderWidth window | localImageName := imageName + ifNotNil: [self localNameFor: imageName] - ifNotNil: [FileDirectory default localNameFor: imageName] ifNil: [' synthetic image']. window := (SystemWindow labelled: 'Simulation of ', localImageName) model: self. window paneColor: self windowColorToUse. window addMorph: (displayView := SimulatorImageMorph new image: displayForm) frame: (0@0 corner: 1(a)0.8). displayView activeHand addEventListener: self. eventTransformer := SimulatorEventTransformer new. transcript := TranscriptStream on: (String new: 10000). window addMorph: (PluggableTextMorph on: transcript text: nil accept: nil readSelection: nil menu: #codePaneMenu:shifted:) frame: (0(a)0.8 corner: 0.7@1). window addMorph: (PluggableTextMorph on: self text: #byteCountText accept: nil readSelection: nil menu: #utilitiesMenu:) hideScrollBarsIndefinitely frame: (0.7(a)0.8 corner: 1@1). borderWidth := [SystemWindow borderWidth] "Squeak 4.1" on: MessageNotUnderstood do: [:ex| 0]. "3.8" borderWidth := borderWidth + window borderWidth. window openInWorldExtent: (self desiredDisplayExtent + (2 * borderWidth @ borderWidth) + (0@window labelHeight) * (1(a)(1/0.8))) rounded. ^window! Item was changed: ----- Method: CogVMSimulator>>openAsMorphNoTranscript (in category 'UI') ----- openAsMorphNoTranscript "Open a morphic view on this simulation." | localImageName borderWidth window | localImageName := imageName + ifNotNil: [self localNameFor: imageName] - ifNotNil: [FileDirectory default localNameFor: imageName] ifNil: [' synthetic image']. window := (SystemWindow labelled: 'Simulation of ', localImageName) model: self. window paneColor: self windowColorToUse. window addMorph: (displayView := SimulatorImageMorph new image: displayForm) frame: (0@0 corner: 1(a)0.95). displayView activeHand addEventListener: self. eventTransformer := SimulatorEventTransformer new. window addMorph: (PluggableTextMorph on: self text: #byteCountText accept: nil readSelection: nil menu: #utilitiesMenu:) hideScrollBarsIndefinitely frame: (0(a)0.95 corner: 1@1). borderWidth := [SystemWindow borderWidth] "Squeak 4.1" on: MessageNotUnderstood do: [:ex| 0]. "3.8" borderWidth := borderWidth + window borderWidth. window openInWorldExtent: (self desiredDisplayExtent + (2 * borderWidth@borderWidth) + (0@window labelHeight) * (1(a)(1/0.95))) rounded! Item was changed: ----- Method: CogVMSimulator>>vmPathGet:Length: (in category 'file primitives') ----- vmPathGet: stringBase Length: stringSize | pathName stringOop | + pathName := self vmPath. - pathName := Smalltalk vmPath. stringOop := stringBase - objectMemory baseHeaderSize. "Due to C call in Interp" 1 to: stringSize do: [:i | objectMemory storeByte: i-1 ofObject: stringOop withValue: (pathName at: i) asciiValue]. ! Item was removed: - ----- Method: CogVMSimulator>>vmPathSize (in category 'file primitives') ----- - vmPathSize - ^ Smalltalk vmPath size! Item was changed: ----- Method: InterpreterProxy>>is:KindOf: (in category 'testing') ----- is: oop KindOf: aString "InterpreterProxy new is: 42 KindOf: 'Number'" - | theClass | <var: #aString type:'char *'> + (Smalltalk at: aString asSymbol ifAbsent:[nil]) + ifNil:[false] + ifNotNil: [:theClass| oop isKindOf: theClass]! - theClass := Smalltalk at: aString asSymbol ifAbsent:[nil]. - ^theClass isNil - ifTrue:[false] - ifFalse:[^oop isKindOf: theClass]! Item was changed: ----- Method: InterpreterSimulator>>openAsMorph (in category 'UI') ----- openAsMorph "Open a morphic view on this simulation." | window localImageName | localImageName := imageName + ifNotNil: [self localNameFor: imageName] - ifNotNil: [FileDirectory default localNameFor: imageName] ifNil: [' synthetic image']. window := (SystemWindow labelled: 'Simulation of ' , localImageName) model: self. window addMorph: (displayView := ImageMorph new image: displayForm) frame: (0@0 corner: 1(a)0.8). transcript := TranscriptStream on: (String new: 10000). window addMorph: (PluggableTextMorph on: transcript text: nil accept: nil readSelection: nil menu: #codePaneMenu:shifted:) frame: (0(a)0.8 corner: 0.7@1). window addMorph: (PluggableTextMorph on: self text: #byteCountText accept: nil) hideScrollBarsIndefinitely frame: (0.7(a)0.8 corner: 1@1). window openInWorld. ^window! Item was changed: ----- Method: InterpreterSimulator>>vmPathGet:Length: (in category 'file primitives') ----- vmPathGet: stringBase Length: stringSize | pathName stringOop | + pathName := self vmPath. - pathName := Smalltalk vmPath. stringOop := stringBase - self baseHeaderSize. "Due to C call in Interp" 1 to: stringSize do: [:i | self storeByte: i-1 ofObject: stringOop withValue: (pathName at: i) asciiValue]. ! Item was removed: - ----- Method: InterpreterSimulator>>vmPathSize (in category 'file primitives') ----- - vmPathSize - ^ Smalltalk vmPath size! Item was added: + ----- Method: NewObjectMemory>>finalizeReference: (in category 'finalization') ----- + finalizeReference: oop + "During sweep phase we have encountered a weak reference. Check if its object + has gone away (or is about to) and if so, signal a semaphore. Do *not* inline + this in sweepPhase - it is quite an unlikely case to run into a weak reference. + Override to ask the coInterpreter to signal finalization." + | weakOop oopGone chunk numFields firstField lastField | + <inline: false> + <var: #oop type: #usqInt> + <var: #weakOop type: #usqInt> + numFields := self nonWeakFieldsOf: oop. "so nonWeakFieldsOf: may be inlined" + firstField := self baseHeaderSize + (numFields << self shiftForWord). + lastField := self lastPointerOf: oop. + firstField to: lastField by: self wordSize do: + [:i| + weakOop := self longAt: oop + i. + "ar 1/18/2005: Added oop < youngStart test to make sure we're not testing + objects in non-GCable region. This could lead to a forward reference in + old space with the oop pointed to not being marked and thus treated as free." + (weakOop = nilObj or: [(self isIntegerObject: weakOop) or:[weakOop < youngStart]]) ifFalse: + ["Check if the object is being collected. + If the weak reference points + * backward: check if the weakOops chunk is free + * forward: check if the weakOoop has been marked by GC" + weakOop < oop + ifTrue: [chunk := self chunkFromOop: weakOop. + oopGone := ((self longAt: chunk) bitAnd: TypeMask) = HeaderTypeFree] + ifFalse: [oopGone := (self isMarked: weakOop) not]. + oopGone ifTrue: "Store nil in the pointer and signal the interpreter" + [self longAt: oop + i put: nilObj. + self + cppIf: PharoVM + ifTrue: [numFields >= 2 ifTrue: [self weakFinalizerCheck: oop]]. + coInterpreter signalFinalization: oop]]]! Item was changed: ----- Method: NewObjectMemory>>fullGC (in category 'garbage collection') ----- fullGC "Do a mark/sweep garbage collection of the entire object memory. Free inaccessible objects but do not move them." <inline: false> fullGCLock > 0 ifTrue: [self warning: 'aborting fullGC because fullGCLock > 0'. ^self]. self runLeakCheckerFor: GCModeFull. + coInterpreter preGCAction: GCModeFull. - self preGCAction: GCModeFull. needGCFlag := false. gcStartUsecs := self ioUTCMicrosecondsNow. statSweepCount := statMarkCount := statMkFwdCount := statCompMoveCount := 0. self clearRootsTable. self initWeakTableForIncrementalGC: false. youngStart := self startOfMemory. "process all of memory" self markPhase: true. "Sweep phase returns the number of survivors. Use the up-to-date version instead the one from startup." totalObjectCount := self sweepPhaseForFullGC. self runLeakCheckerFor: GCModeFull. self fullCompaction. statFullGCs := statFullGCs + 1. statGCEndUsecs := self ioUTCMicrosecondsNow. statFullGCUsecs := statFullGCUsecs + (statGCEndUsecs - gcStartUsecs). + coInterpreter capturePendingFinalizationSignals. - self capturePendingFinalizationSignals. youngStart := freeStart. "reset the young object boundary" self attemptToShrink. + coInterpreter postGCAction: GCModeFull. - self postGCAction: GCModeFull. self runLeakCheckerFor: GCModeFull! Item was changed: ----- Method: NewObjectMemory>>incrementalGC (in category 'garbage collection') ----- incrementalGC "Do a mark/sweep garbage collection of just the young object area of object memory (i.e., objects above youngStart), using the root table to identify objects containing pointers to young objects from the old object area." | survivorCount weDidGrow | <inline: false> rootTableOverflowed ifTrue: ["root table overflow; cannot do an incremental GC because some roots are missing. (this should be very rare)" statRootTableOverflows := statRootTableOverflows + 1. ^self fullGC]. self runLeakCheckerFor: GCModeNewSpace. coInterpreter preGCAction: GCModeNewSpace. needGCFlag := false. gcStartUsecs := self ioUTCMicrosecondsNow. statSweepCount := statMarkCount := statMkFwdCount := statCompMoveCount := 0. self initWeakTableForIncrementalGC: true. "implicitly process memory from youngStart to freeStart" self markPhase: false. self assert: weakRootCount <= WeakRootTableSize. 1 to: weakRootCount do: [:i| self finalizeReference: (weakRoots at: i)]. survivorCount := self sweepPhase. self runLeakCheckerFor: GCModeNewSpace. self incrementalCompaction. statIncrGCs := statIncrGCs + 1. statGCEndUsecs := self ioUTCMicrosecondsNow. statIGCDeltaUsecs := statGCEndUsecs - gcStartUsecs. statIncrGCUsecs := statIncrGCUsecs + statIGCDeltaUsecs. + coInterpreter capturePendingFinalizationSignals. - self capturePendingFinalizationSignals. statRootTableCount := rootTableCount. statSurvivorCount := survivorCount. weDidGrow := false. (((survivorCount > tenuringThreshold) or: [rootTableCount >= RootTableRedZone]) or: [forceTenureFlag == true]) ifTrue: ["move up the young space boundary if * there are too many survivors: this limits the number of objects that must be processed on future incremental GC's * we're about to overflow the roots table: this limits the number of full GCs that may be caused by root table overflows in the near future" forceTenureFlag := false. statTenures := statTenures + 1. self clearRootsTable. ((self freeSize < growHeadroom) and: [gcBiasToGrow > 0]) ifTrue: [self biasToGrow. weDidGrow := true]. youngStart := freeStart]. self attemptToShrink. coInterpreter postGCAction: GCModeNewSpace. self runLeakCheckerFor: GCModeNewSpace. weDidGrow ifTrue: [self biasToGrowCheckGCLimit]! Item was changed: ----- Method: NewObjectMemory>>initializeMemoryFirstFree: (in category 'initialization') ----- initializeMemoryFirstFree: firstFree "Initialize endOfMemory to the top of oop storage space, reserving some space for forwarding blocks, and set freeStart from which space is allocated." "Note: The amount of space reserved for forwarding blocks should be chosen to ensure that incremental compactions can usually be done in a single pass. However, there should be enough forwarding blocks so a full compaction can be done in a reasonable number of passes, say ten. (A full compaction requires N object-moving passes, where N = number of non-garbage objects / number of forwarding blocks). di 11/18/2000 Re totalObjectCount: Provide a margin of one byte per object to be used for forwarding pointers at GC time. Since fwd blocks are 8 bytes, this means an absolute worst case of 8 passes to compact memory. In most cases it will be adequate to do compaction in a single pass. " | fwdBlockBytes totalReserve | "reserve space for forwarding blocks and the interpreter. We can sacrifice forwarding block space at the cost of slower compactions but we cannot safely sacrifice interpreter allocation headroom." fwdBlockBytes := totalObjectCount bitAnd: WordMask - self wordSize + 1. + totalReserve := fwdBlockBytes + coInterpreter interpreterAllocationReserveBytes. - totalReserve := fwdBlockBytes + self interpreterAllocationReserveBytes. (self oop: memoryLimit - totalReserve isLessThan: firstFree + self baseHeaderSize) ifTrue: ["reserve enough space for a minimal free block of BaseHeaderSize bytes. We are apparently in an emergency situation here because we have no space for reserve and forwarding blocks. But a full GC will occur immediately in sufficientSpaceAfterGC: which will grow memory and restore the reserve." fwdBlockBytes := memoryLimit - (firstFree + self baseHeaderSize)]. "set endOfMemory reserveStart and freeStart" self setEndOfMemory: memoryLimit - fwdBlockBytes. + reserveStart := endOfMemory - coInterpreter interpreterAllocationReserveBytes. - reserveStart := endOfMemory - self interpreterAllocationReserveBytes. freeStart := firstFree. "bytes available for oops" scavengeThreshold := freeStart + edenBytes min: reserveStart. self maybeFillWithAllocationCheckFillerFrom: freeStart to: scavengeThreshold. self assert: (self oop: freeStart isLessThan: reserveStart). "We would like to assert this but can't because in GC situations it may be false. It is established by sufficientSpaceToAllocate: and sufficientSpaceAfterGC:" false ifTrue: [self assert: (self oop: reserveStart isLessThan: endOfMemory)]. self assert: (self oop: endOfMemory isLessThan: memoryLimit)! Item was changed: ----- Method: NewObjectMemory>>markPhase: (in category 'gc -- mark and sweep') ----- markPhase: fullGCFlag "Mark phase of the mark and sweep garbage collector. Set the mark bits of all reachable objects. Free chunks are untouched by this process." "Assume: All non-free objects are initially unmarked. Root objects were unmarked when they were made roots. (Make sure this stays true!!!!)." | oop statMarkCountPriorToStackPageFreeing | <inline: false> "trace the interpreter's objects, including the active stacks and special objects array" + coInterpreter markAndTraceInterpreterOops: fullGCFlag. - self markAndTraceInterpreterOops: fullGCFlag. statSpecialMarkCount := statMarkCount. "trace the roots" 1 to: rootTableCount do: [:i | oop := rootTable at: i. self markAndTrace: oop]. 1 to: extraRootCount do: [:i| oop := (extraRoots at: i) at: 0. ((self isIntegerObject: oop) or: [self isFreeObject: oop]) ifFalse: [self markAndTrace: oop]]. statMarkCountPriorToStackPageFreeing := statMarkCount. "Only safe to free stack pages after all roots have been traced." + coInterpreter markAndTraceAndMaybeFreeStackPages: fullGCFlag. - self markAndTraceAndMaybeFreeStackPages: fullGCFlag. "Only safe to free any machine code methods after all stack pages have been traced." + coInterpreter markAndTraceOrFreeMachineCode: fullGCFlag. - self markAndTraceOrFreeMachineCode: fullGCFlag. statSpecialMarkCount := statSpecialMarkCount + (statMarkCount - statMarkCountPriorToStackPageFreeing)! Item was changed: ----- Method: NewObjectMemory>>storeImageSegmentInto:outPointers:roots: (in category 'image segment in/out') ----- storeImageSegmentInto: segmentWordArray outPointers: outPointerArray roots: arrayOfRoots "This primitive will store a binary image segment (in the same format as the Squeak image file) of the receiver and every object in its proper tree of subParts (ie, that is not refered to from anywhere else outside the tree). All pointers from within the tree to objects outside the tree will be copied into the array of outpointers. In their place in the image segment will be an oop equal to the offset in the outPointer array (the first would be 4). but with the high bit set." "The primitive expects the array and wordArray to be more than adequately long. In this case it returns normally, and truncates the two arrays to exactly the right size. To simplify truncation, both incoming arrays are required to be 256 bytes or more long (ie with 3-word headers). If either array is too small, the primitive will fail, but in no other case. During operation of the primitive, it is necessary to convert from both internal and external oops to their mapped values. To make this fast, the headers of the original objects in question are replaced by the mapped values (and this is noted by adding the forbidden XX header type). Tables are kept of both kinds of oops, as well as of the original headers for restoration. To be specific, there are two similar two-part tables, the outpointer array, and one in the upper fifth of the segmentWordArray. Each grows oops from the bottom up, and preserved headers from halfway up. In case of either success or failure, the headers must be restored. In the event of primitive failure, the table of outpointers must also be nilled out (since the garbage in the high half will not have been discarded." | savedYoungStart lastOut lastIn firstIn lastSeg endSeg segOop fieldPtr fieldOop mapOop doingClass lastPtr extraSize hdrTypeBits hdrBaseIn hdrBaseOut header firstOut versionOffset | <inline: false> <var: #firstIn type: #usqInt> <var: #lastIn type: #usqInt> <var: #firstOut type: #usqInt> <var: #lastOut type: #usqInt> <var: #hdrBaseIn type: #usqInt> <var: #hdrBaseOut type: #usqInt> <var: #lastSeg type: #usqInt> <var: #endSeg type: #usqInt> <var: #fieldPtr type: #usqInt> <var: #lastPtr type: #usqInt> <var: #segOop type: #usqInt> <var: #savedYoungStart type: #usqInt> ((self headerType: outPointerArray) = HeaderTypeSizeAndClass "Must be 3-word header" and: [(self headerType: segmentWordArray) = HeaderTypeSizeAndClass]) "Must be 3-word header" ifFalse: [^PrimErrGenericFailure]. DoAssertionChecks ifTrue: [self verifyCleanHeaders]. "Use the top half of outPointers for saved headers." firstOut := outPointerArray + self baseHeaderSize. lastOut := firstOut - self wordSize. hdrBaseOut := outPointerArray + ((self lastPointerOf: outPointerArray) // (self wordSize*2) * self wordSize). "top half" lastSeg := segmentWordArray. endSeg := segmentWordArray + (self sizeBitsOf: segmentWordArray) - self wordSize. "Write a version number for byte order and version check" versionOffset := self wordSize. lastSeg := lastSeg + versionOffset. lastSeg > endSeg ifTrue: [^PrimErrGenericFailure]. self longAt: lastSeg put: self imageSegmentVersion. "Allocate top 1/8 of segment for table of internal oops and saved headers" firstIn := endSeg - ((self sizeBitsOf: segmentWordArray) // (self wordSize*8) * self wordSize). "Take 1/8 of seg" lastIn := firstIn - self wordSize. hdrBaseIn := firstIn + ((self sizeBitsOf: segmentWordArray) // (self wordSize*16) * self wordSize). "top half of that" "First mark the rootArray and all root objects." self longAt: arrayOfRoots put: ((self longAt: arrayOfRoots) bitOr: MarkBit). lastPtr := arrayOfRoots + (self lastPointerOf: arrayOfRoots). fieldPtr := arrayOfRoots + self baseHeaderSize. [fieldPtr <= lastPtr] whileTrue: [fieldOop := self longAt: fieldPtr. (self isIntegerObject: fieldOop) ifFalse: [self longAt: fieldOop put: ((self longAt: fieldOop) bitOr: MarkBit)]. fieldPtr := fieldPtr + self wordSize]. "Then do a mark pass over all objects. This will stop at our marked roots, thus leaving our segment unmarked in their shadow." savedYoungStart := youngStart. youngStart := self startOfMemory. "process all of memory" + coInterpreter markAndTraceInterpreterOops: false. "and special objects array" - self markAndTraceInterpreterOops: false. "and special objects array" youngStart := savedYoungStart. "Finally unmark the rootArray and all root objects." self longAt: arrayOfRoots put: ((self longAt: arrayOfRoots) bitAnd: AllButMarkBit). fieldPtr := arrayOfRoots + self baseHeaderSize. [fieldPtr <= lastPtr] whileTrue: [fieldOop := self longAt: fieldPtr. (self isIntegerObject: fieldOop) ifFalse: [self longAt: fieldOop put: ((self longAt: fieldOop) bitAnd: AllButMarkBit)]. fieldPtr := fieldPtr + self wordSize]. "All external objects, and only they, are now marked. Copy the array of roots into the segment, and forward its oop." lastIn := lastIn + self wordSize. (lastIn >= hdrBaseIn or: [0 = (lastSeg := self copyObj: arrayOfRoots toSegment: segmentWordArray addr: lastSeg stopAt: firstIn saveOopAt: lastIn headerAt: hdrBaseIn + (lastIn - firstIn))]) ifTrue: [lastIn := lastIn - self wordSize. self restoreHeadersFrom: firstIn to: lastIn from: hdrBaseIn and: firstOut to: lastOut from: hdrBaseOut. ^self primitiveFailCodeAfterCleanup: outPointerArray]. "Now run through the segment fixing up all the pointers. Note that more objects will be added to the segment as we make our way along." segOop := self oopFromChunk: segmentWordArray + versionOffset + self baseHeaderSize. [segOop <= lastSeg] whileTrue: [(self headerType: segOop) <= 1 ifTrue: ["This object has a class field (type=0 or 1) -- start with that." fieldPtr := segOop - self wordSize. doingClass := true] ifFalse: ["No class field -- start with first data field" fieldPtr := segOop + self baseHeaderSize. doingClass := false]. lastPtr := segOop + (self lastPointerOf: segOop). "last field" "Go through all oops, remapping them..." [fieldPtr > lastPtr] whileFalse: ["Examine each pointer field" fieldOop := self longAt: fieldPtr. doingClass ifTrue: [hdrTypeBits := fieldOop bitAnd: TypeMask. fieldOop := fieldOop - hdrTypeBits]. (self isIntegerObject: fieldOop) ifTrue: ["Just an integer -- nothing to do" fieldPtr := fieldPtr + self wordSize] ifFalse: [header := self longAt: fieldOop. (header bitAnd: TypeMask) = HeaderTypeFree ifTrue: ["Has already been forwarded -- this is the link" mapOop := header bitAnd: AllButTypeMask] ifFalse: [((self longAt: fieldOop) bitAnd: MarkBit) = 0 ifTrue: ["Points to an unmarked obj -- an internal pointer. Copy the object into the segment, and forward its oop." lastIn := lastIn + self wordSize. (lastIn >= hdrBaseIn or: [0 = (lastSeg := self copyObj: fieldOop toSegment: segmentWordArray addr: lastSeg stopAt: firstIn saveOopAt: lastIn headerAt: hdrBaseIn + (lastIn - firstIn))]) ifTrue: ["Out of space in segment" lastIn := lastIn - self wordSize. self restoreHeadersFrom: firstIn to: lastIn from: hdrBaseIn and: firstOut to: lastOut from: hdrBaseOut. ^self primitiveFailCodeAfterCleanup: outPointerArray]. mapOop := (self longAt: fieldOop) bitAnd: AllButTypeMask] ifFalse: ["Points to a marked obj -- an external pointer. Map it as a tagged index in outPointers, and forward its oop." lastOut := lastOut + self wordSize. lastOut >= hdrBaseOut ifTrue: ["Out of space in outPointerArray" lastOut := lastOut - self wordSize. self restoreHeadersFrom: firstIn to: lastIn from: hdrBaseIn and: firstOut to: lastOut from: hdrBaseOut. ^self primitiveFailCodeAfterCleanup: outPointerArray]. . mapOop := lastOut - outPointerArray bitOr: 16r80000000. self forward: fieldOop to: mapOop savingOopAt: lastOut andHeaderAt: hdrBaseOut + (lastOut - firstOut)]]. "Replace the oop by its mapped value" doingClass ifTrue: [self longAt: fieldPtr put: mapOop + hdrTypeBits. fieldPtr := fieldPtr + (self wordSize*2). doingClass := false] ifFalse: [self longAt: fieldPtr put: mapOop. fieldPtr := fieldPtr + self wordSize]]]. segOop := self objectAfter: segOop]. self restoreHeadersFrom: firstIn to: lastIn from: hdrBaseIn and: firstOut to: lastOut from: hdrBaseOut. "Truncate the outPointerArray..." ((outPointerArray + (self lastPointerOf: outPointerArray) - lastOut) < 12 or: [(endSeg - lastSeg) < 12]) ifTrue: ["Not enough room to insert simple 3-word headers" ^self primitiveFailCodeAfterCleanup: outPointerArray]. extraSize := self extraHeaderBytes: segmentWordArray. hdrTypeBits := self headerType: segmentWordArray. "Copy the 3-word wordArray header to establish a free chunk." self transfer: 3 from: segmentWordArray - extraSize to: lastOut+self wordSize. "Adjust the size of the original as well as the free chunk." self longAt: lastOut+self wordSize put: outPointerArray + (self lastPointerOf: outPointerArray) - lastOut - extraSize + hdrTypeBits. self longAt: outPointerArray-extraSize put: lastOut - firstOut + (self wordSize*2) + hdrTypeBits. "Note that pointers have been stored into roots table" self beRootIfOld: outPointerArray. "Truncate the image segment..." "Copy the 3-word wordArray header to establish a free chunk." self transfer: 3 from: segmentWordArray - extraSize to: lastSeg+self wordSize. "Adjust the size of the original as well as the free chunk." self longAt: segmentWordArray-extraSize put: lastSeg - segmentWordArray + self baseHeaderSize + hdrTypeBits. self longAt: lastSeg+self wordSize put: endSeg - lastSeg - extraSize + hdrTypeBits. DoAssertionChecks ifTrue: [self verifyCleanHeaders]. ^PrimNoErr! Item was changed: ----- Method: SpurMemoryManager>>mem:cp:y: (in category 'simulation') ----- mem: destAddress cp: sourceAddress y: bytes "For SpurGenerationScavenger>>copyToFutureSpace:bytes:. N.B. If ranges overlap, must use memmove." <doNotGenerate> + self deny: ((destAddress <= sourceAddress and: [destAddress asInteger + bytes > sourceAddress]) + or: [sourceAddress <= destAddress and: [sourceAddress asInteger + bytes > destAddress]]). - self deny: ((destAddress <= sourceAddress and: [destAddress + bytes > sourceAddress]) - or: [sourceAddress <= destAddress and: [sourceAddress + bytes > destAddress]]). ^self mem: destAddress mo: sourceAddress ve: bytes! Item was changed: ----- Method: StackInterpreter>>returnAs:ThroughCallback:Context: (in category 'callback support') ----- returnAs: returnTypeOop ThroughCallback: vmCallbackContext Context: callbackMethodContext "callbackMethodContext is an activation of invokeCallback:[stack:registers:jmpbuf:]. Its sender is the VM's state prior to the callback. Reestablish that state (via longjmp), and mark callbackMethodContext as dead." <export: true> <var: #vmCallbackContext type: #'VMCallbackContext *'> | calloutMethodContext theFP thePage | <var: #theFP type: #'char *'> <var: #thePage type: #'StackPage *'> self assert: primFailCode = 0. self assert: (objectMemory isIntegerObject: returnTypeOop). + self assert: (objectMemory isImmediate: vmCallbackContext asInteger) not. - self assert: (objectMemory isImmediate: vmCallbackContext) not. self assert: ((objectMemory addressCouldBeObj: callbackMethodContext) and: [objectMemory isContext: callbackMethodContext]). self assert: (debugCallbackPath := 0) = 0. ((objectMemory isIntegerObject: returnTypeOop) and: [self isLiveContext: callbackMethodContext]) ifFalse: [self assert: (debugCallbackPath := 1) = 1. ^false]. calloutMethodContext := self externalInstVar: SenderIndex ofContext: callbackMethodContext. (self isLiveContext: calloutMethodContext) ifFalse: [self assert: (debugCallbackPath := 2) = 2. ^false]. self assert: (debugCallbackReturns := debugCallbackReturns + 1) > 0. "self assert: debugCallbackReturns < 3802." "We're about to leave this stack page; must save the current frame's instructionPointer." self push: instructionPointer. self externalWriteBackHeadFramePointers. "Mark callbackMethodContext as dead; the common case is that it is the current frame. We go the extra mile for the debugger." (self isSingleContext: callbackMethodContext) ifTrue: [self assert: (debugCallbackPath := debugCallbackPath bitOr: 4) > 0. self markContextAsDead: callbackMethodContext] ifFalse: [self assert: (debugCallbackPath := debugCallbackPath bitOr: 8) > 0. theFP := self frameOfMarriedContext: callbackMethodContext. self assert: (self frameReceiver: theFP) = (objectMemory splObj: ClassAlien). framePointer = theFP "common case" ifTrue: [self assert: (debugCallbackPath := debugCallbackPath bitOr: 16) > 0. (self isBaseFrame: theFP) ifFalse: "calloutMethodContext is immediately below on the same page. Make it current." [self assert: (debugCallbackPath := debugCallbackPath bitOr: 32) > 0. instructionPointer := (self frameCallerSavedIP: theFP) asUnsignedInteger. stackPointer := theFP + (self frameStackedReceiverOffset: theFP) + objectMemory wordSize. framePointer := self frameCallerFP: theFP. self setMethod: (self frameMethodObject: framePointer). self restoreCStackStateForCallbackContext: vmCallbackContext. self assertValidExecutionPointe: instructionPointer r: framePointer s: stackPointer. "N.B. siglongjmp is defines as _longjmp on non-win32 platforms. This matches the use of _setjmp in ia32abicc.c." self siglong: vmCallbackContext trampoline jmp: (self integerValueOf: returnTypeOop). ^true]. stackPages freeStackPage: stackPage] ifFalse: [self assert: (debugCallbackPath := debugCallbackPath bitOr: 64) > 0. self externalDivorceFrame: theFP andContext: callbackMethodContext. self markContextAsDead: callbackMethodContext]]. "Make the calloutMethodContext the active frame. The case where calloutMethodContext is immediately below callbackMethodContext on the same page is handled above." (self isStillMarriedContext: calloutMethodContext) ifTrue: [self assert: (debugCallbackPath := debugCallbackPath bitOr: 128) > 0. theFP := self frameOfMarriedContext: calloutMethodContext. thePage := stackPages stackPageFor: theFP. "findSPOf:on: points to the word beneath the instructionPointer, but there is no instructionPointer on the top frame of the current page." self assert: thePage ~= stackPage. stackPointer := thePage headFP = theFP ifTrue: [thePage headSP] ifFalse: [(self findSPOf: theFP on: thePage) - objectMemory wordSize]. framePointer := theFP. self assert: stackPointer < framePointer] ifFalse: [self assert: (debugCallbackPath := debugCallbackPath bitOr: 256) > 0. thePage := self makeBaseFrameFor: calloutMethodContext. self setStackPointersFromPage: thePage]. instructionPointer := self popStack. self setMethod: (objectMemory fetchPointer: MethodIndex ofObject: calloutMethodContext). self setStackPageAndLimit: thePage. self restoreCStackStateForCallbackContext: vmCallbackContext. primitiveFunctionPointer := vmCallbackContext savedPrimFunctionPointer. "N.B. siglongjmp is defined as _longjmp on non-win32 platforms. This matches the use of _setjmp in ia32abicc.c." self siglong: vmCallbackContext trampoline jmp: (self integerValueOf: returnTypeOop). "NOTREACHED" ^true! Item was changed: ----- Method: StackInterpreterSimulator>>imageNamePut:Length: (in category 'file primitives') ----- imageNamePut: p Length: sz | newName window | newName := ByteString new: sz. 1 to: sz do: [:i | newName at: i put: (Character value: (objectMemory byteAt: p + i - 1))]. imageName := newName. (displayView notNil and: [(window := displayView containingWindow) notNil]) ifTrue: [window setLabel: (window label copyReplaceFrom: (window label lastIndexOf: Character space) + 1 to: window label size + with: (self localNameFor: imageName))]! - with: (FileDirectory localNameFor: imageName))]! Item was changed: ----- Method: StackInterpreterSimulator>>openAsMorph (in category 'UI') ----- openAsMorph "Open a morphic view on this simulation." | localImageName borderWidth window | localImageName := imageName + ifNotNil: [self localNameFor: imageName] - ifNotNil: [FileDirectory default localNameFor: imageName] ifNil: [' synthetic image']. window := (SystemWindow labelled: 'Simulation of ', localImageName) model: self. window paneColor: self windowColorToUse. window addMorph: (displayView := SimulatorImageMorph new image: displayForm) frame: (0@0 corner: 1(a)0.8). displayView activeHand addEventListener: self. eventTransformer := SimulatorEventTransformer new. transcript := TranscriptStream on: (String new: 10000). window addMorph: (PluggableTextMorph on: transcript text: nil accept: nil readSelection: nil menu: #codePaneMenu:shifted:) frame: (0(a)0.8 corner: 0.7@1). window addMorph: (PluggableTextMorph on: self text: #byteCountText accept: nil readSelection: nil menu: #utilitiesMenu:) hideScrollBarsIndefinitely frame: (0.7(a)0.8 corner: 1@1). borderWidth := [SystemWindow borderWidth] "Squeak 4.1" on: MessageNotUnderstood do: [:ex| 0]. "3.8" borderWidth := borderWidth + window borderWidth. window openInWorldExtent: (self desiredDisplayExtent + (2 * borderWidth@borderWidth) + (0@window labelHeight) * (1(a)(1/0.8))) rounded. ^window! Item was changed: ----- Method: StackInterpreterSimulator>>openAsMorphNoTranscript (in category 'UI') ----- openAsMorphNoTranscript "Open a morphic view on this simulation." | localImageName borderWidth window | localImageName := imageName + ifNotNil: [self localNameFor: imageName] - ifNotNil: [FileDirectory default localNameFor: imageName] ifNil: [' synthetic image']. window := (SystemWindow labelled: 'Simulation of ', localImageName) model: self. window paneColor: self windowColorToUse. window addMorph: (displayView := SimulatorImageMorph new image: displayForm) frame: (0@0 corner: 1(a)0.95). displayView activeHand addEventListener: self. eventTransformer := SimulatorEventTransformer new. window addMorph: (PluggableTextMorph on: self text: #byteCountText accept: nil readSelection: nil menu: #utilitiesMenu:) hideScrollBarsIndefinitely frame: (0(a)0.95 corner: 1@1). borderWidth := [SystemWindow borderWidth] "Squeak 4.1" on: MessageNotUnderstood do: [:ex| 0]. "3.8" borderWidth := borderWidth + window borderWidth. window openInWorldExtent: (self desiredDisplayExtent + (2 * borderWidth@borderWidth) + (0@window labelHeight) * (1(a)(1/0.95))) rounded! Item was changed: ----- Method: StackInterpreterSimulator>>openAsSimulatorMorph (in category 'UI') ----- openAsSimulatorMorph "Open a morphic view on this simulation. ala Bert Freudenberg's SqueakJS
http://lively-web.org/users/bert/squeak.html
" | localImageName borderWidth window | localImageName := imageName ifNil: [' synthetic image'] + ifNotNil: [self localNameFor: imageName]. - ifNotNil: [FileDirectory default localNameFor: imageName]. transcript := TranscriptStream on: (String new: 10000). window := SimulatorMorph withVMSimulator: self title: 'Simulation of ' , localImageName, ' (beta)' transcript: transcript. borderWidth := [SimulatorMorph borderWidth] "Squeak 4.1" on: MessageNotUnderstood do: [:ex | 0]. "3.8" borderWidth := borderWidth + window borderWidth. window openInWorldExtent: (self desiredDisplayExtent + (2 * borderWidth) + (0 @ window labelHeight) * (1 @ (1 / 0.8))) rounded. ^window! Item was changed: ----- Method: StackInterpreterSimulator>>vmPathGet:Length: (in category 'file primitives') ----- vmPathGet: stringBase Length: stringSize | pathName stringOop | + pathName := self vmPath. - pathName := Smalltalk vmPath. stringOop := stringBase - objectMemory baseHeaderSize. "Due to C call in Interp" 1 to: stringSize do: [:i | objectMemory storeByte: i-1 ofObject: stringOop withValue: (pathName at: i) asciiValue]. ! Item was removed: - ----- Method: StackInterpreterSimulator>>vmPathSize (in category 'file primitives') ----- - vmPathSize - ^ Smalltalk vmPath size! Item was changed: ----- Method: TSendNode>>printOn:level: (in category 'printing') ----- printOn: aStream level: level | possiblyParenthesize | possiblyParenthesize := [:node :newLevel| + node + ifNil: [aStream print: node] + ifNotNil: + [(node isSend + and: [node selector precedence >= 3]) ifTrue: + [aStream nextPut: $(]. + node printOn: aStream level: newLevel. + (node isSend + and: [node selector precedence >= 3]) ifTrue: + [aStream nextPut: $)]]]. - (node isSend - and: [node selector precedence >= 3]) ifTrue: - [aStream nextPut: $(]. - node printOn: aStream level: newLevel. - (node isSend - and: [node selector precedence >= 3]) ifTrue: - [aStream nextPut: $)]]. possiblyParenthesize value: receiver value: level. arguments size = 0 ifTrue: [aStream space; nextPutAll: selector. ^self]. selector keywords with: (arguments first: selector numArgs) do: [:keyword :arg | aStream space; nextPutAll: keyword; space. possiblyParenthesize value: arg value: level + 1]! Item was changed: ----- Method: VMClass>>doOrDefer: (in category 'simulation support') ----- doOrDefer: aBlock <doNotGenerate> "Either evaluate aBlock immediately if in the uiProcess or defer aBlock as a UI message" + Processor activeProcess == self uiProcess - Processor activeProcess == Project uiProcess ifTrue: [aBlock value] ifFalse: [WorldState addDeferredUIMessage: aBlock]! Item was added: + ----- Method: VMClass>>localNameFor: (in category 'hack compatibility') ----- + localNameFor: aString + <doNotGenerate> + ^(Smalltalk classNamed: #FileSystem) + ifNotNil: [:fs| (fs disk pathFromString: aString) basename] + ifNil: [FileDirectory default localNameFor: aString]! Item was added: + ----- Method: VMClass>>uiProcess (in category 'hack compatibility') ----- + uiProcess + <doNotGenerate> + ^(Smalltalk classNamed: #Project) + ifNotNil: [:project| Project uiProcess] "Squeak" + ifNil: [UIManager default uiProcess] "Pharo"! Item was added: + ----- Method: VMClass>>vmPath (in category 'hack compatibility') ----- + vmPath + <doNotGenerate> + ^(Smalltalk classNamed: #VirtualMachine) + ifNotNil: [:project| Smalltalk vm path] "Squeak" + ifNil: [Smalltalk vmPath] "Pharo"! Item was added: + ----- Method: VMClass>>vmPathSize (in category 'hack compatibility') ----- + vmPathSize + <doNotGenerate> + ^self vmPath size!
1
0
0
0
← Newer
1
2
3
4
5
Older →
Jump to page:
1
2
3
4
5
Results per page:
10
25
50
100
200