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. >> >
