New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

java.lang.IncompatibleClassChangeError in 9.0.0.0 rc1 #3056

Closed
jeremyevans opened this Issue Jun 15, 2015 · 4 comments

Comments

Projects
None yet
2 participants
@jeremyevans
Contributor

jeremyevans commented Jun 15, 2015

Running Sequel's integration tests with 9.0.0.0 rc1 brings up an error similar to the following for most adapters:

C:/jruby-9.0.0.0.rc1/bin/jruby.exe -e "ARGV.each{|f| require f}" ./spec/adapters/postgres_spec.rb ./spec/integration/*_test.rb
Run options: --seed 58223

# Running:

..............................................................................................L:/sequel/lib/sequel/extensions/constraint_validations.rb:233:in `RUBY$block$create_table_generator$2': java.lang.IncompatibleClassChangeError: Class org.jruby.runtime.Block does not implement the requested interface org.jruby.runtime.builtin.IRubyObject
    from CompiledIRBlockBody.java:70:in `commonYieldPath'
    from IRBlockBody.java:146:in `doYield'
    from BlockBody.java:83:in `yield'
    from Block.java:151:in `yieldNonArray'
    from RubyBasicObject.java:1738:in `yieldUnder'
    from RubyBasicObject.java:1764:in `specificEval'
    from RubyBasicObject.java:1638:in `instance_eval19'
    from RubyBasicObject$INVOKER$i$instance_eval19.gen:-1:in `call'
    from CachingCallSite.java:139:in `callBlock'
    from CachingCallSite.java:145:in `call'
    from L:/sequel/lib/sequel/database/schema_generator.rb:-1:in `invokeOther18:instance_eval'
    from L:/sequel/lib/sequel/database/schema_generator.rb:39:in `RUBY$method$initialize$0'
    from CompiledIRMethod.java:131:in `call'
    from MixedModeIRMethod.java:183:in `call'
    from CachingCallSite.java:171:in `callBlock'
    from CachingCallSite.java:177:in `call'
    from RubyClass.java:860:in `newInstance'
    from RubyClass$INVOKER$i$newInstance.gen:-1:in `call'
    from CachingCallSite.java:171:in `callBlock'
    from CachingCallSite.java:177:in `call'
    from L:/sequel/lib/sequel/database/schema_methods.rb:-1:in `invokeOther1:new'
    from L:/sequel/lib/sequel/database/schema_methods.rb:230:in `RUBY$method$create_table_generator$0'
    from CompiledIRMethod.java:101:in `call'
    from MixedModeIRMethod.java:113:in `call'
    from IRRuntimeHelpers.java:928:in `unresolvedSuper'
    from IRRuntimeHelpers.java:910:in `unresolvedSuperSplatArgs'
    from L:/sequel/lib/sequel/extensions/constraint_validations.rb:-1:in `invokeSuper9:-unknown-super-target-'
    from L:/sequel/lib/sequel/extensions/constraint_validations.rb:230:in `RUBY$method$create_table_generator$0'
    from CompiledIRMethod.java:116:in `call'
    from MixedModeIRMethod.java:148:in `call'
    from CachingCallSite.java:303:in `cacheAndCall'
    from CachingCallSite.java:141:in `callBlock'
    from CachingCallSite.java:145:in `call'
    from L:/sequel/lib/sequel/database/schema_methods.rb:-1:in `invokeOther10:create_table_generator'
    from L:/sequel/lib/sequel/database/schema_methods.rb:194:in `RUBY$method$create_table$0'
    from CompiledIRMethod.java:101:in `call'
    from CompiledIRMethod.java:129:in `call'
    from MixedModeIRMethod.java:183:in `call'
    from CachingCallSite.java:323:in `cacheAndCall'
    from CachingCallSite.java:173:in `callBlock'
    from CachingCallSite.java:177:in `call'
    from InterpreterEngine.java:301:in `processCall'
    from StartupInterpreterEngine.java:78:in `interpret'
    from Interpreter.java:137:in `INTERPRET_BLOCK'
    from InterpretedIRBlockBody.java:116:in `commonYieldPath'
    from IRBlockBody.java:146:in `doYield'
    from BlockBody.java:83:in `yield'
    from Block.java:161:in `yieldArray'
    from RubyBasicObject.java:1701:in `yieldUnder'
    from RubyBasicObject.java:1675:in `instance_exec19'
    from RubyBasicObject$INVOKER$i$0$3$instance_exec19.gen:-1:in `call'
    from CachingCallSite.java:273:in `cacheAndCall'
    from CachingCallSite.java:79:in `callBlock'
    from CachingCallSite.java:83:in `call'
    from CallBase.java:419:in `interpret'
    from InterpreterEngine.java:324:in `processCall'
    from StartupInterpreterEngine.java:78:in `interpret'
    from Interpreter.java:137:in `INTERPRET_BLOCK'
    from InterpretedIRBlockBody.java:116:in `commonYieldPath'
    from IRBlockBody.java:58:in `call'
    from Block.java:106:in `call'
    from RubyProc.java:317:in `call'
    from ProcMethod.java:63:in `call'
    from DynamicMethod.java:201:in `call'
    from DynamicMethod.java:197:in `call'
    from CachingCallSite.java:293:in `cacheAndCall'
    from CachingCallSite.java:131:in `call'
    from InterpreterEngine.java:308:in `processCall'
    from StartupInterpreterEngine.java:78:in `interpret'
    from Interpreter.java:137:in `INTERPRET_BLOCK'
    from InterpretedIRBlockBody.java:116:in `commonYieldPath'
    from IRBlockBody.java:66:in `yieldSpecific'
    from Block.java:116:in `yieldSpecific'
    from IRRuntimeHelpers.java:456:in `yieldSpecific'
    from YieldInstr.java:72:in `interpret'
    from StartupInterpreterEngine.java:184:in `processOtherOp'
    from StartupInterpreterEngine.java:108:in `interpret'
    from MixedModeIRMethod.java:129:in `INTERPRET_METHOD'
    from MixedModeIRMethod.java:115:in `call'
    from CachingCallSite.java:273:in `cacheAndCall'
    from CachingCallSite.java:79:in `callBlock'
    from CachingCallSite.java:83:in `call'
    from CallBase.java:419:in `interpret'
    from InterpreterEngine.java:324:in `processCall'
    from StartupInterpreterEngine.java:78:in `interpret'
    from MixedModeIRMethod.java:129:in `INTERPRET_METHOD'
    from MixedModeIRMethod.java:115:in `call'
    from CachingCallSite.java:273:in `cacheAndCall'
    from CachingCallSite.java:79:in `callBlock'
    from CachingCallSite.java:83:in `call'
    from CallBase.java:419:in `interpret'
    from InterpreterEngine.java:324:in `processCall'
    from StartupInterpreterEngine.java:78:in `interpret'
    from Interpreter.java:137:in `INTERPRET_BLOCK'
    from InterpretedIRBlockBody.java:116:in `commonYieldPath'
    from IRBlockBody.java:139:in `doYield'
    from BlockBody.java:77:in `yield'
    from Block.java:147:in `yield'
    from RubyArray.java:2296:in `collect'
    from RubyArray.java:2309:in `map19'
    from RubyArray$INVOKER$i$0$0$map19.gen:-1:in `call'
    from JavaMethod.java:473:in `call'
    from CachingCallSite.java:273:in `cacheAndCall'
    from CachingCallSite.java:79:in `callBlock'
    from CachingCallSite.java:83:in `call'
    from CallBase.java:419:in `interpret'
    from InterpreterEngine.java:324:in `processCall'
    from StartupInterpreterEngine.java:78:in `interpret'
    from MixedModeIRMethod.java:129:in `INTERPRET_METHOD'
    from MixedModeIRMethod.java:115:in `call'
    from CachingCallSite.java:273:in `cacheAndCall'
    from CachingCallSite.java:79:in `callBlock'
    from CachingCallSite.java:83:in `call'
    from CallBase.java:419:in `interpret'
    from InterpreterEngine.java:324:in `processCall'
    from StartupInterpreterEngine.java:78:in `interpret'
    from InterpreterEngine.java:84:in `interpret'
    from MixedModeIRMethod.java:199:in `INTERPRET_METHOD'
    from MixedModeIRMethod.java:185:in `call'
    from DynamicMethod.java:205:in `call'
    from CachingCallSite.java:313:in `cacheAndCall'
    from CachingCallSite.java:163:in `call'
    from InterpreterEngine.java:292:in `processCall'
    from StartupInterpreterEngine.java:78:in `interpret'
    from Interpreter.java:137:in `INTERPRET_BLOCK'
    from InterpretedIRBlockBody.java:116:in `commonYieldPath'
    from IRBlockBody.java:58:in `call'
    from Block.java:106:in `call'
    from RubyProc.java:317:in `call'
    from RubyProc.java:232:in `call'
    from Ruby.java:3264:in `tearDown'
    from Ruby.java:3237:in `tearDown'
    from Main.java:300:in `internalRun'
    from Main.java:225:in `run'
    from Main.java:197:in `main'
rake aborted!
Command failed with status (1): [C:/jruby-9.0.0.0.rc1/bin/jruby.exe -e "ARG...]
org/jruby/RubyProc.java:301:in `call'
L:/sequel/rakefile:92:in `block in (root)'
org/jruby/RubyProc.java:301:in `call'
L:/sequel/rakefile:99:in `block in (root)'
org/jruby/RubyProc.java:301:in `call'
org/jruby/RubyArray.java:1571:in `each'
org/jruby/RubyArray.java:1571:in `each'
org/jruby/RubyKernel.java:958:in `load'
Tasks: TOP => spec_postgres
(See full trace by running task with --trace)

This seems to be related to instance evaled blocks and super usage in the constraint_validations plugin, but I was unable to reduce it to a smaller example. The specs pass correctly on pre1, similar failure on pre2.

@enebo enebo added the JRuby 9000 label Jun 16, 2015

@enebo enebo added this to the JRuby 9.0.0.0.rc2 milestone Jun 16, 2015

@enebo enebo added the ir label Jun 16, 2015

@enebo

This comment has been minimized.

Show comment
Hide comment
@enebo

enebo Jun 16, 2015

Member

I think between pre1 and pre2 we added logic to reify blocks into procs only if they end up being used. So this is likely still fallout from that.

Member

enebo commented Jun 16, 2015

I think between pre1 and pre2 we added logic to reify blocks into procs only if they end up being used. So this is likely still fallout from that.

@enebo enebo added jit and removed jit labels Jun 29, 2015

@enebo

This comment has been minimized.

Show comment
Hide comment
@enebo

enebo Jun 29, 2015

Member

HEH. I had marked this a JIT bug but in fact it is an IR bug and our block reification logic. I do not have this localized yet but the general way to reproduce without JIT is:

JRUBY_OPTS="-Xir.passes=OptimizeDelegationPass,DeadCodeElimination,AddLocalVarLoadStoreInstructions,OptimizeDynScopesPass,AddCallProtocolInstructions,EnsureTempsAssigned -X-C -Xjit.threshold=0 -Xjit.background=false" SEQUEL_SQLITE_URL=jdbc:sqlite::memory jrake spec_sqlite

The code in question croaking is:

    def create_table_generator(&block)
      super do
        extend CreateTableGeneratorMethods
        @validations = []
        instance_eval(&block) if block
      end
    end
Member

enebo commented Jun 29, 2015

HEH. I had marked this a JIT bug but in fact it is an IR bug and our block reification logic. I do not have this localized yet but the general way to reproduce without JIT is:

JRUBY_OPTS="-Xir.passes=OptimizeDelegationPass,DeadCodeElimination,AddLocalVarLoadStoreInstructions,OptimizeDynScopesPass,AddCallProtocolInstructions,EnsureTempsAssigned -X-C -Xjit.threshold=0 -Xjit.background=false" SEQUEL_SQLITE_URL=jdbc:sqlite::memory jrake spec_sqlite

The code in question croaking is:

    def create_table_generator(&block)
      super do
        extend CreateTableGeneratorMethods
        @validations = []
        instance_eval(&block) if block
      end
    end
@enebo

This comment has been minimized.

Show comment
Hide comment
@enebo

enebo Jun 29, 2015

Member

Reduced:

module Base
  def foo
    yield
  end
end

module Doo
  include Base

  def foo(&block)
    super do
      instance_eval(&block) if block
    end
  end
end

class Mine
  include Doo
end

Mine.new.foo { puts "AAAA" }

Run with:

JRUBY_OPTS="-Xir.passes=OptimizeDelegationPass,DeadCodeElimination,AddLocalVarLoadStoreInstructions,OptimizeDynScopesPass,AddCallProtocolInstructions,EnsureTempsAssigned -X-C -Xjit.threshold=0 -Xjit.background=false" jruby ../../snippets/super_block1.rb 
StoreLocalVarInstr.java:83:in `interpret': java.lang.ClassCastException: org.jruby.runtime.Block cannot be cast to org.jruby.runtime.builtin.IRubyObject
    from InterpreterEngine.java:511:in `processOtherOp'
Member

enebo commented Jun 29, 2015

Reduced:

module Base
  def foo
    yield
  end
end

module Doo
  include Base

  def foo(&block)
    super do
      instance_eval(&block) if block
    end
  end
end

class Mine
  include Doo
end

Mine.new.foo { puts "AAAA" }

Run with:

JRUBY_OPTS="-Xir.passes=OptimizeDelegationPass,DeadCodeElimination,AddLocalVarLoadStoreInstructions,OptimizeDynScopesPass,AddCallProtocolInstructions,EnsureTempsAssigned -X-C -Xjit.threshold=0 -Xjit.background=false" jruby ../../snippets/super_block1.rb 
StoreLocalVarInstr.java:83:in `interpret': java.lang.ClassCastException: org.jruby.runtime.Block cannot be cast to org.jruby.runtime.builtin.IRubyObject
    from InterpreterEngine.java:511:in `processOtherOp'
@enebo

This comment has been minimized.

Show comment
Hide comment
@enebo

enebo Jun 29, 2015

Member

Ok done for tonight but I will jot down what I think is wrong here. OptimizeDelegationPass is not examining the usage of block variables at all in children scopes. This is a little more involved than uncommenting out @subbuss FIXME processing of the children scopes, but we need to consider any ordinary usage of blocks in children scopes.

Member

enebo commented Jun 29, 2015

Ok done for tonight but I will jot down what I think is wrong here. OptimizeDelegationPass is not examining the usage of block variables at all in children scopes. This is a little more involved than uncommenting out @subbuss FIXME processing of the children scopes, but we need to consider any ordinary usage of blocks in children scopes.

@enebo enebo closed this in 467e2f7 Jun 30, 2015

enebo added a commit that referenced this issue Jun 30, 2015

Revert "Fixes #3056. java.lang.IncompatibleClassChangeError in 9.0.0.…
…0 rc1"

This fixed the issue but @subbuss rightly points out this scope should have
been marked as BINDING_HAS_ESCAPED and thus this pass should not have even
ran.

This reverts commit 467e2f7.

enebo added a commit that referenced this issue Jun 30, 2015

Fixes #3056. java.lang.IncompatibleClassChangeError in 9.0.0.0 rc1.
This replaces the previous fix.  The previous fix was wrong because the
code in question contained a closure and we were not marking the parent
method as scope as BINDING_HAS_ESCAPED.  As a result, OptimizeDelegationPass
was executing and mucking things up.  The previous fix corrected the pass
to work with nested closures but it would create new problems if that closure
did something which needed to conume the parents binding.

The new fix is just a simple oversight in a few of our instructions.  ZSuper,
UnresolvesSuper, and Match are calls but they were not calling their
superclasses computeScopeFlags.  This is turn made the issue at hand not notice
that the method contained a closure so it never marked BINDING_HAS_ESCAPED.

This fix should potentially fix other weird errors where we did not set common
call IRScope flags.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment