Actually, from CoInterpreter:

addNewMethodToCache: class
"Override to refuse to cache other than compiled methods.
 This protects open PICs against having to test for compiled methods."
(objectMemory isOopCompiledMethod: newMethod) ifFalse:
[primitiveFunctionPointer := #primitiveInvokeObjectAsMethod.
^self].
super addNewMethodToCache: class


On Fri, May 31, 2013 at 9:20 AM, Guillermo Polito <[email protected]
> wrote:

> 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 <[email protected]> wrote:
>
>> On 30 May 2013 20:06, Guillermo Polito <[email protected]> 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.
>>
>>
>

Reply via email to