[Vm-dev] Re: problem with #become,
GC and proxies for compiled methods
Mariano Martinez Peck
marianopeck at gmail.com
Mon Jan 30 17:30:28 UTC 2012
On Mon, Jan 30, 2012 at 5:05 PM, Mariano Martinez Peck <
marianopeck at gmail.com> wrote:
> Hi guys. I am doing some hacky things and I have a problem. I am sure it
> is not VM's fault but mine. I would just like to understand what could be
> Scenario: I have developed an "object graph swapper" which basically takes
> a graph, and replaces each object of the graph by a proxy. Then the graph
> is serialized and swapped out to a file. The proxies then intercept
> messages and materialize from file, and replaces proxies with the
> materialized objects. When I am swapping out, after I become original
> objects to proxies, the only reachable proxies are the proxies for the
> roots and for objects inside the graph which were also referenced from
> outside the graph. All the rest of the proxies (for objects only reachable
> from inside the graph) can be garbage collected without problem.
> Problem: I am swapping out several graphs one after another one. If after
> swapping out each graph, I do a GC, then I have no problem. I can swap lots
> of graphs. However, if I start to swap several graphs but I do not run a gc
> after each graph, then I have a crash in the VM. The crash happens when
> becoming original objects to proxies. More precisely it crashes in:
> remappedObj: forwardedObj
> "Answer the given forwardedOop's target value
> during a compaction or become: operation."
> | fwdBlock targetObj |
> <inline: true>
> fwdBlock := self forwardingPointerOf: forwardedObj.
> self assert: (self fwdBlockValid: fwdBlock).
> targetObj := self longAt: fwdBlock.
> self assert: (self addressCouldBeObjWhileForwarding: targetObj).
> line targetObj := self longAt: fwdBlock.
> it seems fwdBlock has a negative value (I debugged the VM and checked its
> value) and then the longAt: gives EXC_BAD_ACCESS.
> My question is, can you imagine something that could be causing the
> crash? I would like to understand what is happening. Maybe I am becoming
> objects which are not reachable anymore and that fails?
> Any hint is really appreciated.
> Some investigations: sometimes it fails, but sometimes it works (I think
> this is because on when the GC runs). It seems that when it breaks, in
> #remapFieldsAndClassOf: the oop is a CompiledMethod and so the
> fieldOffset is the last literal, that is the assocation to the class. Since
> I also replace classes with proxies, such association has a ClassProxy in
> its value. Such class contains the 3 intsVars superclass, methodDict and
> format so that not to crash VM. Format is set with ClassProxy format.
> More information is that it doesn't crash in StackVM... moreover, it
> doesn't crash if I DO NOT create proxies for CompiledMethod .... looks like
> something with them ... So.... can this give you a hint?
Doing some more debugging, it always failing updatePointersInRangeFromto
and always the same reason. The OOP is always a compiled method and fails
in the same place. After looking a bit, the final cause is that fwdBlock1
is incorrect...but it is incorrect because of previous other incorrect
fwdBlock1 -> fieldOop -> fieldOffset -> numLiterals -> headerPointer
So from what I can see in:
/* begin literalCountOfHeader: */
/* begin headerOf: */
methodHeader = longAt((oop + BaseHeaderSize) + (HeaderIndex <<
headerPointer = (isCogMethodReference(methodHeader)
? (assert(((((CogMethod *) methodHeader)->objectHeader)) ==
(((CogMethod *) methodHeader)->methodHeader))
numLiterals = (((usqInt) headerPointer) >> 10) & 255;
it looks like if the oop is correct, but headerPointer finishes with an
incorrect (negative) value. This is return by #rawHeaderOf:
So...to sum up, I have a compiled method which seems to have its header
If with this piece of data, together with what I mentioned in the first
email, you have a hint, please tell me :)
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Vm-dev