I'll have to give this a try once I've upgraded my machine. I only
have GLIBC_2.11 and this requires GLIBC_2.15.

Excellent news though!

frank

On 31 May 2013 14:17, Guillermo Polito <[email protected]> wrote:
> It is fixed in latest vm (which you can get from the zeroconf script
> http://get.pharo.org/vmLatest) :).
>
> Guille
>
>
> On Fri, May 31, 2013 at 1:25 PM, Igor Stasenko <[email protected]> wrote:
>>
>> On 31 May 2013 09:20, 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."
>> >
>>
>> Yes, my bad..
>> It is hard to see that in code: the logic to handle objects-as-method.
>> So, yes, please fix executNewMethod and internalExecuteNewMethod with
>> this additional check.
>>
>> > 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.
>> >>
>> >
>>
>>
>>
>> --
>> Best regards,
>> Igor Stasenko.
>>
>

Reply via email to