Hi Ben,

On Fri, Jun 3, 2016 at 2:30 PM, Ben Coman <btc@openinworld.com> wrote:

On Fri, Jun 3, 2016 at 6:33 PM, Ben Coman <btc@openinworld.com> wrote:

> where  OwnedLock>>experiment1   is...
>     | result |
>     result := OrderedCollection new: 20.
>     result myAdd: 0.

btw, OrderedCollection>>myAdd:
is direct copy of OrderderedCollection>>add:
just so [set break selector...] can distinguish these from every send
of add: in the image.


> The current VM produces a result of...
>      OrderedCollection(0 11 12 21 22 13 14 24 8 9)
>
> but I'm hoping to get something like...
>      OrderedCollection(0 11 12 21 22 14 23 24 8 9)


After loading my 'ownedlock-reader.image' with an unchaged VM,
then adding these two lines to transferTo:

>     objectMemory
>         storeInteger: SuspendedPrimitiveFailCodeIndex
>         ofObject: oldProc
>         withValue: primFailCode.
>     primFailCode := objectMemory
>        fetchInteger: SuspendedPrimitiveFailCodeIndex
>        ofObject: newProc.

then executing...    OwnedLock new experiment1 !
I get an AssertionFailure in...

Spur32BitMMLESimulator>>fetchPointer: fieldIndex ofObject: objOop
    self assert: (self isForwarded: objOop) not.
    self assert: (fieldIndex >= 0 and: [fieldIndex < (self
numSlotsOfAny: objOop)
           or: [fieldIndex = 0 "forwarders and free objs"]]).
    ^super fetchPointer: fieldIndex ofObject: objOop

where...
  objOop  ==>
      16r2D2490: a(n) OwnedLock
           16r41A280 nil   16r41A280 nil   16r41A280 nil

  fieldIndex  ==>  3

  self numSlotsOfAny: objOop  ==>  3


One thing I'm curious about is why the " < " and not a " <= " ?
    super fetchPointer: fieldIndex ofObject: objOop
successfully returns...   16r41A280: a(n) UndefinedObject
 
Can you print the class definition of OwnedLock ?

Maybe I am wrong but it looks like it's because it's 0-based so the fieldIndex can be between 0 and 2 if numSlots is 3. That would imply a bytecode compiler bug if that object is fixed-sized.

When you try:
objectMemory
      storePointer: 3
      ofObject: objOop
      withValue: objOop

And then print objOop with printOop, is the 3rd field edited ?
If not, what if you put 2 as 1st argument ?



btw, here is the call stack...
   -16r106C [] in OwnedLock>experiment1 16r2D2490: a(n) OwnedLock
   -16r104C BlockClosure>on:do: 16r2D29C8: a(n) BlockClosure
   -16r1024 [] in OwnedLock>experiment1 16r2D2490: a(n) OwnedLock
   -16r1008 [] in BlockClosure>newProcess 16r2D27E8: a(n) BlockClosure

and the ext head frame...
   -16r106C [] in OwnedLock>experiment1 16r2D2490: a(n) OwnedLock
   -16r1064/3559:   rcvr/clsr:   16r2D29C8 a BlockClosure
   -16r1068/3558:cllr ip/ctxt:   16rA3F922=10746146
   -16r106C/3557:    saved fp:    -16r104C=-4172
   -16r1070/3556:      method:   16r81EF10 a CompiledMethod
   -16r1074/3555:       flags:  16r1010001=16842753  numArgs: 0
hasContext: true  isBlock: true
   -16r1078/3554:     context:   16r2D29F8=2959864
   -16r107C/3553:    receiver:   16r2D2490 an OwnedLock
   -16r1080/3552:   temp/stck:   16r2D24A8 an OrderedCollection
   -16r1084/3551:   temp/stck:   16r2D2490 an OwnedLock

and the int head frame...
   -16r108C OwnedLock(Process)>suspend 16r2D2490: a(n) OwnedLock
   -16r1084/3551:   rcvr/clsr:   16r2D2490 an OwnedLock
   -16r1088/3550:cllr ip/ctxt:   16r81EFBB=8515515
   -16r108C/3549:    saved fp:    -16r106C=-4204
   -16r1090/3548:      method:  16r10DF5B0 a CompiledMethod
   -16r1094/3547:       flags:        16r1=1  numArgs: 0  hasContext:
false  isBlock: false
   -16r1098/3546:     context:   16r41A280=4301440
   -16r109C/3545:    receiver:   16r2D2490 an OwnedLock
   -16r10A0/3544:   temp/stck:   16r41A280 nil


What is the difference between ext and int  head frames?

Err...
That's an interpreter optimization. I am not sure I remember correctly. I think internal stack frame may have an incorrect pc / stack pointer / frame pointer as the value may be in the interpreter and not on stack. External stack frame have always the correct value. Basically if the frame is machine code frame, it is always external. If the frame is an interpreted frame, it is internal if it's the active stack frame. Or something like that.

Eliot can you explain again ? I'm pretty sure I am confused.


One thing I find curious here is "OwnedLock(Process)>suspend".  Does
this indicate that #suspend was sent to an OwnedLock and looked up the
hierarchy to find the method in Process?
But OwnedLock doesn't inherit from Process, it inherits from LinkedList.


Well then the external stack frame was correct and not the internal one.

I always look at machine code frame and they are always external, so I forgot :-(.
 
cheers -ben