Ahh, that's why the code in CoInterpreter I was looking didn't match the C code :D. Was looking at the wrong place, hehe.
Igor, why do you say that this method should be reached only with vanilla compiled methods? From the comment I understand "For interpreter performance and to ease the objectAsMethod implementation eagerly evaluate the primtiive, i.e. if the method is cogged and has a primitive /do not/ evaluate the machine code primitive, just evaluate primitiveFunctionPointer directly." And in #addNewMethodToCache: there is as a first statement: [...] (objectMemory isOopCompiledMethod: newMethod) ifTrue: [primitiveIndex := self primitiveIndexOf: newMethod. primitiveFunctionPointer := self functionPointerFor: primitiveIndex inClass: class] ifFalse: [*primitiveFunctionPointer := #primitiveInvokeObjectAsMethod*]. [...] So I'd say that both objects as methods and primitives are kind of handled in the same way after? On Fri, May 31, 2013 at 2:27 AM, Igor Stasenko <siguc...@gmail.com> wrote: > On 30 May 2013 20:06, Guillermo Polito <guillermopol...@gmail.com> wrote: > > Ok, I was playing with flushing caches and stuff... Its still a bit > obsure > > to me why the example in the workspace works and the code coverage > doesnot. > > > > However, I managed to hack the VM to make it work :). > > > > It looks like the VM is treating the objects as methods, as cog methods. > So > > I added the following validation in the commonSend: > > > > methodHeader2 = longAt((GIV(newMethod) + BaseHeaderSize) + (HeaderIndex > << > > ShiftForWord)); > > > > if (isCogMethodReference(methodHeader2) && > > isCompiledMethodHeader(methodHeader2)) { > > > > /* begin externalizeIPandSP */ > > > > assert((((usqInt)localIP)) != (ceReturnToInterpreterPC())); > > > > GIV(instructionPointer) = oopForPointer(localIP); > > > > GIV(stackPointer) = localSP; > > > > GIV(framePointer) = localFP; > > > > executeCoggedNewMethodmethodHeader(1, methodHeader2); > > > > } > > > > > > And it works :). > > > > I cc Eliot, so maybe he has an idea... > > > I touched this code. > > Original: > > CoInterpreter>>internalExecuteNewMethod > <inline: true> > "For interpreter performance and to ease the objectAsMethod > implementation eagerly > evaluate the primtiive, i.e. if the method is cogged and has a > primitive /do not/ evaluate > the machine code primitive, just evaluate > primitiveFunctionPointer directly." > primitiveFunctionPointer ~= 0 ifTrue: > [| succeeded | > self isPrimitiveFunctionPointerAnIndex ifTrue: > [^self internalQuickPrimitiveResponse]. > "slowPrimitiveResponse may of course context-switch. If > so we must > reenter the > new process appropriately, returning only if we've found > an > interpreter frame." > self externalizeIPandSP. > succeeded := self slowPrimitiveResponse. > instructionPointer = cogit ceReturnToInterpreterPC ifTrue: > [instructionPointer := self iframeSavedIP: > framePointer]. > self internalizeIPandSP. > succeeded ifTrue: > [self return: self popStack toExecutive: true. > self browserPluginReturnIfNeeded. > ^nil]]. > "if not primitive, or primitive failed, activate the method" > (self methodHasCogMethod: newMethod) > ifTrue: [self iframeSavedIP: localFP put: localIP > asInteger. > instructionPointer := cogit > ceReturnToInterpreterPC. > self externalizeFPandSP. > self activateCoggedNewMethod: true. > self internalizeIPandSP] > ifFalse: [self internalActivateNewMethod] > > Now in subclass (NBCoInterpreter) > i made this: > > internalExecuteNewMethod > <inline: true> > "For interpreter performance and to ease the objectAsMethod > implementation eagerly > evaluate the primtiive, i.e. if the method is cogged and has a > primitive /do not/ evaluate > the machine code primitive, just evaluate > primitiveFunctionPointer directly." > > | methodHeader | > > methodHeader := self rawHeaderOf: newMethod. > > (self isCogMethodReference: methodHeader) ifTrue: [ > self externalizeIPandSP. > self executeCoggedNewMethod: true methodHeader: > methodHeader. > "we never reach here" > ]. > > primitiveFunctionPointer ~= 0 ifTrue: > [| succeeded | > self isPrimitiveFunctionPointerAnIndex ifTrue: > [^self internalQuickPrimitiveResponse]. > "slowPrimitiveResponse may of course context-switch. If > so we must > reenter the > new process appropriately, returning only if we've found > an > interpreter frame." > self externalizeIPandSP. > succeeded := self slowPrimitiveResponse. > instructionPointer = cogit ceReturnToInterpreterPC ifTrue: > [instructionPointer := self iframeSavedIP: > framePointer]. > self internalizeIPandSP. > succeeded ifTrue: > [self return: self popStack toExecutive: true. > self browserPluginReturnIfNeeded. > ^nil]]. > "if not primitive, or primitive failed, activate the method" > (self methodHasCogMethod: newMethod) > ifTrue: [self iframeSavedIP: localFP put: localIP > asInteger. > instructionPointer := cogit > ceReturnToInterpreterPC. > self externalizeFPandSP. > self activateCoggedNewMethod: true. > self internalizeIPandSP] > ifFalse: [self internalActivateNewMethod] > > === > The intent of change was: > - if method is cog method, execute it (the jited code takes care to > call primitive, if it there) > > The old code logic was: > - run primitive if it there > - and only then, if no prim/or prim failed, try to run a jited code > (but entry point is to the first bytecode of method, > not to its start) > > This (old) logic prevents from using primitive 220 properly, because > it is a "meta-primitive" - a marker > that says that given method should: > - always be jited > - actual primitive is taken by copying machine code from compiled > method trailer into CogMethod's primitive section. > Therefore executing prim 220 (a C function) ~~ invoking method's > primitive (a machine code generated by image). > > Still i cannot understand why code reaching this point, when a result > of lookup is not a compiled method, but arbitrary object, because > everything even in original code says: VM enters this method only if > it found 100% vanilla guaranteed CompiledMethod, and not something > which pretends to be it. > As i understand , the logic to handle object-as-method is in method > lookup.. but not in internalExecuteNewMethod, because VM can "execute" > the only thing it knows, and it is CompiledMethod. > > Your test says, that Cog does something extra (some magic, which i > failed to grasp) with object-as-method, > like generating special kind of CogMethod which sends #run:as:in: message > to it. > > I would like to hear Eliot's comments on this. > > > > -- > Best regards, > Igor Stasenko. > >