United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-8005418 : JSR 292: virtual dispatch bug in 292 impl

Details
Type:
Bug
Submit Date:
2012-12-21
Status:
Resolved
Updated Date:
2013-04-30
Project Name:
JDK
Resolved Date:
2013-01-10
Component:
hotspot
OS:
Sub-Component:
compiler
CPU:
Priority:
P3
Resolution:
Fixed
Affected Versions:
Fixed Versions:
hs25 (b15)

Related Reports
Backport:
Backport:
Backport:
Relates:

Sub Tasks

Description
http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2012-December/009201.html

I wasn't sure if this had been filed already by Christian, so I wanted
to post here.

It appears that in C1, method handles are not properly dispatching to
an overridden version of a method. My reproduction case is tied to
JRuby, but I can come up with something isolated if necessary.

In JRuby, the ENV object is a subclass of a Ruby Hash. Rather than
rebinding all of Hash's methods (defined on org.jruby.RubyHash), the
ENV impl just overrides them at the Java level. When dispatching to
the [] method on ENV with invokedynamic, the handle points at
RubyHash.op_aref, the implementation of [] for Hash. The ENV version
should raise an error...but it does not, because it dispatches to the
superclass version rather than the subclass version.

If I turn off tiered compilation, the code works as expected.

Reproduction for JRuby is here: https://gist.github.com/4311979

I tested on hotspot-comp built yesterday:

openjdk version "1.8.0-internal"
OpenJDK Runtime Environment (build 1.8.0-internal-headius_2012_12_15_16_45-b00)
OpenJDK 64-Bit Server VM (build 25.0-b13, mixed mode)

If I have time I'll try to investigate in more depth.

- Charlie
                                    

Comments
Contrary to the report it seems to be a C2 problem, not C1:

cthaling@sc14ia01:~/jruby$ jruby -J-showversion -J-client test_env.rb 
java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b69)
Java HotSpot(TM) Client VM (build 25.0-b13, mixed mode)

Run options: 

# Running tests:

.

Finished tests in 53.285000s, 0.0188 tests/s, 1876.7008 assertions/s.

1 tests, 100000 assertions, 0 failures, 0 errors, 0 skips
cthaling@sc14ia01:~/jruby$ jruby -J-showversion -J-server -J-XX:-TieredCompilation test_env.rb 
java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b69)
Java HotSpot(TM) Server VM (build 25.0-b13, mixed mode)

Run options: 

# Running tests:

F

Finished tests in 2.222000s, 0.4500 tests/s, 424.8425 assertions/s.

  1) Failure:
test_bracket(TestEnv) [test_env.rb:11]:
TypeError expected but nothing was raised.

1 tests, 944 assertions, 1 failures, 0 errors, 0 skips
cthaling@sc14ia01:~/jruby$ jruby -J-showversion -J-server -J-XX:+TieredCompilation -J-XX:TieredStopAtLevel=3 test_env.rb 
java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b69)
Java HotSpot(TM) Server VM (build 25.0-b13, mixed mode)

Run options: 

# Running tests:

.

Finished tests in 90.676000s, 0.0110 tests/s, 1102.8277 assertions/s.

