Charles Oliver Nutter schrieb:
> Jochen Theodorou wrote:
>> Charles Oliver Nutter schrieb:
[...]
>> my point wasn't so much, that it is not possible, it is more that when 
>> target is invoked, the call to target is no tail call anymore now. That 
>> means the stack frame can not be removed, even if we had tail calls. 
>> retconv is in tail call position, but that won't get me much
> 
> You wouldn't do this; you'd provide those handles to some 
> MethodHandles.adapt* variant and it would handle invoking each of them 
> for you.

true... only that it is not part of picture yet, just an idea. By 
showing the problems of alternatives you get to know how much you really 
want the the realization of that idea ;)

> My general assumption in all this is that once we've presented 
> a set of handles to self-contained functions and told the JVM how to 
> stitch them together, it can do what it pleases with the stack.

yes, I hope we add this.

> I don't think there's a reason that a Java stack frame ever *has to* be 
> created unless the JVM actually needs it; and in this case it does not. 

I see thatthe same way, but maybe John does see it in a different way, 
since he is the VM guy here.

> Each of the pieces is free-standing, has no side effects, and does not 
> directly intervene in the call stack. Now if you have dependencies on 
> converting arguments being returned, that's a complication introduced by 
> your implementation that's unavoidable; the return values from the 
> actual call is no longer the last operation in the method. I don't doubt 
> the JVM can reduce that cost, but it could never be a tail call because 
> it's not a tail call. How common is this?

I guess in cases of

T x = foo()
x = bar()

where this is really needed I can work with the Groovy-made-checkcast... 
only when the method returns a primitive this won't do anymore, because 
I need to box first

So probably the only problem are primitive returning methods.

> But back to the point; even if it's not a tail call, I don't expect 
> you'd ever see anything but a chain of Groovy methods in the call stack, 
> all the way up to the first non-Groovy target method. The handles would 
> ideally be entirely invisible.

would the stack frame be invisible to things like Class.forName too?

>>> As does JRuby...but I think we are not formal about which method we 
>>> select. The first best match, in reflection order, I guess.
>> we are formal, we use the most common version, for example if there is 
>> foo(Object), then it gets it... we introduced a NullObject class, but 
>> that can not be used for method parameters yet. In the long term we want 
>> to change that, so that you can define foo(null) to catch the null 
>> cases. Well, it has no priority atm
> 
> You mean the most general version? 

sorry, yes.

> That's not a bad rule. Perhaps we 
> could adopt the same. It's better than the reflection order we "let 
> work" now.

in fact it is exactly as the normal method selection rule, which selects 
the "most specific" method, but it makes sense.. also you can in groovy 
combine null with a cast to force certain methods being selected.

[...]
>> but my goal is to not have any boxing if possible. And 
>> even if I use only double, float, int, long and Object I have already 5 
>> types that can be combined in argument types and return types. And 
>> counting for positions I have over 500 possibilities00. 4 positions, 
>> that are 4 arguments and void/Object, or 3 arguments and return type. Or 
>> did I make a mistake?
> 
> Mathematically, probably not. But you would not generate all these 
> signatures.

yes, but the point is, that I still need code generation at runtime. If 
it where only a fixed set of maybe 256 classes, then I could generate 
them beforehand

> The actual number of real signatures in a real application 
> would be far, far fewer than all permutations of all known types. The 
> practical maximum would be one for every method in the system, and 
> that's if you loaded all of them, bound all their methods, and they all 
> had different signatures. Let's call that the worst case scenario. So 
> this is where using composable method handles makes a lot more sense 
> than generating all your own signature into a static class or generating 
> them at runtime.

I agree.

> MethodHandles would provide a lightweight mechanism for 
> efficiently referencing all those method signatures, and for composing 
> adapters for them as needed. At the very least, the method handles for 
> all those methods would be far smaller in memory than, for example, the 
> bytecode that represents them; so this theoretical worst case would be 
> gigantic already, with or without a handle per signature. Real systems 
> won't be like that, and I doubt the method handle cost would be as high 
> as you think.

I don't have problems with the cost of the MethodHandle, only with 
runtime code generation... but maybe that fear is without reason, 
because you work without any specific types in such an adapter. If there 
is no specific type (besides some primitives maybe), then there is no 
class loading problem with the class loader that I have to use to 
"store" my class.

>>> Does Groovy still use reflection to invoke arbitrary Java methods?
>> partially. For some GDK methods no reflection will be used, because we 
>> have pre-build stubs for them. For general methods... we still use 
>> reflection, because of possible class loader issues if we generate 
>> direct code.
> 
> JRuby uses direct calls for all core JRuby classes and any extensions 
> written directly to JRuby, and for classes outside JRuby (Java classes) 
> we use reflection. But I see a path to removing *all* of that binding 
> logic, PLUS our call site logic, PLUS Java argument conversion logic, 
> PLUS Ruby argument coersion, PLUS a bunch of pre/post method logic and 
> stuffing it all into method handles. The picture in my head is pretty 
> nice, and I'm trying to communicate it to John as best I can while he 
> moves forward with things on his end. I think it's going well so far.

I think we are on the same side for this ;)

[...]
> JRuby can in general perform similarly, though there's overhead related 
> to Ruby features that's more difficult to eliminate than in Groovy's 
> case. I would expect that the JIT can work in concert with invokedynamic:
> 
> - First compiled output produces the most generate invokedynamic sites 
> possible, which get bound to handles that inspect arg lists, do full 
> lookup, and so on.
> - Future refinements to the compiled output produce specialized 
> invocations with guards, so that if the types match those seen 
> previously you can pass more information on to the bootstrap.
> - The dynamic binding passes through some adapted method handle in each 
> case, but the resulting stack trace looks as though the call went 
> directly from the call site to the target method. You would cut out all 
> intervening logic.
> 
> So iterative specialization of the bytecode becomes a matter of 
> generating a series of likely dynamic invocation method signatures 
> (potentially one, if you've only seen one) to choose from that will each 
> get bound to the appropriate target method.
> 
> Honestly, I believe invokedynamic as it's currently coming together is 
> going to work extremely well for Groovy. Nothing I've heard so far makes 
> me think otherwise.

we are not there yet, but it seems to be on the right path

bye blackdrag

-- 
Jochen "blackdrag" Theodorou
The Groovy Project Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
http://www.g2one.com/

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "JVM 
Languages" group.
To post to this group, send email to jvm-languages@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/jvm-languages?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to