[Vm-dev] When Cog should deoptimize CM and when its not?

Igor Stasenko siguctua at gmail.com
Fri Mar 8 22:34:44 UTC 2013


Hi, Eliot & all

I was looking at #become: code
and did not found the place where it deoptimizing compiled methods to
throw away the jited version of it (if it has one),
before even trying to do anything with it.

i know it pricey, because it should:

 - remove CogMethod from JIT zone
 - walk the stack and look for all activations of it, and replace
native code instruction pointer with bytecode instruction pointer
 - fix the compiled method's header
(another alternative, if method has activations, i would fail
primitive actually, because this is too hard to do things right and
very dangerous
to play with, as well as it makes little sense )

IMO, if we add that, then we could minimize the impact of JIT
complexity on #become: and make things work
in same way as in stack vm (which is stable ;).
And since become scans part/whole heap.. deoptimizing the CM would not
add too much on top :)

I don't know if it is there, maybe it is.. then sorry for first part..
but not the second one:


objectAt: index put: value
	"Primitive. Store the value argument into a literal in the receiver. An
	index of 2 corresponds to the first literal. Fails if the index is less than 2
	or greater than the number of literals. Answer the value as the result.
	Normally only the compiler sends this message, because only the
	compiler stores values in CompiledMethods. Essential. See Object
	documentation whatIsAPrimitive."

	<primitive: 69>
	self primitiveFailed

i was playing with metaprogramming , using
#literalAt:put:
to store/change some value directly in method's literal (yeah.. you
can kill the messenger and stop reading further ;) .

And i found that the change is not immediately visible..

My idea is plain simple:
 - you have a template method, like:

 foo
   ^ 'ssssss'

and then i simply doing things like:

 copy := foo copy literalAt:1 put: 'bar'.
 methodDict at: #bar put: copy

and when i wanna change the #bar value next time, i don't creating new
method again, but just modifying
its literal.
Things worked perfectly on old interpreted VMs and i used this
trickery to implement prototypes (where object's properties
are held by correspoding CM )

But with Cog, because of its aggressive caching, it no longer working:

at: aName put: value
	| method |
	
	(getter methodDict includesKey: aName) ifTrue: [
		
		method := getter methodDict at: aName.
		method literalAt: 1 put: value.
		method flushCache.
		
	] ifFalse: [
		
		method := getter addReadAccessorFor: aName value: value.
		setter addWriteAccessorFor: aName readAccessor: method.
	].
	aName flushCache.
	
	^ value

here neither "method flushCache. " nor "aName flushCache." helps with it..
my test still fails.
But of course, when i click to debug , it magically passes when i
evaluating very same expression in debugger :)

Things working only when i always replacing things with new method(s)
(as i doing under under ifFalse: clause).

I strongly suggest that <primitive: 69> should always deoptimize CM
(throw away Cogged method , even if it has high price to pay)
as well as #flushCache (<primitive: 116>) should also do the same, because
  - JITed code is a cache
  - we should have a means to throw it away when asked so

The #voidCogVMState flushes all machine code.. but is it possible to
make more could we have one which flushing only particular one?

(...in alternative universe, i'd rather look for a way how to
"deoptimize Jited method in smart way, so when you deoptimizing the
CM,
it won't require scanning stacks to patch instruction pointers, and
instead mark/make jited code obsolete by:

- patching the machine code at entry point to immediately switch back
to interpreter mode of corresponding method (to prevent spawning new
activations with native code)
 - patching the machine code at every possible return address (call
sites) to immediately switch to interpreter (to gracefully handle
existing activations so, there is no need to fix instruction pointers)
 - keep that obsolete CogMethod till next GC.
 ;)



-- 
Best regards,
Igor Stasenko.


More information about the Vm-dev mailing list