Le 02/11/2009 18:40, John Wilson a écrit :
> 2009/11/2 Charles Oliver Nutter<[email protected]>:
>    
>> On Mon, Nov 2, 2009 at 7:11 AM, Jochen Theodorou<[email protected]>  wrote:
>>      
>>> Oh you would wonder... In fact we call it optional typing in Groovy, but
>>> it is really very much like gradual typing. Only the compiler is not
>>> using the type information to speed up the program. We will change that
>>> for Groovy 1.8.
>>>
>>> I should maybe try to explain a difference between the Java type system
>>> and the one Groovy uses. In Groovy a method call on an object with Type
>>> T is not limited to the methods declared for this type.  Instead the
>>> runtime type is used. Since Groovy supports overloading of methods too,
>>> that means you cannot relay on information you find in the type, unless
>>> it is a really a direct match. If you have an Object typed variable x
>>> and do x.foo(), and the runtime type of x will be Foo, which has a foo()
>>> method, then the call will succeed. Since we at compile time don't know
>>> the type Foo, we cannot generate a direct method call for that. And now
>>> optional typing in 1.8 will come into play. You can type the variable as
>>> Foo and the compiler will be able to generate a direct method call on x
>>> using Foo. Also in Groovy you don't need casts when you assign something
>>> to a typed variable. Instead Groovy will add an implicit cast. This way
>>> Groovy ensures, that the variable will contain an object of at least
>>> that type all the time. It is like declaring an upper bound kind of (if
>>> parents are above).
>>>        
>> Won't this break existing behavior? Currently, even if you declare a
>> type, it will still dispatch based on the runtime set of methods for
>> that type. So in your example, if I have replaced the foo() method on
>> Foo with some other piece of code, will statically declaring my
>> variables as type Foo dispatch to the original foo() method or the one
>> I've replaced? This is the conundrum I face in Ruby, where we already
>> can gather type feedback to know a variable is always X, but still
>> need to check if X is being modified so our direct calls are valid.
>> Some of this exists already in JRuby; if you call a numeric method
>> directly against a Fixnum (boxed 64-bit integer), it will go straight
>> in and even inline the logic. Upcoming compiler work will also start
>> to add type and method guards to inlined/optimized versions of code.
>> But the mutability of classes common to both Ruby and Groovy means
>> unguarded direct calls will probably always be suspect.
>>      
>
> It's a good question!
>
> It's virtually impossible to do effective type inferencing with Groovy
> semantics. E.G. with
>
> int a = 1
> int b = 2
> def x = a + b
>
> you have no idea of the type of x. Indeed if this code is executed at
> the same time in two different threads x can end up being two
> different types (because of Categories).
>
> It's, at least theoretically, possible to do speculative execution of
> some classes of Groovy expression and, if you can do a cheap test to
> ensure that the operators have not been overloaded, you can get
> execution speeds within an order of magnitude of straight Java.
>
> I have never seen any way of doing unguarded direct method calls in
> Groovy. It is possible to generate synthetic helper methods on a
> compiled Groovy class which can be safely called directly but these
> helper methods need to do checks before they can pass the call on to
> the target method; so you are, in effect, doing guarded calls.
>    

In september, just at the end of the summit, we (or I and)
the JSR292 EG group talk a lot about Jochen presentation
(JRuby exhibits exactly the same problem).

Yes currently you have to check some metaclass invariant
and that check cost a lot because it need to be a volatile check.

But I think John proposes a very good solution that need to
be implemented to be sure.
The magic word here is invalidation.

The idea is to let the code without guard but to be able
to trigger a VM safepoint. At this safepoint, all or some
callsites will be invalided, i.e the callsite target will be flushed
and the callsite will be in state that will require
to call the bootstrap method to re-initialise its target.

The thread that has triggered the invalidation will hold a lock
to change the hierarchy, i.e do all language specific modifications.
If during this step another thread want to call a callsite target,
because the callsite was invalided it will require to call the
bootstrap method again. And to acheive proper synchronisation,
the BSM should try to take the lock beore installing a new target.
If the lock is held by the thread that has required invalidation,
the thread will just wait on the lock..

If invalidation works, you can get ride all of guards against
metaclass modification. And if a metaclass modification
occurs, all callsite targets will be flushed and new target
will need to be reinstalled.

So please guys, push to have a real invalidation implementation
and don't add guards. Let the VM do the magics :)

> Because, in the general case, Groovy needs to examine the type of each
> parameter at runtime before dispatching the method (because Groovy
> supports a method dispatch mechanism very similar to Java's) this
> requires another set of guards: E.G.
>
> class C {
>    int foo(int p) {
>      return p + 2
>    }
> }
>
> int x = 1
> int y = 2
>
>
> new C().foo(x + y)
>
> there is no way you can do a direct dispatch to foo on the instance of
> C. Firstly you don't know the type of the result of x + y and secondly
> you don't know what methods have been been monkey patched onto
> instances of C.
>
> The method dispatch problem is really difficult in Groovy because of
> the need to implement Java style method selection based on the type of
> the actual parameters (In Groovy it's based on the type of the actual
> parameter not the declared type of the variable holding the actual
> parameter - but that makes it even more difficult).
>
> Still, Jochen has been thinking about this for longer than I have - so
> maybe he's seen something I've missed.
>
> John Wilson
>    

Rémi

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "JVM 
Languages" group.
To post to this group, send email to [email protected]
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