Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.634.mcz ==================== Summary ==================== Name: VMMaker.oscog-eem.634 Author: eem Time: 9 March 2014, 10:35:34.439 am UUID: 6eba1357-7d48-41e2-b193-8bf6aa8d71c8 Ancestors: VMMaker.oscog-eem.633 Spur: Fix the reading of 0-sized bridges for adjacent segments on image load. Rename writeImageToFile: to writeImageSegmentsToFile:. Snapshot: don't use cCode: in writeImageFileIO and move the simulatpr's version up to writeImageFileIOSimulation to cut down on duplication. =============== Diff against VMMaker.oscog-eem.633 =============== Item was added: + ----- Method: CogVMSimulator>>imageName (in category 'image save/restore') ----- + imageName + ^imageName! Item was removed: - ----- Method: CogVMSimulator>>writeImageFileIO (in category 'image save/restore') ----- - writeImageFileIO - "Write the image to a file as an image snapshot." - - | headerSize file | - BytesPerWord = 4 ifFalse: [self error: 'Not rewritten for 64 bits yet']. - headerSize := 64. - - (file := FileStream fileNamed: imageName) ifNil: - [self primitiveFail. - ^nil]. - [ - file binary. - - { - self imageFormatVersion. - headerSize. - objectMemory imageSizeToWrite. - objectMemory baseAddressOfImage. - objectMemory specialObjectsOop. - objectMemory lastHash. - self ioScreenSize. - self getImageHeaderFlags. - extraVMMemory - } - do: [:long | self putLong: long toFile: file]. - - { desiredNumStackPages. self unknownShortOrCodeSizeInKs } do: - [:short| self putShort: short toFile: file]. - - self putLong: desiredEdenBytes toFile: file. - - { maxExtSemTabSizeSet ifTrue: [self ioGetMaxExtSemTableSize] ifFalse: [0]. 0 } do: - [:short| self putShort: short toFile: file]. - - objectMemory hasSpurMemoryManagerAPI - ifTrue: - [| bytesWritten | - self putLong: objectMemory firstSegmentBytes toFile: file."Pad the rest of the header." - 3 timesRepeat: [self putLong: 0 toFile: file]. - - "Position the file after the header." - file position: headerSize. - bytesWritten := objectMemory segmentManager writeImageToFile: file. - self assert: bytesWritten = objectMemory imageSizeToWrite] - ifFalse: - ["Pad the rest of the header." - 4 timesRepeat: [self putLong: 0 toFile: file]. - - "Position the file after the header." - file position: headerSize. - - "Write the object memory." - objectMemory baseAddressOfImage // 4 + 1 - to: objectMemory baseAddressOfImage + objectMemory imageSizeToWrite // 4 - do: [:index | - self - putLong: (objectMemory memory at: index) - toFile: file]]. - - self success: true - ] - ensure: [file ifNotNil: [file close]]! Item was added: + ----- Method: SpurMemoryManager>>writeImageSegmentsToFile: (in category 'snapshot') ----- + writeImageSegmentsToFile: aBinaryStream + <doNotGenerate> + ^segmentManager writeImageSegmentsToFile: aBinaryStream! Item was added: + ----- Method: SpurSegmentManager>>nextNonEmptySegmentAfter: (in category 'snapshot') ----- + nextNonEmptySegmentAfter: i + "Answer the the next non-empty segment or nil. The size of a segment includes + that of its bridge. A segment containing just a free object and a bridge will still + have a size of manager bridgeSize after shortening it in prepareForSnapshot." + <returnTypeC: #'SpurSegmentInfo *'> + | nextx | + nextx := i. + [(nextx := nextx + 1) >= numSegments ifTrue: + [^nil]. + (segments at: nextx) segSize > manager bridgeSize ifTrue: + [^self addressOf: (segments at: nextx)]] repeat! Item was removed: - ----- Method: SpurSegmentManager>>nextNonEmptySegmentSizeAfter: (in category 'snapshot') ----- - nextNonEmptySegmentSizeAfter: i - "Answer the size of the next non-empty segment. - The size of a segment includes that of its bridge. - A segment containing just a free object and a bridge will still have a - size of manager bridgeSize after shortening it in prepareForSnapshot." - | nextx | - nextx := i. - [(nextx := nextx + 1) >= numSegments ifTrue: - [^0]. - (segments at: nextx) segSize > manager bridgeSize ifTrue: - [^(segments at: nextx) segSize]] repeat! Item was changed: ----- Method: SpurSegmentManager>>readHeapFromImageFile:dataBytes: (in category 'snapshot') ----- readHeapFromImageFile: f dataBytes: numBytes "Read numBytes of image data from f into memory at memoryBaseForImageRead. Answer the number of bytes written. In addition, read each segment, build up the + segment info for swizzling, while eliminating the bridge objects at the end of each + segment that specify the distance to and the size of the subsequent segment." - segment info, while eliminating the bridge objects that end each segment and - give the size of the subsequent segment." <var: #f type: #sqImageFile> <inline: false> | bytesRead totalBytesRead bridge nextSegmentSize oldBase newBase segInfo bridgeSpan | <var: 'segInfo' type: #'SpurSegmentInfo *'> self allocateOrExtendSegmentInfos. "segment sizes include the two-header-word bridge at the end of each segment." numSegments := totalBytesRead := 0. oldBase := 0. "N.B. still must be adjusted by oldBaseAddr." newBase := manager oldSpaceStart. nextSegmentSize := firstSegmentSize. bridge := firstSegmentSize + manager oldSpaceStart - manager baseHeaderSize. [segInfo := self addressOf: (segments at: numSegments). segInfo segStart: oldBase; "N.B. still must be adjusted by oldBaseAddr." segSize: nextSegmentSize; swizzle: newBase - oldBase. "N.B. still must be adjusted by oldBaseAddr." bytesRead := self readHeapFrom: f at: newBase dataBytes: nextSegmentSize. bytesRead > 0 ifTrue: [totalBytesRead := totalBytesRead + bytesRead]. bytesRead ~= nextSegmentSize ifTrue: [^totalBytesRead]. numSegments := numSegments + 1. + bridgeSpan := (manager rawNumSlotsOf: bridge) = 0 + ifTrue: [0] + ifFalse: [manager bytesPerSlot * (manager rawOverflowSlotsOf: bridge)]. - bridgeSpan := manager bytesPerSlot * (manager rawOverflowSlotsOf: bridge). oldBase := oldBase + nextSegmentSize + bridgeSpan. newBase := newBase + nextSegmentSize - manager bridgeSize. nextSegmentSize := manager longLongAt: bridge. nextSegmentSize ~= 0] whileTrue: [bridge := bridge - manager bridgeSize + nextSegmentSize]. "newBase should point just past the last bridge. all others should have been eliminated." self assert: newBase - manager oldSpaceStart = (totalBytesRead - (numSegments * manager bridgeSize)). "set freeOldSpaceStart now for adjustAllOopsBy:" manager setFreeOldSpaceStart: newBase. "we're done. nil firstSegmentSize for a subsequent snapshot." firstSegmentSize := nil. ^totalBytesRead! Item was added: + ----- Method: SpurSegmentManager>>writeImageSegmentsToFile: (in category 'snapshot') ----- + writeImageSegmentsToFile: aBinaryStream + <var: 'aBinaryStream' type: #sqImageFile> + <inline: false> + | total | + self assert: (manager endOfMemory = (segments at: numSegments - 1) segLimit + or: [manager endOfMemory + manager bridgeSize = (segments at: numSegments - 1) segLimit]). + firstSegmentSize ifNotNil: + [self assert: firstSegmentSize = (segments at: 0) segSize]. + self assert: (segments at: 0) segSize > 0. + total := 0. + 0 to: numSegments - 1 do: + [:i| + (segments at: i) segSize > manager bridgeSize ifTrue: + [total := total + (self writeSegment: (self addressOf: (segments at: i)) + nextSegment: (self nextNonEmptySegmentAfter: i) + toFile: aBinaryStream)]]. + ^total! Item was removed: - ----- Method: SpurSegmentManager>>writeImageToFile: (in category 'snapshot') ----- - writeImageToFile: aBinaryStream - <var: 'aBinaryStream' type: #'FILE *'> - <inline: false> - | total | - self assert: (manager endOfMemory = (segments at: numSegments - 1) segLimit - or: [manager endOfMemory + manager bridgeSize = (segments at: numSegments - 1) segLimit]). - firstSegmentSize ifNotNil: - [self assert: firstSegmentSize = (segments at: 0) segSize]. - self assert: (segments at: 0) segSize > 0. - total := 0. - 0 to: numSegments - 1 do: - [:i| - (segments at: i) segSize > manager bridgeSize ifTrue: - [total := total + (self writeSegment: (self addressOf: (segments at: i)) - nextSegmentSize: (self nextNonEmptySegmentSizeAfter: i) - toFile: aBinaryStream)]]. - ^total! Item was added: + ----- Method: SpurSegmentManager>>writeSegment:nextSegment:toFile: (in category 'snapshot') ----- + writeSegment: segment nextSegment: nextSegment toFile: aBinaryStream + "Write the segment contents, the size of and the distance to the next segment to aBinaryStream." + <var: 'segment' type: #'SpurSegmentInfo *'> + <var: 'nextSegment' type: #'SpurSegmentInfo *'> + <var: 'aBinaryStream' type: #sqImageFile> + | pier1 pier2 firstSavedBridgeWord secondSavedBridgeWord nWritten | + <var: 'firstSavedBridgeWord' type: #usqLong> + <var: 'secondSavedBridgeWord' type: #usqLong> + pier1 := segment segLimit - manager bridgeSize. + pier2 := pier1 + manager baseHeaderSize. + self assert: (self isValidSegmentBridge: (self bridgeFor: segment)). + self assert: (manager startOfObject: (self bridgeFor: segment)) = pier1. + "Temporarily change the bridge to bridge to the next non-empty segment. + The first double word of the bridge includes the bridge size in slots, and + hence specifies the distance to the next segment. The following double + word is replaced by the size of the next segment, or 0 if there isn't one." + firstSavedBridgeWord := manager longLongAt: pier1. + secondSavedBridgeWord := manager longLongAt: pier2. + self bridgeFrom: segment to: nextSegment. + manager + longLongAt: pier2 + put: (nextSegment ifNil: [0] ifNotNil: [nextSegment segSize]). + nWritten := self cCode: + [self + sq: segment segStart asVoidPointer + Image: 1 + File: segment segSize + Write: aBinaryStream] + inSmalltalk: + [aBinaryStream + next: segment segSize / 4 + putAll: manager memory + startingAt: segment segStart / 4 + 1. + segment segSize]. + manager + longLongAt: pier1 put: firstSavedBridgeWord; + longLongAt: pier2 put: secondSavedBridgeWord. + ^nWritten! Item was removed: - ----- Method: SpurSegmentManager>>writeSegment:nextSegmentSize:toFile: (in category 'snapshot') ----- - writeSegment: segment nextSegmentSize: nextSegSize toFile: aBinaryStream - <var: 'segment' type: #'SpurSegmentInfo *'> - <var: 'aBinaryStream' type: #'FILE *'> - | lastDoubleWord savedDoubleWord nWritten | - <var: 'savedDoubleWord' type: #usqLong> - lastDoubleWord := segment segLimit - manager baseHeaderSize. - self assert: (self isValidSegmentBridge: (self bridgeFor: segment)). - self assert: (manager startOfObject: (self bridgeFor: segment)) = (lastDoubleWord - manager baseHeaderSize). - savedDoubleWord := manager longLongAt: lastDoubleWord. - manager longLongAt: lastDoubleWord put: nextSegSize. - nWritten := self cCode: - [self - sq: segment segStart asVoidPointer - Image: 1 - File: segment segSize - Write: aBinaryStream] - inSmalltalk: - [aBinaryStream - next: segment segSize / 4 - putAll: manager memory - startingAt: segment segStart / 4 + 1. - segment segSize]. - manager longLongAt: lastDoubleWord put: savedDoubleWord. - ^nWritten! Item was changed: ----- Method: StackInterpreter>>writeImageFileIO (in category 'image save/restore') ----- writeImageFileIO + "Write the image header and heap contents to imageFile for snapshot." + | imageName headerStart headerSize f imageBytes bytesWritten sCWIfn okToWrite | + <var: #f type: #sqImageFile> + <var: #headerStart type: #squeakFileOffsetType> + <var: #sCWIfn type: #'void *'> + <var: #imageName declareC: 'extern char imageName[]'> + self cCode: [] inSmalltalk: [^self writeImageFileIOSimulation]. - | headerStart headerSize f bytesWritten sCWIfn okToWrite | - <var: #f type: 'sqImageFile'> - <var: #headerStart type: 'squeakFileOffsetType '> - <var: #sCWIfn type: 'void *'> "If the security plugin can be loaded, use it to check for write permission. If not, assume it's ok" sCWIfn := self ioLoadFunction: 'secCanWriteImage' From: 'SecurityPlugin'. sCWIfn ~= 0 ifTrue: [okToWrite := self cCode: '((sqInt (*)(void))sCWIfn)()'. okToWrite ifFalse:[^self primitiveFail]]. "local constants" headerStart := 0. headerSize := 64. "header size in bytes; do not change!!" + f := self sqImageFile: imageName Open: 'wb'. - f := self cCode: 'sqImageFileOpen(imageName, "wb")'. f = nil ifTrue: "could not open the image file for writing" [^self primitiveFail]. + imageBytes := objectMemory imageSizeToWrite. + headerStart := self sqImage: f File: imageName StartLocation: headerSize + imageBytes. - headerStart := self cCode: 'sqImageFileStartLocation(f,imageName,headerSize+imageBytes)'. self cCode: '/* Note: on Unix systems one could put an exec command here, padded to 512 bytes */'. "position file to start of header" self sqImageFile: f Seek: headerStart. self putLong: self imageFormatVersion toFile: f. self putLong: headerSize toFile: f. + self putLong: imageBytes toFile: f. - self putLong: objectMemory imageSizeToWrite toFile: f. self putLong: objectMemory baseAddressOfImage toFile: f. self putLong: objectMemory specialObjectsOop toFile: f. self putLong: objectMemory newObjectHash toFile: f. self putLong: self ioScreenSize toFile: f. self putLong: self getImageHeaderFlags toFile: f. self putLong: extraVMMemory toFile: f. self putShort: desiredNumStackPages toFile: f. self putShort: self unknownShortOrCodeSizeInKs toFile: f. self putLong: desiredEdenBytes toFile: f. self putShort: (maxExtSemTabSizeSet ifTrue: [self ioGetMaxExtSemTableSize] ifFalse: [0]) toFile: f. self putShort: the2ndUnknownShort toFile: f. objectMemory hasSpurMemoryManagerAPI ifTrue: [self putLong: objectMemory firstSegmentBytes toFile: f."Pad the rest of the header." 1 to: 3 do: [:i| self putLong: 0 toFile: f]] ifFalse: [1 to: 4 do: [:i| self putLong: 0 toFile: f]]. "fill remaining header words with zeros" - self successful ifFalse: [ - "file write or seek failure" - self cCode: 'sqImageFileClose(f)'. - ^ nil]. - "position file after the header" self sqImageFile: f Seek: headerStart + headerSize. + self successful ifFalse: "file write or seek failure" + [self sqImageFileClose: f. + ^nil]. + "write the image data" objectMemory hasSpurMemoryManagerAPI ifTrue: + [bytesWritten := objectMemory writeImageSegmentsToFile: f] - [bytesWritten := objectMemory segmentManager writeImageToFile: f] ifFalse: + [bytesWritten := self sq: (self pointerForOop: objectMemory baseAddressOfImage) - [| memStart | - memStart := objectMemory baseAddressOfImage. - bytesWritten := self sq: (self pointerForOop: memStart) Image: (self sizeof: #char) + File: imageBytes + Write: f]. + self success: bytesWritten = imageBytes. + self sqImageFileClose: f! - File: objectMemory imageSizeToWrite - Write: f. - self touch: memStart]. - self success: bytesWritten = objectMemory imageSizeToWrite. - self cCode: 'sqImageFileClose(f)' - ! Item was added: + ----- Method: StackInterpreter>>writeImageFileIOSimulation (in category 'image save/restore') ----- + writeImageFileIOSimulation + "Write the image header and heap contents to imageFile for snapshot. + c.f. writeImageFileIO" + <doNotGenerate> + | headerSize file | + BytesPerWord = 4 ifFalse: [self error: 'Not rewritten for 64 bits yet']. + headerSize := 64. + + (file := FileStream fileNamed: self imageName) ifNil: + [self primitiveFail. + ^nil]. + [ + file binary. + + { + self imageFormatVersion. + headerSize. + objectMemory imageSizeToWrite. + objectMemory baseAddressOfImage. + objectMemory specialObjectsOop. + objectMemory lastHash. + self ioScreenSize. + self getImageHeaderFlags. + extraVMMemory ifNil: [0] + } + do: [:long | self putLong: long toFile: file]. + + { desiredNumStackPages. self unknownShortOrCodeSizeInKs } do: + [:short| self putShort: short toFile: file]. + + self putLong: desiredEdenBytes toFile: file. + + { maxExtSemTabSizeSet ifTrue: [self ioGetMaxExtSemTableSize] ifFalse: [0]. 0 } do: + [:short| self putShort: short toFile: file]. + + objectMemory hasSpurMemoryManagerAPI + ifTrue: + [| bytesWritten | + self putLong: objectMemory firstSegmentBytes toFile: file."Pad the rest of the header." + 3 timesRepeat: [self putLong: 0 toFile: file]. + + "Position the file after the header." + file position: headerSize. + bytesWritten := objectMemory writeImageSegmentsToFile: file. + self assert: bytesWritten = objectMemory imageSizeToWrite] + ifFalse: + ["Pad the rest of the header." + 4 timesRepeat: [self putLong: 0 toFile: file]. + + "Position the file after the header." + file position: headerSize. + + "Write the object memory." + objectMemory baseAddressOfImage // 4 + 1 + to: objectMemory baseAddressOfImage + objectMemory imageSizeToWrite // 4 + do: [:index | + self + putLong: (objectMemory memory at: index) + toFile: file]]. + + self success: true + ] + ensure: [file ifNotNil: [file close]]! Item was changed: + ----- Method: StackInterpreterSimulator>>imageName (in category 'image save/restore') ----- - ----- Method: StackInterpreterSimulator>>imageName (in category 'spur bootstrap') ----- imageName ^imageName! Item was removed: - ----- Method: StackInterpreterSimulator>>writeImageFileIO (in category 'image save/restore') ----- - writeImageFileIO - "Write the image to a file as an image snapshot." - - | headerSize file | - BytesPerWord = 4 ifFalse: [self error: 'Not rewritten for 64 bits yet']. - headerSize := 64. - - (file := FileStream fileNamed: imageName) ifNil: - [self primitiveFail. - ^nil]. - [ - file binary. - - { - self imageFormatVersion. - headerSize. - objectMemory imageSizeToWrite. - objectMemory baseAddressOfImage. - objectMemory specialObjectsOop. - objectMemory lastHash. - self ioScreenSize. - self getImageHeaderFlags. - extraVMMemory ifNil: [0] - } - do: [:long | self putLong: long toFile: file]. - - { desiredNumStackPages. self unknownShortOrCodeSizeInKs } do: - [:short| self putShort: short toFile: file]. - - self putLong: desiredEdenBytes toFile: file. - - { maxExtSemTabSizeSet ifTrue: [self ioGetMaxExtSemTableSize] ifFalse: [0]. 0 } do: - [:short| self putShort: short toFile: file]. - - objectMemory hasSpurMemoryManagerAPI - ifTrue: - [| bytesWritten | - self putLong: objectMemory firstSegmentBytes toFile: file."Pad the rest of the header." - 3 timesRepeat: [self putLong: 0 toFile: file]. - - "Position the file after the header." - file position: headerSize. - bytesWritten := objectMemory segmentManager writeImageToFile: file. - self assert: bytesWritten = objectMemory imageSizeToWrite] - ifFalse: - ["Pad the rest of the header." - 4 timesRepeat: [self putLong: 0 toFile: file]. - - "Position the file after the header." - file position: headerSize. - - "Write the object memory." - objectMemory baseAddressOfImage // 4 + 1 - to: objectMemory baseAddressOfImage + objectMemory imageSizeToWrite // 4 - do: [:index | - self - putLong: (objectMemory memory at: index) - toFile: file]]. - - self success: true - ] - ensure: [file ifNotNil: [file close]]! |
Free forum by Nabble | Edit this page |