'From Squeak3.8.2a of ''26 Oct 2007'' [latest update: #6748] on 23 October 2008 at 8:43:58 pm'! "Change Set: Interpreter-readImageFromFile-jmm-dtl Date: 23 October 2008 Author: David T. Lewis Pass image file and image header length to object memory allocation function in order to enable mmap loading without address swizzling, per jmm proposal. For backward compatibility in support code: #define allocateMemoryminimumimageFileheaderSize(heapSize, minimumMemory, f, headerSize) sqAllocateMemory(minimumMemory, heapSize) "! !Interpreter methodsFor: 'image save/restore' stamp: 'dtl 10/23/2008 20:32'! readImageFromFile: f HeapSize: desiredHeapSize StartingAt: imageOffset "Read an image from the given file stream, allocating the given amount of memory to its object heap. Fail if the image has an unknown format or requires more than the given amount of memory." "Details: This method detects when the image was stored on a machine with the opposite byte ordering from this machine and swaps the bytes automatically. Furthermore, it allows the header information to start 512 bytes into the file, since some file transfer programs for the Macintosh apparently prepend a Mac-specific header of this size. Note that this same 512 bytes of prefix area could also be used to store an exec command on Unix systems, allowing one to launch Smalltalk by invoking the image name as a command." "This code is based on C code by Ian Piumarta and Smalltalk code by Tim Rowledge. Many thanks to both of you!!!!" | swapBytes headerStart headerSize dataSize oldBaseAddr minimumMemory memStart bytesRead bytesToShift heapSize | self var: #f type: 'sqImageFile '. self var: #headerStart type: 'squeakFileOffsetType '. self var: #dataSize type: 'size_t '. self var: #imageOffset type: 'squeakFileOffsetType '. swapBytes := self checkImageVersionFrom: f startingAt: imageOffset. headerStart := (self sqImageFilePosition: f) - BytesPerWord. "record header start position" headerSize := self getLongFromFile: f swap: swapBytes. dataSize := self getLongFromFile: f swap: swapBytes. oldBaseAddr := self getLongFromFile: f swap: swapBytes. specialObjectsOop := self getLongFromFile: f swap: swapBytes. lastHash := self getLongFromFile: f swap: swapBytes. savedWindowSize := self getLongFromFile: f swap: swapBytes. fullScreenFlag := self getLongFromFile: f swap: swapBytes. extraVMMemory := self getLongFromFile: f swap: swapBytes. lastHash = 0 ifTrue: [ "lastHash wasn't stored (e.g. by the cloner); use 999 as the seed" lastHash := 999]. "decrease Squeak object heap to leave extra memory for the VM" heapSize := self cCode: 'reserveExtraCHeapBytes(desiredHeapSize, extraVMMemory)'. "compare memory requirements with availability". minimumMemory := dataSize + 100000. "need at least 100K of breathing room" heapSize < minimumMemory ifTrue: [ self insufficientMemorySpecifiedError]. "allocate a contiguous block of memory for the Squeak heap" memory := self allocateMemory: heapSize minimum: minimumMemory imageFile: f headerSize: headerSize. memory = nil ifTrue: [self insufficientMemoryAvailableError]. memStart := self startOfMemory. memoryLimit := (memStart + heapSize) - 24. "decrease memoryLimit a tad for safety" endOfMemory := memStart + dataSize. "position file after the header" self sqImageFile: f Seek: headerStart + headerSize. "read in the image in bulk, then swap the bytes if necessary" bytesRead := self sqImage: (self pointerForOop: memory) read: f size: (self cCode: 'sizeof(unsigned char)') length: dataSize. bytesRead ~= dataSize ifTrue: [self unableToReadImageError]. headerTypeBytes at: 0 put: BytesPerWord * 2. "3-word header (type 0)" headerTypeBytes at: 1 put: BytesPerWord. "2-word header (type 1)" headerTypeBytes at: 2 put: 0. "free chunk (type 2)" headerTypeBytes at: 3 put: 0. "1-word header (type 3)" swapBytes ifTrue: [self reverseBytesInImage]. "compute difference between old and new memory base addresses" bytesToShift := memStart - oldBaseAddr. self initializeInterpreter: bytesToShift. "adjusts all oops to new location" self isBigEnder. "work out the machine endianness and cache the answer" ^ dataSize ! !