Java::JavaLangInvoke::WrongMethodTypeException when using invokedynamic #4148

Closed
andreaseger opened this Issue Sep 12, 2016 · 17 comments

Projects

None yet

2 participants

@andreaseger
andreaseger commented Sep 12, 2016 edited

Environment

Provide at least:

  • JRuby version:
> echo $JRUBY_OPTS
-Xcompile.invokedynamic=true --server
>jruby -v
jruby 9.1.5.0 (2.3.1) 2016-09-07 036ce39 OpenJDK 64-Bit Server VM 25.102-b14 on 1.8.0_102-b14 +indy +jit [linux-x86_64]
  • Operating system and platform (e.g. uname -a)
Linux scruffy 4.7.0-1-ARCH #1 SMP PREEMPT Mon Aug 8 22:05:58 CEST 2016 x86_64 GNU/Linux

I'm getting the following errors when running parts of my test suite of a big sinatra application using jruby 9.1.5.0 with invokedynamic enabled. The test suite is running fine without indy.

Please let me know how I can give you more information if needed. In the meantime I'll try to isolate the issue to a smaller part of our codebase.

Expected Behavior

The tests and code to run successfully

Actual Behavior

specs start to fail with the following error. Some of these specs will work if run in isolation. Others fail even if executed alone. I haven't yet been able to figure out a more precise cause as the consistently failing specs are bigger integration specs which touch quite a big surace. But suspect some jiting issue given other specs which work in isolation.

