-fno-cast-check ?!

Bryce McKinlay bryce@waitaki.otago.ac.nz
Tue Aug 6 06:01:00 GMT 2002


Norman Hendrich wrote:
>Hello,
>>with the ugly hack outlined below, I got my simulator to run
>as fast under gcj as it does under Hotspot Client (even 
>without method inlining).
>>As it turned out, my code executes multiple type casts in the
>inner loop. Unfortunately, the very simple class hierarchy 
>involved is somewhat of a "worst case" for _Jv_CheckCast.
>Eliminating the cast check results in more than 10% speedup.
>
Cool, thats very interesting. FYI I have long had a plan to improve 
GCJ's type checking. In many cases where GCJ currently always does a 
_Jv_CheckCast there is enough compile time knowledge of the type to 
replace it with a very simple inline check or even eliminate it 
completely. I agree that the type checks are currently a big performance 
sink for many applications, and its good to know that your tests confirm 
this.
>Many applications, including every application that uses
>the Java Collections API, will execute frequent downcasts. 
>It might therefore be useful to add another "overclocker" 
>command line option to gcj,
>> gcj -fno-cast-check
>>that totally eliminates the type checking overhead for those
>classes that are believed to be type-safe. What do you think?
>Yes I agree ;-)
>---- diagnosis: frequently called code sequence in my code
>>public class A { ... } // base class
>public class AA extends A { ... } // direct subclass
>>>public class App {
>> void innerLoop() {
> Iterator iterator = collection.iterator();
>> while(!done) {
> A tmp1 = (A) iterator.next(); // actually gets AA: slow
> A tmp2 = (A) iterator.next(); // actually gets AA: slow 
> ...
> result = calculateResult( tmp1, tmp2, ... );
> }
> }
>}
>>>Unfortunately, the situation sketched above is a "worst case"
>scenario for the current implementation of type cast checking
>in libjava/java/lang/natClass.cc.
>>Each cast results in a call to _Jv_CheckCast(), which checks for 
>a non-null argument and then falls through to _Jv_isAssignableFrom().
>This method includes a short-circuit test that checks whether
>the target and source classes are the same. But here, they are 
>not (target=A vs. source=AA). This means that the full method is 
>traversed, until finally Per's constant time type checking trick 
>is executed:
>> // _Jv_isAssignableFrom() 
> ...
> else if (source->ancestors != NULL
> && target->ancestors != NULL
> && source->depth >= target->depth
> && source->ancestors[source->depth - target->depth] == target)
> return true;
> ...
>>>Question 2: Is the ordering of the different tests (for array, 
>object, interfaces, primitive types) in _Jv_CheckCast necessary? 
>Perhaps a little reordering would already speed up the frequent 
>case (here, unpacking things from collections).
>
There are a few subtle ordering dependencies in there. Its possible that 
there is room for improvement, but we'd have to be careful not to break 
something. The best solution is to make the compiler smarter because 
many of those tests can be avoided with compile time knowledge. ie: we 
know at compile time when we're casting to an interface, etc.
>---- gcc/java/expr.c:
>>static void
>expand_java_CHECKCAST (type)
> tree type;
>{
> tree value = pop_value (ptr_type_node);
> value = build (CALL_EXPR, promote_type (type),
> build_address_of (soft_checkcast_node),
> tree_cons (NULL_TREE, build_class_ref (type),
> build_tree_list (NULL_TREE, value)),
> NULL_TREE);
> push_value (value);
>}
>>Question 3: Is this the right place to substitute the tree
>when trying to disable the type checks? How do I get a 
>"no operation" tree instead of the checkcast?
>>Just make it return a NOP_EXPR instead of the CALL_EXPR. See 
build_java_arraystore_check for an example of a function which does 
something similar.
regards
Bryce.


More information about the Java mailing list

AltStyle によって変換されたページ (->オリジナル) /