[Vm-dev] About Cog on linux
Igor Stasenko
siguctua at gmail.com
Fri Feb 11 19:53:57 UTC 2011
Ok, i traced the interpret loop up to the point execution takes
different(wrong) route.
Given the method:
snapshot: save andQuit: quit embedded: embeddedFlag
"Mark the changes file and close all files as part of #processShutdownList.
If save is true, save the current state of this Smalltalk in the image file.
If quit is true, then exit to the outer OS shell.
The latter part of this method runs when resuming a previously saved
image. This resume logic checks for a document file to process when
starting up."
| snapshotResult resuming msg |
Object flushDependents.
Object flushEvents.
(SourceFiles at: 2)
ifNotNil: [
msg := String
streamContents: [ :s |
s
nextPutAll: '----';
nextPutAll:
(save
ifTrue: [
quit
ifTrue: [ 'QUIT' ]
ifFalse: [ 'SNAPSHOT' ] ]
ifFalse: [
quit
ifTrue: [ 'QUIT/NOSAVE' ]
ifFalse: [ 'NOP' ] ]);
nextPutAll: '----';
print: Date dateAndTimeNow;
space;
nextPutAll: (FileDirectory default localNameFor: self imageName);
nextPutAll: ' priorSource: ';
print: LastQuitLogPosition ].
self assureStartupStampLogged.
save
ifTrue: [
LastQuitLogPosition := (SourceFiles at: 2)
setToEnd;
position ].
self logChange: msg.
Transcript
cr;
show: msg ].
self processShutDownList: quit.
Cursor write show.
save
ifTrue: [
snapshotResult := embeddedFlag
ifTrue: [ self snapshotEmbeddedPrimitive ]
ifFalse: [ self snapshotPrimitive ]. "<-- PC frozen here on image file"
resuming := snapshotResult == true.
snapshotResult == false
ifTrue: [
"Time to reclaim segment files is immediately after a save"
Smalltalk globals at: #ImageSegment ifPresent: [ :theClass |
theClass reclaimObsoleteSegmentFiles ] ] "guard against failure" ]
ifFalse: [ resuming := false ].
(quit and: [ resuming not ])
ifTrue: [ self quitPrimitive ].
Cursor normal show.
self setGCParameters.
resuming
ifTrue: [ Smalltalk clearExternalObjects ].
self processStartUpList: resuming.
resuming
ifTrue: [ self recordStartupStamp ].
UIManager default onSnapshot: resuming. "Now it's time to raise an error"
snapshotResult == nil
ifTrue: [ self error: 'Failed to write image file (disk full?)' ].
^ resuming
------------
And its bytecode:
-------------
217 <41> pushLit: Object
218 <D0> send: flushDependents
219 <87> pop
220 <41> pushLit: Object
221 <D2> send: flushEvents
222 <87> pop
223 <56> pushLit: SourceFiles
224 <77> pushConstant: 2
225 <C0> send: at:
226 <73> pushConstant: nil
227 <C6> send: ==
228 <A8 5B> jumpTrue: 321
230 <44> pushLit: String
231 <10> pushTemp: 0
232 <11> pushTemp: 1
233 <8F 21 00 32> closureNumCopied: 2 numArgs: 1 bytes 237 to 286
237 <10> pushTemp: 0
238 <88> dup
239 <26> pushConstant: '----'
240 <E5> send: nextPutAll:
241 <87> pop
242 <88> dup
243 <11> pushTemp: 1
244 <9D> jumpFalse: 251
245 <12> pushTemp: 2
246 <99> jumpFalse: 249
247 <2A> pushConstant: 'QUIT'
248 <90> jumpTo: 250
249 <29> pushConstant: 'SNAPSHOT'
250 <94> jumpTo: 256
251 <12> pushTemp: 2
252 <99> jumpFalse: 255
253 <28> pushConstant: 'QUIT/NOSAVE'
254 <90> jumpTo: 256
255 <27> pushConstant: 'NOP'
256 <E5> send: nextPutAll:
257 <87> pop
258 <88> dup
259 <26> pushConstant: '----'
260 <E5> send: nextPutAll:
261 <87> pop
262 <88> dup
263 <4D> pushLit: Date
264 <DC> send: dateAndTimeNow
265 <EB> send: print:
266 <87> pop
267 <88> dup
268 <DE> send: space
269 <87> pop
270 <88> dup
271 <51> pushLit: FileDirectory
272 <83 10> send: default
274 <70> self
275 <83 12> send: imageName
277 <EF> send: localNameFor:
278 <E5> send: nextPutAll:
279 <87> pop
280 <88> dup
281 <33> pushConstant: ' priorSource: '
282 <E5> send: nextPutAll:
283 <87> pop
284 <54> pushLit: LastQuitLogPosition
285 <EB> send: print:
286 <7D> blockReturn
287 <E3> send: streamContents:
288 <6D> popIntoTemp: 5
289 <70> self
290 <83 15> send: assureStartupStampLogged
292 <87> pop
293 <10> pushTemp: 0
294 <AC 0B> jumpFalse: 307
296 <56> pushLit: SourceFiles
297 <77> pushConstant: 2
298 <C0> send: at:
299 <88> dup
300 <83 17> send: setToEnd
302 <87> pop
303 <83 18> send: position
305 <82 D4> popIntoLit: LastQuitLogPosition
307 <70> self
308 <15> pushTemp: 5
309 <83 39> send: logChange:
311 <87> pop
312 <5A> pushLit: Transcript
313 <88> dup
314 <83 1B> send: cr
316 <87> pop
317 <15> pushTemp: 5
318 <83 3C> send: show:
320 <87> pop
321 <70> self
322 <11> pushTemp: 1
323 <83 3D> send: processShutDownList:
325 <87> pop
326 <80 E0> pushLit: Cursor
328 <83 1F> send: write
330 <83 1E> send: show
332 <87> pop
333 <10> pushTemp: 0
334 <AC 26> jumpFalse: 374
336 <12> pushTemp: 2
337 <9B> jumpFalse: 342
338 <70> self
339 <86 22> send: snapshotEmbeddedPrimitive
341 <92> jumpTo: 345
342 <70> self
343 <86 21> send: snapshotPrimitive
345 <6B> popIntoTemp: 3
346 <13> pushTemp: 3
347 <71> pushConstant: true
348 <C6> send: ==
349 <6C> popIntoTemp: 4
350 <13> pushTemp: 3
351 <72> pushConstant: false
352 <C6> send: ==
353 <AC 11> jumpFalse: 372
355 <80 E5> pushLit: Smalltalk
357 <86 24> send: globals
359 <80 A6> pushConstant: #ImageSegment
361 <8F 01 00 04> closureNumCopied: 0 numArgs: 1 bytes 365 to 368
365 <10> pushTemp: 0
366 <86 27> send: reclaimObsoleteSegmentFiles
368 <7D> blockReturn
369 <86 A3> send: at:ifPresent:
371 <90> jumpTo: 373
372 <73> pushConstant: nil
373 <92> jumpTo: 377
374 <72> pushConstant: false
375 <81 44> storeIntoTemp: 4
377 <87> pop
378 <11> pushTemp: 1
379 <9B> jumpFalse: 384
380 <14> pushTemp: 4
381 <86 29> send: not
383 <90> jumpTo: 385
384 <72> pushConstant: false
385 <9B> jumpFalse: 390
386 <70> self
387 <86 28> send: quitPrimitive
389 <87> pop
390 <80 E0> pushLit: Cursor
392 <86 2A> send: normal
394 <83 1E> send: show
396 <87> pop
397 <70> self
398 <86 2B> send: setGCParameters
400 <87> pop
401 <14> pushTemp: 4
402 <9C> jumpFalse: 408
403 <80 E5> pushLit: Smalltalk
405 <86 2C> send: clearExternalObjects
407 <87> pop
408 <70> self
409 <14> pushTemp: 4
410 <86 6D> send: processStartUpList:
412 <87> pop
413 <14> pushTemp: 4
414 <9B> jumpFalse: 419
415 <70> self
416 <86 2E> send: recordStartupStamp
418 <87> pop
419 <80 F0> pushLit: UIManager
421 <83 10> send: default
423 <14> pushTemp: 4
424 <86 6F> send: onSnapshot:
426 <87> pop
427 <13> pushTemp: 3
428 <73> pushConstant: nil
429 <C6> send: ==
430 <9D> jumpFalse: 437
431 <70> self
432 <80 B2> pushConstant: 'Failed to write image file (disk full?)'
434 <86 71> send: error:
436 <87> pop
437 <14> pushTemp: 4
438 <7C> returnTop
-----
it is diverging from simulator at bytecode
378 <11> pushTemp: 1
which is instead of pushing quit = true, pushes nil.
Then of course next bytecode (jumpFalse:) fails and it sends
#mustBeBoolean: to nil object.
Apparently either stack is imbalanced (so it points to wrong stack
frame which has nil at temp=1 offset),
or something overwrites this argument by nil, for some unknown reason.
Now the question is where this nil came from and who wrote it there. :)
Here the stack frame when loading this image in simulator and before
starting any interpretation:
-16r27C14 SmalltalkImage>snapshot:andQuit:embedded: 2268340: a(n)
SmalltalkImage
-16r27C00/512: rcvr/clsr: 16r229CB4 a SmalltalkImage
-16r27C04/511: arg: 16r14 true
-16r27C08/510: arg: 16r14 true
-16r27C0C/509: arg: 16rC false
-16r27C10/508:cllr ip/ctxt: 16r1A8F5E0=27850208
-16r27C14/507: saved fp: 16r0
-16r27C18/506: method: 16r918D24 a CompiledMethod
-16r27C1C/505: flags: 16r10301=66305 numArgs: 3
hasContext: true isBlock: false
-16r27C20/504: context: 16r1A8F63C=27850300
-16r27C24/503: receiver: 16r229CB4 a SmalltalkImage
-16r27C28/502: temp/stck: 16r4 nil
-16r27C2C/501: temp/stck: 16r4 nil
-16r27C30/500: temp/stck: 16r1A8FEF8 '----QUIT----an Array(10
February 2011 7:56:30 pm) generator.image priorSource: 24702567'
-16r27C34/499: temp/stck: 16r14 true
And evaluating:
(self temporary: 1 in: localFP) == objectMemory trueObject
in simulator yields true, which seems correct.
Here the stack at the point of pushing quit flag (temp1):
-16r27C14 SmalltalkImage>snapshot:andQuit:embedded: 2268340: a(n)
SmalltalkImage
-16r27C00/512: rcvr/clsr: 16r229CB4 a SmalltalkImage
-16r27C04/511: arg: 16r14 true
-16r27C08/510: arg: 16r14 true
-16r27C0C/509: arg: 16rC false
-16r27C10/508:cllr ip/ctxt: 16r1A8F5E0=27850208
-16r27C14/507: saved fp: 16r0
-16r27C18/506: method: 16r918D24 a CompiledMethod
-16r27C1C/505: flags: 16r10301=66305 numArgs: 3
hasContext: true isBlock: false
-16r27C20/504: context: 16r1A8F63C=27850300
-16r27C24/503: receiver: 16r229CB4 a SmalltalkImage
-16r27C28/502: temp/stck: 16r14 true
-16r27C2C/501: temp/stck: 16r14 true
-16r27C30/500: temp/stck: 16r1A8FEF8 '----QUIT----an Array(10
February 2011 7:56:30 pm) generator.image priorSource: 24702567'
378 11 pushTemporaryVariableBytecode (12)
and it reads value from
-16r27C08/510: arg: 16r14 true
when performing #pushTemporaryVariableBytecode
So, in simulator it looks fine :)
--
Best regards,
Igor Stasenko AKA sig.
More information about the Vm-dev
mailing list