1 tests, 100000 assertions, 0 failures, 0 errors, 0 skips

                                     
2012-12-21
Inlining org.jruby.RubyHash::op_aref in that compile is the bug:

 12903  956             java.lang.invoke.LambdaForm$MH/847376::convert (52 bytes)
                           @ 15   java.lang.invoke.LambdaForm$BMH/23638730::reinvoke (26 bytes)   inline (hot)
                             @ 12   java.lang.invoke.BoundMethodHandle$Species_LL::reinvokerTarget (8 bytes)   inline (hot)
                             @ 22   java.lang.invoke.LambdaForm$DMH/20340225::invokeStatic_LL_L (15 bytes)   inline (hot)
                               @ 1   java.lang.invoke.DirectMethodHandle::internalMemberName (8 bytes)   inline (hot)
                               @ 11   sun.invoke.util.ValueConversions::castReference (6 bytes)   inline (hot)
                                 @ 2   java.lang.Class::cast (27 bytes)   inline (hot)
                                   @ 6   java.lang.Class::isInstance (0 bytes)   (intrinsic)
                           @ 33   java.lang.Class::cast (27 bytes)   inline (hot)
                             @ 6   java.lang.Class::isInstance (0 bytes)   (intrinsic)
                           @ 43   java.lang.Class::cast (27 bytes)   inline (hot)
                             @ 6   java.lang.Class::isInstance (0 bytes)   (intrinsic)
                           @ 48   java.lang.invoke.LambdaForm$DMH/32367447::invokeVirtual_LLL_L (18 bytes)   inline (hot)
                             @ 1   java.lang.invoke.DirectMethodHandle::internalMemberName (8 bytes)   inline (hot)
                             @ 14   org.jruby.RubyHash::op_aref (23 bytes)   inline (hot)
                               @ 2   org.jruby.RubyHash::internalGet (9 bytes)   inline (hot)
                                \-> TypeProfile (5247/5247 counts) = org/jruby/RubyHash
                                 @ 2   org.jruby.RubyHash::internalGetEntry (51 bytes)   inline (hot)
                                   @ 1   java.lang.Object::hashCode (0 bytes)   (intrinsic, virtual)
                                   @ 4   org.jruby.RubyHash::hashValue (5 bytes)   inline (hot)
                                     @ 1   org.jruby.RubyHash::MRIHashValue (5 bytes)   inline (hot)
                                   @ 18   org.jruby.RubyHash::bucketIndex (6 bytes)   inline (hot)
                                     @ 2   org.jruby.RubyHash::MRIBucketIndex (7 bytes)   inline (hot)
                                   @ 31   org.jruby.RubyHash::internalKeyExist (42 bytes)   inline (hot)
                                     @ 1   org.jruby.RubyHash$RubyHashEntry::access$300 (5 bytes)   inline (hot)
                                     @ 9   org.jruby.RubyHash$RubyHashEntry::access$500 (5 bytes)   inline (hot)
                                   @ 40   org.jruby.RubyHash$RubyHashEntry::access$200 (5 bytes)   inline (hot)
                                 @ 5   org.jruby.RubyHash$RubyHashEntry::access$400 (5 bytes)   inline (hot)

                                     
2013-01-04
The logic in CallGenerator::for_method_handle_inline does not pass call_is_virtual correctly.  Currently target->is_abstract() is used as a workaround.

The fix is to do the same thing as Parse::do_call is doing.

                                     
2013-01-04
After that fix there is a 20% regression with navier-stokes on Nashorn:

cthaling@sc14ia01:~/nashorn/v8$ java -showversion -server -XX:-TieredCompilation -Xmx3G -Xms3G -jar ~/nashorn/nashorn/dist/nashorn.jar run-v8.js -- --verbose --iterations 10 navier-stokes.js 
java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b70)
Java HotSpot(TM) Server VM (build 25.0-b15-internal, mixed mode)

command line: running navier-stokes.js...
Score: 2489
Score: 3350
Score: 3554
Score: 3217
Score: 3659
Score: 3677
Score: 3688
Score: 3699
Score: 3692
Score: 3681
command line: NavierStokes (version 8): 2489-3699

cthaling@sc14ia01:~/nashorn/v8$ java -showversion -server -XX:-TieredCompilation -Xmx3G -Xms3G -jar ~/nashorn/nashorn/dist/nashorn.jar run-v8.js -- --verbose --iterations 10 navier-stokes.js 
java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b70)
Java HotSpot(TM) Server VM (build 25.0-b15-internal, mixed mode)

command line: running navier-stokes.js...
Score: 2582
Score: 2890
Score: 2722
Score: 2921
Score: 2621
Score: 3002
Score: 3002
Score: 2991
Score: 3023
Score: 3014
command line: NavierStokes (version 8): 2582-3023

Probably a virtual method that's not inlined anymore because of missing profiles.
                                     
2013-01-05
D'oh ;)
                                     
2013-01-08
URL:   http://hg.openjdk.java.net/hsx/hotspot-comp/hotspot/rev/5698813d45eb
User:  twisti
Date:  2013-01-10 03:16:38 +0000

                                     
2013-01-10
URL:   http://hg.openjdk.java.net/hsx/hsx25/hotspot/rev/5698813d45eb
User:  amurillo
Date:  2013-01-11 12:07:43 +0000

                                     
2013-01-11



Hardware and Software, Engineered to Work Together