What I find also interesting is that after the error occurs the first time not necessary all following specs fail too. From what I see related codes also fails while other codeparts keep working as intended.

     Failure/Error: Unable to find java.lang.invoke.MethodHandles.explicitCastArgumentsChecks(MethodHandles.java to read failed line

     Java::JavaLangInvoke::WrongMethodTypeException:
       cannot explicitly cast MethodHandle(RubyObjectVar5)Object to (IRubyObject,IRubyObject[],Block)IRubyObject
     # java.lang.invoke.MethodHandles.explicitCastArgumentsChecks(MethodHandles.java:2038)
     # java.lang.invoke.MethodHandles.explicitCastArguments(MethodHandles.java:2026)
     # com.headius.invokebinder.transform.Cast.up(Cast.java:43)
     # com.headius.invokebinder.Binder.invoke(Binder.java:1110)
     # com.headius.invokebinder.Binder.getField(Binder.java:1355)
     # com.headius.invokebinder.Binder.getFieldQuiet(Binder.java:1376)
     # org.jruby.ir.targets.Bootstrap.createAttrReaderHandle(Bootstrap.java:422)
     # org.jruby.ir.targets.Bootstrap.buildAttrHandle(Bootstrap.java:381)
     # org.jruby.ir.targets.InvokeSite.getHandle(InvokeSite.java:197)
     # org.jruby.ir.targets.InvokeSite.invoke(InvokeSite.java:136)
     # org.jruby.internal.runtime.methods.CompiledIRMethod.invokeExact(CompiledIRMethod.java:210)
     # org.jruby.internal.runtime.methods.CompiledIRMethod.call(CompiledIRMethod.java:88)
     # org.jruby.internal.runtime.methods.CompiledIRMethod.call(CompiledIRMethod.java:93)
     # org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:128)
     # org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:189)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:318)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:131)
     # org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:340)
     # org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:73)
     # org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:84)
     # org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:179)
     # org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:165)
     # org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:197)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:338)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:163)
     # org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:315)
     # org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:73)
@headius
Member
headius commented Sep 12, 2016

From that trace it's not possible to tell where in your code it failed, and that would be helpful information. If you are able to run your specs while passing -Xjit.threshold=0 to JRuby (perhaps via JRUBY_OPTS) it would help us narrow down a reproduction.

I may be able to figure out the problem by just looking at JRuby code too, but that flag about would help.

Priority for 9.1.6.0.

@headius headius added this to the JRuby 9.1.6.0 milestone Sep 12, 2016
@andreaseger

I feared that this backtrace won't help much.
I reran a part of our test suite with the flag you mentioned and got the following

> set -x JRUBY_OPTS '-Xcompile.invokedynamic=true -Xjit.threshold=0'
> bundle exec rspec spec/samples/use_case/add_spec.rb
Unable to load thrift_native extension. Defaulting to pure Ruby libraries.
Unable to load cassandra_native extension. Defaulting to pure Ruby libraries.
/home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/ruby-debug-0.10.6/cli/ruby-debug/commands/list.rb:36: warning: `-' after local variable or literal is interpreted as binary operator
/home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/ruby-debug-0.10.6/cli/ruby-debug/commands/list.rb:36: warning: even though it seems like unary operator
I, [2016-09-12T16:46:18.186000 #4326]  INFO -- : Celluloid 0.17.3 is running in BACKPORTED mode. [ http://git.io/vJf3J ]
Coverage may be inaccurate; set "cli.debug=true" ("-Xcli.debug=true") in your .jrubyrc or do JRUBY_OPTS="-d"
bundler: failed to load command: rspec (/home/ane/.rbenv/versions/jruby-9.1.5.0/bin/rspec)
LoadError: load error: factory_girl -- java.lang.invoke.WrongMethodTypeException: cannot explicitly cast MethodHandle(RubyObjectVar5)Object to (IRubyObject,IRubyObject[],Block)IRubyObject
  org/jruby/RubyKernel.java:956:in `require'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/bundler-1.13.0/lib/bundler/runtime.rb:91:in `block in require'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/bundler-1.13.0/lib/bundler/runtime.rb:86:in `block in require'
  org/jruby/RubyArray.java:1734:in `each'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/bundler-1.13.0/lib/bundler/runtime.rb:75:in `require'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/bundler-1.13.0/lib/bundler.rb:106:in `require'
  /home/ane/runtastic/services/samples/config/environment.rb:13:in `<main>'
  org/jruby/RubyKernel.java:956:in `require'
  uri:classloader:/jruby/kernel/kernel.rb:13:in `require_relative'
  /home/ane/runtastic/services/samples/spec/spec_helper.rb:1:in `<main>'
  org/jruby/RubyKernel.java:956:in `require'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/rspec-core-3.5.3/lib/rspec/core/configuration.rb:1394:in `block in requires='
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/rspec-core-3.5.3/lib/rspec/core/configuration.rb:1394:in `requires='
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/rspec-core-3.5.3/lib/rspec/core/configuration_options.rb:112:in `block in process_options_into'
  org/jruby/RubyArray.java:1734:in `each'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/rspec-core-3.5.3/lib/rspec/core/configuration_options.rb:111:in `process_options_into'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/rspec-core-3.5.3/lib/rspec/core/configuration_options.rb:21:in `configure'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/rspec-core-3.5.3/lib/rspec/core/runner.rb:99:in `setup'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/rspec-core-3.5.3/lib/rspec/core/runner.rb:86:in `run'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/rspec-core-3.5.3/lib/rspec/core/runner.rb:71:in `run'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/rspec-core-3.5.3/lib/rspec/core/runner.rb:45:in `invoke'
  /home/ane/runtastic/services/samples/spec/spec_helper.rb:26:in `<main>'
  org/jruby/RubyKernel.java:974:in `load'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/rspec-core-3.5.3/exe/rspec:1:in `<main>'
  org/jruby/RubyKernel.java:974:in `load'

If I only run it with set -x JRUBY_OPTS '-Xjit.threshold=0' the specs work.

Let me know how else I can help while trying to get the failing codebase down to something sharable.

@headius
Member
headius commented Sep 12, 2016

That's actually close! If you can also pass -d to JRuby we can see what error is behind that LoadError (and it looks like the same problem as your report).

@andreaseger
andreaseger commented Sep 12, 2016 edited

doing the following jruby -d -S bundle exec rspec spec/samples/use_case/add_spec.rb > out 2>&1

I got this

java.lang.invoke.WrongMethodTypeException: cannot explicitly cast MethodHandle(RubyObjectVar5)Object to (IRubyObject,IRubyObject[],Block)IRubyObject
    at java.lang.invoke.MethodHandles.explicitCastArgumentsChecks(MethodHandles.java:2038)
    at java.lang.invoke.MethodHandles.explicitCastArguments(MethodHandles.java:2026)
    at com.headius.invokebinder.transform.Cast.up(Cast.java:43)
    at com.headius.invokebinder.Binder.invoke(Binder.java:1110)
    at com.headius.invokebinder.Binder.getField(Binder.java:1355)
    at com.headius.invokebinder.Binder.getFieldQuiet(Binder.java:1376)
    at org.jruby.ir.targets.Bootstrap.createAttrReaderHandle(Bootstrap.java:422)
    at org.jruby.ir.targets.Bootstrap.buildAttrHandle(Bootstrap.java:381)
    at org.jruby.ir.targets.InvokeSite.getHandle(InvokeSite.java:197)
    at org.jruby.ir.targets.InvokeSite.invoke(InvokeSite.java:136)
    at home.ane.$_dot_rbenv.versions.jruby_minus_9_dot_1_dot_5_dot_0.lib.ruby.gems.shared.gems.factory_girl_minus_4_dot_5_dot_0.lib.factory_girl_dot_rb.RUBY$method$strategies$0(/home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/factory_girl-4.5.0/lib/factory_girl.rb:63)
    at org.jruby.internal.runtime.methods.CompiledIRMethod.invokeExact(CompiledIRMethod.java:210)
    at org.jruby.internal.runtime.methods.CompiledIRMethod.call(CompiledIRMethod.java:88)
    at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:93)
    at org.jruby.ir.targets.InvokeSite.invoke(InvokeSite.java:140)
    at home.ane.$_dot_rbenv.versions.jruby_minus_9_dot_1_dot_5_dot_0.lib.ruby.gems.shared.gems.factory_girl_minus_4_dot_5_dot_0.lib.factory_girl_dot_rb.RUBY$method$register_strategy$0(/home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/factory_girl-4.5.0/lib/factory_girl.rb:102)
    at org.jruby.internal.runtime.methods.CompiledIRMethod.invokeExact(CompiledIRMethod.java:210)
    at org.jruby.internal.runtime.methods.CompiledIRMethod.call(CompiledIRMethod.java:88)
    at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:93)
    at org.jruby.ir.targets.InvokeSite.invoke(InvokeSite.java:140)
    at home.ane.$_dot_rbenv.versions.jruby_minus_9_dot_1_dot_5_dot_0.lib.ruby.gems.shared.gems.factory_girl_minus_4_dot_5_dot_0.lib.factory_girl_dot_rb.RUBY$method$register_default_strategies$0(/home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/factory_girl-4.5.0/lib/factory_girl.rb:111)
    at org.jruby.internal.runtime.methods.CompiledIRMethod.invokeExact(CompiledIRMethod.java:223)
    at org.jruby.internal.runtime.methods.CompiledIRMethod.call(CompiledIRMethod.java:97)
    at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:128)
    at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:189)
    at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:318)
    at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:131)
    at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:340)
    at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:73)
    at org.jruby.ir.interpreter.Interpreter.INTERPRET_ROOT(Interpreter.java:112)
    at org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:99)
    at org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:35)
    at org.jruby.ir.IRTranslator.execute(IRTranslator.java:42)
    at org.jruby.Ruby.runInterpreter(Ruby.java:850)
    at org.jruby.Ruby.loadFile(Ruby.java:2976)
    at org.jruby.runtime.load.LibrarySearcher$ResourceLibrary.load(LibrarySearcher.java:243)
    at org.jruby.runtime.load.LibrarySearcher$FoundLibrary.load(LibrarySearcher.java:34)
    at org.jruby.runtime.load.LoadService.tryLoadingLibraryOrScript(LoadService.java:885)
    at org.jruby.runtime.load.LoadService.smartLoadInternal(LoadService.java:525)
    at org.jruby.runtime.load.LoadService.require(LoadService.java:396)
    at org.jruby.RubyKernel.requireCommon(RubyKernel.java:963)
    at org.jruby.RubyKernel.require19(RubyKernel.java:956)
    at org.jruby.RubyKernel$INVOKER$s$1$0$require19.call(RubyKernel$INVOKER$s$1$0$require19.gen)
    at org.jruby.internal.runtime.methods.JavaMethod$JavaMethodOneOrNBlock.call(JavaMethod.java:383)
    at org.jruby.internal.runtime.methods.AliasMethod.call(AliasMethod.java:61)
    at home.ane.$_dot_rbenv.versions.jruby_minus_9_dot_1_dot_5_dot_0.lib.ruby.gems.shared.gems.bundler_minus_1_dot_13_dot_0.lib.bundler.runtime_dot_rb.RUBY$block$require$2(/home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/bundler-1.13.0/lib/bundler/runtime.rb:91)
    at org.jruby.runtime.CompiledIRBlockBody.yieldDirect(CompiledIRBlockBody.java:156)
    at org.jruby.runtime.BlockBody.yield(BlockBody.java:108)
    at org.jruby.runtime.Block.yield(Block.java:167)
    at org.jruby.specialized.RubyArrayOneObject.each(RubyArrayOneObject.java:128)
    at home.ane.$_dot_rbenv.versions.jruby_minus_9_dot_1_dot_5_dot_0.lib.ruby.gems.shared.gems.bundler_minus_1_dot_13_dot_0.lib.bundler.runtime_dot_rb.RUBY$block$require$1(/home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/bundler-1.13.0/lib/bundler/runtime.rb:86)
@headius
Member
headius commented Sep 12, 2016

Ok, great. So whatever attribute accessor is being called at factory_girl-4.5.0/lib/factory_girl.rb:63 is our trigger.

@headius
Member
headius commented Sep 12, 2016

No luck so far reproducing this.

@headius
Member
headius commented Sep 12, 2016 edited

If you could, add this line above the delegate call:

puts method(:delegate).source_location

And give me the output.

The problem here seems to be that the delegate method, which is decidedly not an attribute accessor, is getting bound as such by mistake. I don't know how this could happen given the definition of delegate in factory_girl, so I'm wondering if it is instead picking up some other accessor. That would indicate a bug in method lookup somewhere.

@andreaseger

seems to be the one from active_support
https://github.com/rails/rails/blob/v4.1.14.2/activesupport/lib/active_support/core_ext/module/delegation.rb#L143

> bundle exec rspec spec/samples/use_case/add_spec.rb
Unable to load thrift_native extension. Defaulting to pure Ruby libraries.
Unable to load cassandra_native extension. Defaulting to pure Ruby libraries.
/home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/ruby-debug-0.10.6/cli/ruby-debug/commands/list.rb:36: warning: `-' after local variable or literal is interpreted as binary operator
/home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/ruby-debug-0.10.6/cli/ruby-debug/commands/list.rb:36: warning: even though it seems like unary operator
I, [2016-09-12T19:05:20.058000 #21668]  INFO -- : Celluloid 0.17.3 is running in BACKPORTED mode. [ http://git.io/vJf3J ]
Coverage may be inaccurate; set "cli.debug=true" ("-Xcli.debug=true") in your .jrubyrc or do JRUBY_OPTS="-d"
/home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/activesupport-4.1.14.2/lib/active_support/core_ext/module/delegation.rb
143
bundler: failed to load command: rspec (/home/ane/.rbenv/versions/jruby-9.1.5.0/bin/rspec)
LoadError: load error: factory_girl -- java.lang.invoke.WrongMethodTypeException: cannot explicitly cast MethodHandle(RubyObjectVar5)Object to (IRubyObject,IRubyObject[],Block)IRubyObject
  org/jruby/RubyKernel.java:956:in `require'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/bundler-1.13.0/lib/bundler/runtime.rb:91:in `block in require'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/bundler-1.13.0/lib/bundler/runtime.rb:86:in `block in require'
  org/jruby/RubyArray.java:1734:in `each'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/bundler-1.13.0/lib/bundler/runtime.rb:75:in `require'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/bundler-1.13.0/lib/bundler.rb:106:in `require'
  /home/ane/code/jruby_indy_bug/samples/config/environment.rb:13:in `<main>'
  org/jruby/RubyKernel.java:956:in `require'
  uri:classloader:/jruby/kernel/kernel.rb:13:in `require_relative'
  /home/ane/code/jruby_indy_bug/samples/spec/spec_helper.rb:1:in `<main>'
  org/jruby/RubyKernel.java:956:in `require'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/rspec-core-3.5.3/lib/rspec/core/configuration.rb:1394:in `block in requires='
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/rspec-core-3.5.3/lib/rspec/core/configuration.rb:1394:in `requires='
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/rspec-core-3.5.3/lib/rspec/core/configuration_options.rb:112:in `block in process_options_into'
  org/jruby/RubyArray.java:1734:in `each'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/rspec-core-3.5.3/lib/rspec/core/configuration_options.rb:111:in `process_options_into'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/rspec-core-3.5.3/lib/rspec/core/configuration_options.rb:21:in `configure'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/rspec-core-3.5.3/lib/rspec/core/runner.rb:99:in `setup'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/rspec-core-3.5.3/lib/rspec/core/runner.rb:86:in `run'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/rspec-core-3.5.3/lib/rspec/core/runner.rb:71:in `run'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/rspec-core-3.5.3/lib/rspec/core/runner.rb:45:in `invoke'
  /home/ane/code/jruby_indy_bug/samples/spec/spec_helper.rb:26:in `<main>'
  org/jruby/RubyKernel.java:974:in `load'
  /home/ane/.rbenv/versions/jruby-9.1.5.0/lib/ruby/gems/shared/gems/rspec-core-3.5.3/exe/rspec:1:in `<main>'
  org/jruby/RubyKernel.java:974:in `load'
@headius
Member
headius commented Sep 12, 2016

Hmm, indeed it does. So much for that theory.

I have a possible fix for this but I'm still very confused why it's seeing this method as an attribute accessor.

@headius headius added a commit that referenced this issue Sep 13, 2016
@headius headius Only do attr binding if arity is appropriate. See #4148
I'm still baffled as to why we'd be following either of these
paths for a plain Ruby method (ActiveSupport's "delegate" method
in #4148) but this should at least prevent us from attempting to
bind those methods at attrs.
3b24d24
@headius
Member
headius commented Sep 13, 2016

I have pushed a fix to master that should prevent this from happening. It's still rather a mystery why it happened at all...and I hate unsolved mysteries.

If you can build JRuby, give it a try. Otherwise check http://ci.jruby.org for a snapshot build after this post (I'll try to kick one off now.

@andreaseger

I just got around testing a snapshot (2016-09-14T04:37:55.000Z snapshots/master/jruby-bin-9.1.6.0-SNAPSHOT.tar.gz) and yes now it works.

Maybe next week I find some time to try creating something reproducible. So the mystery can be solved properly.

@andreaseger

I managed to create a reproducible example (not sure if it could have been more minimal) and pushed it here https://github.com/andreaseger/jruby_indy_wrong_method_type_exception_example

Maybe this helps finding out why this is happening in the first place

@headius
Member
headius commented Sep 19, 2016

@andreaseger Great, thank you! I'll have a look at your repro.

@headius
Member
headius commented Sep 19, 2016

Ah-ha, now I see why the line numbers didn't make any sense; delegate causes new methods to be eval'ed with file and line number set to the location of the delegate call. So the problem was not in that call but in one of the eval'ed methods.

And now I have my answer. The problem is that this attempts to call an attribute accessor generically using *args and so on. My logic for binding attributes directly does not consider this case, instead assuming that all attr reader calls will be simple ones with no arguments. That explains why my fix worked...it would refuse to directly bind attributes when they were called with unusual argument layouts.

I'll have a proper spec shortly, and I'll see if I can improve the binding for these cases.

@headius
Member
headius commented Sep 19, 2016

Trivial reproduction:

$ jruby -Xcompile.invokedynamic -e "class A; attr_reader :foo; end; args = []; A.new.foo(*args)"
Unhandled Java exception: java.lang.invoke.WrongMethodTypeException: cannot explicitly cast MethodHandle(RubyObjectVar0)Object to (IRubyObject,IRubyObject[])IRubyObject
java.lang.invoke.WrongMethodTypeException: cannot explicitly cast MethodHandle(RubyObjectVar0)Object to (IRubyObject,IRubyObject[])IRubyObject
  explicitCastArgumentsChecks at java/lang/invoke/MethodHandles.java:2039
        explicitCastArguments at java/lang/invoke/MethodHandles.java:2027
                           up at com/headius/invokebinder/transform/Cast.java:43
                       invoke at com/headius/invokebinder/Binder.java:1110
                     getField at com/headius/invokebinder/Binder.java:1355
                getFieldQuiet at com/headius/invokebinder/Binder.java:1376
       createAttrReaderHandle at org/jruby/ir/targets/Bootstrap.java:422
              buildAttrHandle at org/jruby/ir/targets/Bootstrap.java:381
                    getHandle at org/jruby/ir/targets/InvokeSite.java:197
                       invoke at org/jruby/ir/targets/InvokeSite.java:136
                       <main> at -e:1
@headius
Member
headius commented Sep 19, 2016

I've added a spec and I'm satisfied with the fix. Calling an attribute reader in this way will not optimize as well as calling it with no arguments, but because of the variable nature of splats it's tricky to make this a direct operation. As it is, the empty array still would get created anyway.

I'll be getting jit specs running under indy today.

@headius headius closed this Sep 19, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment