joast has quit [Ping timeout: 260 seconds]
joast has joined #jruby
<headius> good morning!
* mattpatt[m] waves]
<headius> let's try to wrap up that last issue today
<basshelal[m]> headius: I got some free time today, I want to work on
<basshelal[m]> Let me know about what other hacks you want to merge into JNR-FFI from the other JNR repos, I'll work on the FreeBSD version thing now, hopefully I can get a FreeBSD image running to test on
<headius> basshelal: cool! The two I know of are enxio and posix, but unixsocket might have something too to detect linux vs bsd
<headius> everyone that uses jnr-ffi comes up with their own platform detection garbage so we really need to centralize it
<basshelal[m]> headius: lol 😂 that's why I added the endianness thing a while back
<basshelal[m]> headius: Well link em to me in that issue and I'll see if I can something done for them, will probably do them in separate PRs just in case
<headius> ok will link what I know of
<headius> basshelal: FWIW I think it's incredibly stupid that updating to junit5 with existing junit4 tests just silently ignores those tests, so I don't blame you for the recent hassle
<headius> not sure who thought that was a good idea but they were wrong
<basshelal[m]> headius: Yeah I agree, should be a simple update with the ability to update gradually, sorry for causing a hassle
<headius> basshelal: updated
<headius> ok bit of overhead this morning but I am digging into the JI issue a bit byteit101 enebo
<enebo[m]> headius: yeah I have looked a little bit at this
<enebo[m]> instanceSuper will just keep going down to Ruby Object but there is a reifiedClass in that class
<headius> I'm just starting to look so any tips would be great
<enebo[m]> so I am a bit confused on what is the right thing here ... should original module/class have java.lang.Object in it as a proxy or should we go...oh its reified lets search with that class
<enebo[m]> I was specifically looking at byteit101 case with Parent < java.lang.Object
<enebo[m]> derp...well I am silly I just fired up debugger again and superClass is Java::JavaLang::Object
<headius> so it is pointing at the right place
<headius> byteit101 said something about the method we get back from the search pointing at the wrong self class
<headius> so it ends up supering back into the one we were just in
<headius> so perhaps something wrong with the framing?
<enebo[m]> I can see it is searching on Java Proxy Object for a super which would be toString
<headius> aha
<enebo[m]> so it finds a method on java.lang.Object for toString and enters call on that method and that is what is looping
<headius> calling toString on Parent is fine
<headius> it only fails calling it from Child
<enebo[m]> At the point in debugger I am at I am seeing Parent as definingModule so Child has class Parents version and the super in parent version is looking for java.lang.Object version and looping
<headius> so it is getting the current self class from the target of the call and not from the source of the method, or something
<enebo[m]> hmm this is interesting
<enebo[m]> I did not go this far before
<enebo[m]> upwrapIfJavaProxy(self) in InstanceMethodInvoker
<enebo[m]> IDE debugger craps itself on generated classes
<headius> yeah I don't know what we're doing wrong on some of those
<headius> JIT code is fine in debugger other than having no source associated
<enebo[m]> ok so you a) found only dispatch down through child does it fail and I found b) once it is down to super from parent it must resolve back to parent for the invokeDirect
<headius> yeah
<enebo[m]> I cannot actually see that as values in b because the stuff is red in IDE
<headius> so it gets a method that pushes the child class as frame class and then it just keeps doing that
<headius> because it searches from child again
<enebo[m]> ok JavaMethod enters mightBeProxy in invokeDirect and does a tryProxyInvocation
<enebo[m]> Seems like it maybe should have did a invokeDirectSuperWithExceptionHandling but it passes that and does invokeDirectWithExceptionHandling
<headius> fixed my example above... I guess does not work right
<enebo[m]> but I don't really follow this code too well
<headius> not sure if it ever did though
<headius> -Xcompile.dump does dump out the generated bits of byteit101 generated code
<enebo[m]> well I can see it bump back to a regular invoke on Parent toString
<enebo[m]> but of course we knew that already
<enebo[m]> headius: look at JavaMethod#tryProxyInvocation at 602
<headius> I think this is missing framing needed for super
<headius> GETFIELD rubyobj/Parent.this$rubyObject : Lorg/jruby/java/proxies/ConcreteJavaProxy;
<headius> INVOKEVIRTUAL org/jruby/java/proxies/ConcreteJavaProxy.callMethod (Ljava/lang/String;[Lorg/jruby/runtime/builtin/IRubyObject;)Lorg/jruby/runtime/builtin/IRubyObject;
<headius> GETSTATIC org/jruby/runtime/builtin/IRubyObject.NULL_ARRAY : [Lorg/jruby/runtime/builtin/IRubyObject;
<headius> LDC "toString"
<headius> it passes in the self object and the method name for the call but no frame class, because it does no framing
<enebo[m]> err 592
<headius> so it always will do the lookup from the self object's class
<headius> I suppose I should have noticed this in the original PR
<enebo[m]> It is not finding toString on proxyclass and then just moving on
<basshelal[m]> headius: I've added `String getVersion()` `int getVersionMajor()` methods to `Platform`, should I do a `int getVersionMinor()` as well?
<headius> that bytecode above is what's within the Parent.toString generated code
<enebo[m]> So could it be that it is looking at Child proxyclass and not finding the toString of Parent?
<headius> basshelal: probably? I mean, Solaris/SunOS had some weird-ass versioning for a while so I suspect we will want it
<enebo[m]> oh so it is doing this right but it is not loading the right thing from a missing frame
<headius> that'
<headius> that's my current theory
<headius> without frame it can't know where to super from so it is just searching from the bottom again
<headius> wait
<headius> I am not quite right
<headius> this code is what lives on the Java side of this thing
<headius> so this is ok
<enebo[m]> ok so in where I am at I can see that the jpc for the invoke in JavaMethod is Child and not Parent
<headius> I need to see the code running in the Ruby side that has the super
<enebo[m]> so it fails to see there is a super to invoke
<enebo[m]> headius: do you we still put all Java methods on all proxies or do we only put them on each proxy class where they are defined?
<headius> that is it
<headius> but still no frame
<headius> it is generating IR that does not trigger a frame so the super has to search based on scope and gets it wrong
<headius> hmm
<headius> interestingly a normal "class Foo; def foo; super; end; end" also looks like this in IR
<headius> perhaps mod<0> is the wrong static scope module?
<enebo[m]> headius: do you we still put all Java methods on all proxies or do we only put them on each proxy class where they are defined?
<headius> if you mean in general I think we still do all on all, but we bind the parent's version if there is an override in the child
<enebo[m]> So in Child there is no toString and when we ask the proxy it says nope so we don't so super invoke in JavaMethod
<enebo[m]> I am not saying it is static scope or frame but the call has self of child. has clazz of java.lang.Object and figured out Object location from Parent
<enebo[m]> but when we ask child .get("toString", param_types) it returns null
<headius> instance super does assume that the cref class is the one to super from
<headius> so that is likely where this is getting messed up... it is getting the wrong static scope passed into the toString call?
<enebo[m]> so what should jpc be in tryProxyInvocation?
<enebo[m]> should it be parent or child
<headius> tryProxyInvocation happening where?
<enebo[m]> The failing code snippet
<enebo[m]> if ((jpm = jpc.getMethod(method.getName(), parameterTypes)) != null && jpm.hasSuperImplementation()) {... (full message at
<enebo[m]> jpc when I run it is Child as it comes from javaInvokee which seems right to me but when we look to see if it has a super method to toString it returns null because it is not defined on Child
<enebo[m]> but if we are supposed to put all method defines down and Child has no toString then maybe we should have added Parents as an entry and I have no idea
<headius> what is javaInvokee in that case?
<enebo[m]> Child
<enebo[m]> If it was Parent it would work but javaInvokee seems to be self from the call
<headius> I think jpc should be the current class, not the current self class
<headius> which is what it is getting wrong from further up the call stack
<headius> if it is getting class from the static scope and it ends up being Child, then it has the wrong scope or that scope is resolved to the wrong cref module
<enebo[m]> instanceSuper in IRTuntimeHelpers which is where it would all start to go wrong is maybe a place to state what is there
<headius> I think this is entirely a problem with the super splitting logic in the new proxy stuff
<headius> isn't that what is happening here? Or was that only for initialize?
<enebo[m]> definingModule is Parent
<headius> when called against child?
<enebo[m]> The example byteit101 has no super in it at all
<enebo[m]> err no initialize
<enebo[m]> it has a super
<headius> right ok you are more on the track then I think
<headius> so super goes into proxy super logic but it does not have the original class in hand and has to infer it from self
<headius> I need to get into the debugger
<enebo[m]> This is similar to monkstone's case with setSize (or whatever it is) but it lacks the complexity that there are overrides (Although I doubt that matters)
<enebo[m]> yeah so I see it find what I would think is all the right stuff at this point but when it goes to invoke it then asks Child whether it has a super version of toString and it says nope because Parent has it
<enebo[m]> that was why I asked the question about definitions
<enebo[m]> Maybe our reified classes don't do what JI proxies do and we are just not putting that info onto Child
<enebo[m]> I should add when it doesn't find it just assumes it can invoke toString on the child which then takes it back to the parent toString which then repeats until we are out of stack
<enebo[m]> My confusion is mostly not knowing how this is supposed to work in the first place
<headius> the super search does look ok so my earlier theory was wrong
<headius> I am stepping in
<headius> aha
<headius> I'm caught up with you now
<headius> so it just skips the super version of the call
<headius> because it doesn'
<enebo[m]> It doesn't think there is one
<headius> it doesn't see that the current self is the original proxy
<headius> or rather I think it sees that we are calling against Child and Child does not override this so it does a normal invocation
<headius> right
<enebo[m]> I think because the invoker is Child it gets jpc from that and not where we found the method
<headius> right
<headius> that is it
<enebo[m]> but should it be peeling out Parent somehow?
<enebo[m]> That is where I don't see how this all works
<enebo[m]> If we added all parent methods onto child this would just work I think
<headius> well this is problematic because we are far from where we had a reference to Parent now
<headius> so it has to infer it from the invokee and that is wrong
<enebo[m]> yeah
<headius> tryProxyInvocation should probably be getting the method's defining class to use as the current class for super lookups
<headius> I think InstanceMethodInvoker should be passing clazz through
<enebo[m]> well that also makes sense but we do not pass it into call
<headius> we do
<enebo[m]> although we do pass java.lang.Object
<headius> but we leave it behing
<headius> behind
<headius> it looks up the java.lang.Object toString just fine
<headius> passes java.lang.Object proxy in
<enebo[m]> oh yeah right it does
<headius> and then ignores it and proceeds on to the inferred super logic
<enebo[m]> unwrapIfJavaProxy target gets swapped in
<headius> so the fact is that this turns out to be a proxy so instead of calling the java.lang.Object version it redispatches against invokee
<enebo[m]> but yeah we drop clazz at that point
<headius> the method from findCallable seems correct too
<enebo[m]> yeah
<headius> public java.lang.String java.lang.Object.toString()
<enebo[m]> amusingly if invokeDirect did not see that javaInvokee was a proxy it would work
<headius> yeah it would
<headius> so possibilities here
<enebo[m]> so we still need javaInvokee as a sort of self but we also need to pass in where toString is defined
<headius> yeah h,mm
<headius> so there's two possible places that could be fixed
<headius> maybeProxy seems like the wrong place... Child is a proxy, it just doesn't override this method
<headius> so that seems to leave the test in tryInvocationDirect
<enebo[m]> yeah it definitely seems like it is being used for two purposes and in this case one is wrong
<enebo[m]> so we need intent before that which does not call that (or conversely we move that further down somewhere)
<byteit101[m]> > -Xcompile.dump does dump out the generated bits of byteit101 generated code
<byteit101[m]> Oh, that would have been useful to know a year ago, I had just edited the code to dump to a folder :-)
<headius> byteit101: oh sorry! one of those hidden gems I seem to be the only one that uses
<byteit101[m]> >but I don't really follow this code too well
<byteit101[m]> Let me know if you need some help, and I'll also note it down in a wiki page or something too
<headius> enebo: might be helpful to step through the 9.2 version of this
<byteit101[m]> >it passes in the self object and the method name for the call but no frame class, because it does no framing
<byteit101[m]> Interesting possiblity
<headius> for whatever reason that one works and this one re-supers at the wrong place
<headius> byteit101: I think that was a red herring... will let you catch up though
<byteit101[m]> >I suppose I should have noticed this in the original PR
<byteit101[m]> I was honestly surprised you merged it as is given the number of questions about stuff like this I had
<byteit101[m]> >do you we still put all Java methods on all proxies or do we only put them on each proxy class where they are defined?
<byteit101[m]> configurable now
<byteit101[m]> >My confusion is mostly not knowing how this is supposed to work in the first place
<byteit101[m]> Let me know here I can help explain things
<headius> enebo: it occurs to me though, this logic was never built with supering from a proxy in mind so this is just a gap in the "new" JI logic as opposed to the JavaProxyClass monster that Kresten build
<headius> byteit101: you did a great job building this logic on top of the "new" JI, I think this just needs some extension to know how to do super properly
<enebo[m]> yeah makes sense based on walking through the stack through call
<byteit101[m]> I know the super work that exists was tricky with bridge methods and all, but that was a definite weak point, as can be plainly seen
<enebo[m]> quick lunch break
<headius> this is purely in how it invokes the target method it finds from super in a proxy subclass
<headius> it invokes it through logic that was primarily designed for direct normal invocation of a Java object and that logic does not know how to handle super class vs self class right
<headius> it wasn't really your mistake, this logic just should have been passing the calling method's class through to this super logic
<headius> not just the invokee
<headius> we should be invoking super as though we are in Parent, not as though we are in Child
<headius> I'm not sure he meant normal Java objects or proxied subclasses but that is good to know too
<byteit101[m]> enebo: but you can configure just explicitly-defined methods instead:
<headius> so tryProxyInvocation fails because jpc ends up looking for the Java method on the self proxy (Child) and does not find it, so it invokes normally
<headius> it should be looking for the Java method on the defining module (Parent)
<headius> since that is where we are
<headius> so I think if we can pass the Parent class through it will work
<byteit101[m]> OH! that signature style I kept seeing in makes sense now. I saw the two "self" params, and in all my testing they were usually nearly similar, and never figured it out. That makes sense though
<byteit101[m]> > it wasn't really your mistake, this logic just should have been passing the calling method's **class** through to this super logic
<headius> right you got it
<headius> the clazz passed in is intended to be used for things like super
<headius> see also which passes clazz always
<headius> byteit101: if I have the Parent RubyModule in hand, will the reified class be the proxy I need for "jpc" in tryInvocationDirect?
<headius> I'm trying to figure out how to adapt this for your new reified logic
<headius> without breaking the rest of JI
<headius> or more specifically how do I get to the JavaProxyClass for a RubyClass subclass of a Java object
<headius> this uses ReifiedJavaProxy.___jruby$proxyClass()
<headius> but I won't have an instance because the instance is Child
<byteit101[m]> Oh, hmm
<byteit101[m]> I should open up the code :-D
<headius> yeah I am grabbing some lunch, have a look and I'll bbiab
meckispaghetti[m has joined #jruby
<byteit101[m]> well, I think getParent.getReifiedJavaClass.__jruby$proxyClass, would work, but there is probably a more direct way to get that
<headius> that isn't bad, I can try that
<byteit101[m]> (I don't remember if that method is static)
<byteit101[m]> not static: m = new SkinnyMethodAdapter(cw, ACC_SYNTHETIC | ACC_PUBLIC,
<headius> hmm
<headius> ok that maybe should be made static... I don't think I can get it from the class itself
<byteit101[m]> [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project jruby-base: Compilation failure
<byteit101[m]> [ERROR] An exception has occurred in the compiler (1.8.0_201). Please file a bug against the Java compiler via the Java bug reporting page ( after checking the Bug Database ( for duplicates. Include your program and the following diagnostic in your report. Thank you.
<byteit101[m]> [ERROR] at
<byteit101[m]> [ERROR] java.lang.AssertionError: unknown annotation tag ''
<byteit101[m]> Oh hmm
<headius> I only have the class
<headius> unsure though
<byteit101[m]> Once I can compile jruby again, I'll open the debugger
<headius> I could probably get the self object's java class and search for the defining module's java class in its hierarchy but that is super indirect
<byteit101[m]> to clarify: you have the parent self IRubyObject, and want the JavaProxyClass?
<headius> I have the parent RubyClass
<headius> self is an instance of Child (Child < Parent < j.l.Object) and I have the Parent class in hand and need its JavaProxyClass
<byteit101[m]> Ok, unrelated running things issues: Caused by: java.lang.ClassNotFoundException: com.headius.options.Option
<headius> ok something is weird in your end
<byteit101[m]> I last used this workspace several months ago
<byteit101[m]> "The type java.lang.Class cannot be resolved. It is indirectly referenced from required .class file"
<byteit101[m]> How???
<headius> what's the java -version output?
<byteit101[m]> Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
<byteit101[m]> Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)
<byteit101[m]> java version "1.8.0_201"
<headius> something is really weird
<headius> gist the full build output, maybe I will see something
<headius> and double check you are on latest master
<byteit101[m]> The mvn build works now, but not eclipse
<headius> hmm ok
meckispaghetti[m has left #jruby [#jruby]
<headius> .classpath messed up maybe?
<byteit101[m]> I don't know, but to answer your question:
<byteit101[m]> singleton.setInstanceVariable("@java_proxy_class", proxyClass);
<headius> singleton is the class object?
<byteit101[m]> See JPC.setProxyClassReified
<byteit101[m]> both on clazz and singleton
<headius> got it, so I should be able to retrieve from there then
<byteit101[m]> helper method JPC.getProxyClass
<byteit101[m]> Hmm, should I make ___jruby$proxyClass static? the variable is static...
<headius> cool
<headius> well you have it as an instance method so we can cast the interface
<headius> I wish static methods could have an interface
<byteit101[m]> Yes, I think that's why I did it that way. I could do both an interface and static method, given how trivial it is
<headius> it's fine for now if I can get it from the ivar
<headius> static method we'd have to invoke through a method handle or reflection method anyway
<byteit101[m]> The ivar always confused me (was like that before I made my changes)
<headius> yeah
<headius> hmm does not seem to be getting me the JPC
<headius> I will step into it and poke around the RubyClass's guts
<headius> oh hmm
<headius> the module in hand is already the java.lang.Object proxy
<headius> I wonder if this super logic is even needed anymore
<headius> we do the super logic from Ruby correctly now
<headius> it is not the right logic in any case because I am already calling Object.toString at this point, regardless of whether the original object was a proxy or not
<basshelal[m]> Is IBM i Unix or Unix-like?
<basshelal[m]> AIX is definitely Unix-like
<headius> hmm I assumed unix-like but I guess I don't know
<headius> it can't be too weird if people are using the JNR stack there
<basshelal[m]> Will need to update `Platform.isUnix()` if not
<basshelal[m]> Not a huge deal, just curious
<byteit101[m]> basshelal: A friend who works with IBM i says Unix-like
<basshelal[m]> Cheers! byteit101
<basshelal[m]> Less work 😁
<headius> byteit101 this is not really your bug
<headius> It occurred to me now that there is no way to invoke the super method using reflection
<headius> There's not really any bug in this code, it just can't use reflection to make this call. I believe the old logic generated shim methods to dispatch super from within the generated class
<headius> There are a few ways to fix this but none of them are simple and we may punt to a update release
<byteit101[m]> I generate shim methods
<headius> For what exactly?
<byteit101[m]> RubyClass ConCreteJavaReifier.generateSuperBridges
<headius> In this case the method in hand is the one from object and not the shim
<headius> So we get the normal reflection toString and try to dispatch with that
<byteit101[m]> That's what that generates, I think
<headius> So since you are generating shims perhaps what we need to be doing is looking up the shim instead
<headius> When we know we need to call against a super class
<byteit101[m]> I tied those in with a register call
<headius> okay I am remembering that now
<headius> Because this uses the normal Ruby super logic it finds the normal method from the j.l.Object proxy
<headius> Then it proceeds to dispatch with regular reflection and just loops back on itself
<headius> Right so that happens in the getSuperMethod
<headius> So I think I may be coming back to us just needing to fix the test in this try method
<headius> We need to know we are calling the super class method but in a different way than this test does
<byteit101[m]> JavaProxyClass.initMethod() is called for each super overload
<byteit101[m]> ~line 2000 of RubyClass
<headius> Okay, I have to run an errand but maybe this won't be too bad. I need to step through the working case again
<byteit101[m]> gets the method in line 396 of
<headius> It just needs to recognize that we are calling a super class in Java and it simply doesn't see that right now
<byteit101[m]> I had hoped that call would be enough, but clearly not :-)
<byteit101[m]> though without that call it doesn't support super at all
<headius> Yeah the problem is that the child doesn't override the method so when we go looking for the super method we find nothing at all
<headius> If we started from the parent like we should, it would just work
<headius> That's why I was trying to get the proper JPC
<headius> BRB
<byteit101[m]> (from generated Parent.class)
<byteit101[m]> Child.class has no toString nor __super$toString, just:... (full message at
<headius> right so the trick here is somehow carrying the Parent class through to the dispatch so we can use its JPC
<headius> that is a conundrum 🤔
<headius> but it is curious that it works in the simple case so I am stepping through now
<headius> ah right... it works because Parent is the self class
<headius> yeah so I think we need to add some logic to super to detect that we are dealing with proxies
<headius> enebo: and this doesn't improve if you override toString in the Child class because it still always restarts the search from the bottom
<headius> the minute we are one level above the self class it loses track of where it is
<byteit101[m]> the super bridge methods were added to allow ruby calling super of the java parent, not of caling super of the ruby parent
<enebo[m]> I was thinking about that too
<headius> byteit101: right
<headius> the ruby super can just go through Ruby but it still ends up back in the Parent method looking up against Child
<headius> or rather, dispatching normally rather than through the shim methods
<byteit101[m]> yes
<headius> if you add toString to Child it ends up in Parent, sees that Child is a proxy, retrieves the JPC from Child, gets Child.toString.super, and then we are stuck again
<byteit101[m]> it was my hope that that would be the case
<headius> so it overflows in a slightly different way but the same cause
<headius> the super lookup logic way back in IR needs to know about JI for this to work, I think
<byteit101[m]> *dispatching normally via ruby vs the shim/proxy methods, that is
<headius> so it can keep the original defining class in hand
<headius> otherwise it finds java.lang.Object and then goes from there to dispatching against Child again
<enebo[m]> well perhaps instancesuper needs to do something different when it sees this
<headius> I think so
<headius> I think we need to rewrite supers in java proxy classes
<headius> (rather than checking for a proxy every call)
<enebo[m]> we can see self.clazz != definedModule
<headius> it doesn't have to be a split but it should be a different call
<headius> JavaProxySuperInstr or something
<headius> that will know how to get the correct super shim if needed
<enebo[m]> I think we can detect this by just looking can't we?
<headius> well yeah but you want to do this check for every super everywhere?
<enebo[m]> maybe
<enebo[m]> I guess it depends on the check
<enebo[m]> I have wondered about making instrs which do Java calls
<headius> the check would be like the code in tryProxyInvocation
<enebo[m]> like you know it is unconditionally an array
<headius> if it is a proxy and it defines this method and there's a super method then use that instead
<enebo[m]> so you can just call op_set on RubyArray
<headius> sure
<enebo[m]> so I just threw that out there
<headius> could be that an instanceof check against self wouldn't add too much but I wouldn't want to leave it that way long term
<enebo[m]> but near term a simpler approach would be to leave istance_super as an instr and then make a boolean on the instr
<headius> instanceof ReifiedJavaProxy or whatever
<headius> also an option, sure
<enebo[m]> for JIT it would have no perf impact and for interp it would just be a boolean comparison
<headius> that is equivalent to rewriting in my mind
<headius> except for checking the boolean every time in interp
<enebo[m]> I don't love that per se but it is a lot less work and I am wondering what other issues we will hit once we release
<headius> we can do it without revisiting the IR by using something like an instanceof check
<enebo[m]> IR is pure internals for us so I don't fear changing them later once we learn more
<enebo[m]> All I can say is the boolean check will not be noticeable in the interp :)
<enebo[m]> but my suggestion is more based on pragmatism of doing a bunch of work and then realizing next week we need to a bunch of other work
<headius> right
<headius> I can get behind that for 9.3 if we look at a better fix in 9.3.1
<enebo[m]> yeah so how do we know we are in a JI thing to do this?
<enebo[m]> When we run addMethod we look at what it is and mutate instanceSuper to have the boolean toggled?
<headius> prototyping a fix quick
<enebo[m]> For super on split it is obviously only for JI but for this particular test case we don't know until we add
<headius> well the same way we detect that we need to split initialize, no?
<enebo[m]> we only check that in initialize
<enebo[m]> Or wait maybe we don't
<enebo[m]> haha let me check.
<enebo[m]> yeah we only split on constructors/initialize
<enebo[m]> byteit101: I sort of wish we had some nice way of flagging methods called by concreteJavaProxy by proxies so they do not look like dead code in the IDE (e.g. finishInitialize)
<enebo[m]> we do have a comment so that is probably as good as it gets without doing something weird
<enebo[m]> I don't even think the idea of toggling instance_super works. We have to know if we are on top of a class which is on top of a reified class
<byteit101[m]> enebo: yes, that's why I made sure I put comments above all of them * Do not refactor without looking at RCG
<enebo[m]> Parent < java.lang.Object and is an ordinary ruby method but what happens if Parent < GrandParent < java.lang.Object where GrandParent has no toString?
<byteit101[m]> //called from reified java concrete-extended classes with super-overrides
<byteit101[m]> JPC has several
<enebo[m]> byteit101: yeah I did manage to notice them but whenever I see gray text then I decide to figure out if it is dead
<enebo[m]> byteit101: So I am not really asking for anything since I think all we could do is make some bogus shim class call them which is never instantiated or something which would be silly
<byteit101[m]> Annotations maybe?
<enebo[m]> byteit101: yeah I try that historicall and come up short but perhaps we could put @JIT anno on them
<enebo[m]> I made @Interp and @JIT so we could tell what helpers are used by what but @JIT really means something from bytecode
<byteit101[m]> @calledFromReifiedCode
<enebo[m]> It is purely as a doc marker though so perhaps that is ok
<enebo[m]> if I see @JIT I know I can grep through source and see something invoking it
<enebo[m]> via ASM or whatever
<byteit101[m]> @calledFromReifiedCode(ClassThatGeneratesSaidCode.class)
<enebo[m]> I think I will just add @JIT since I am probably the only person who actually cares
<enebo[m]> but annotation was agood suggestion since it made me remember this
<byteit101[m]> bin/ruby -e 'class Parent < java.lang.Object;end;class Child < Parent;def toString;"child " + super;end;end;Child.become_java!("/tmp/abc");p'
<byteit101[m]> "child rubyobj.Child@2aceadd4"
<byteit101[m]> enebo: ^
<byteit101[m]> (ignore the b_j!, I was looking at the class files)
<enebo[m]> does that not work also
<byteit101[m]> That works, see the second line
<enebo[m]> ok ignore b_j!
<byteit101[m]> vs bin/ruby -e 'class Parent < java.lang.Object;def toString;"parent " + super;end;end;class Child < Parent;def test;"child " + toString;end;end;Child.become_java!("/tmp/abc");p'
<byteit101[m]> Specify -J-Xss####k to increase it (#### = cap size in KB).
<byteit101[m]> Error: Your application used more stack memory than the safety cap of 2048K.
<byteit101[m]> Specify -w for full java.lang.StackOverflowError stack trace
<byteit101[m]> bin/ruby -e 'class Parent < java.lang.Object;end;class Child < Parent;def toString;"child " + super;end;end;class GrandChild < Child; end;p'
<byteit101[m]> Error: Your application used more stack memory than the safety cap of 2048K.
<byteit101[m]> Specify -J-Xss####k to increase it (#### = cap size in KB).
<byteit101[m]> Specify -w for full java.lang.StackOverflowError stack trace
<enebo[m]> but that makes sense... jpc will be Child and it will have a getMethod entry marked as having a super implementation
<byteit101[m]> so empty parents above make no difference
<enebo[m]> byteit101: I don't think so because the case you originally put in the comment will run if we just pretend it has a super impl and go down the invokeDirectSuperWithExceptionHandling(context, jpm.getSuperMethod(), javaInvokee, args); path
<byteit101[m]> `Child(toString)< (Parent <)* Object` works, `(GrandChild <)+ Child(toString)< (Parent <)* Object` doesn't
<enebo[m]> well we need a valid getSuperMethod()
<enebo[m]> yeah because toString entry in Child seems to end up with the proper getSuperMethod() return value
<enebo[m]> or I think it does
<enebo[m]> but in GrandChild we ask Grandchild for toString and it has no entry so we do something else which basically has us just call the same method over and over
<enebo[m]> for it to work at the moment whatever javaInvokee passed in to tryProxyInvocation must have a method entry on it with the proper superMethod attached to it
<headius> I'm close to having something
<headius> it works
<headius> $ jruby --disable-gems -X-C blah.rb
<headius> "parent rubyobj.Parent@6a396c1e"
<headius> "parent rubyobj.Child@1c72da34"
<enebo[m]> so what did you change?
<headius> I basically inlined all that java proxy dispatch logic into instanceSuper
<enebo[m]> oh ok
<headius> but using the right module to do the JPC lookup
<enebo[m]> yeah so we will pay some cost per instance_super
<headius> child override is broken but I know how to fix that too
<basshelal[m]> headius: should I add all of the Windows versions?
<basshelal[m]> It's a lot of code to add and I don't know how relevant or useful some of the old Windows versions are like anything before XP
<headius> the check is not cheap
<headius> basshelal: I wouldn't go back past whatever Java 8 requires
<headius> ok the child override case is harder
<headius> because the child adds a same-named shim for super
<headius> so we are back at the bottom again
<headius> the shims need to be unique to the level they are at
<headius> isn
<headius> isn't this fun 😀
<headius> it would work if the shim in Parent was named differently than the shim in Child with what I have here
<headius> I will gist a diff
<headius> actually I can make the check cheaper
<headius> updated gist
<headius> it just detects if the super method is a JI method now
<headius> and then additionally confirms we are calling on a proxied class, which might be redundant at that point
<headius> so there it is gents, ship it
<byteit101[m]> Oh, Its possible to uniqueify the shim names
<headius> yeah I am trying that quick
<byteit101[m]> update in two spots JPC.initMethod ~396 and RubyClass GenerateSuperBridges ~2024
<headius> got it
<byteit101[m]> (feel free to make a constant or helper method, just realized it was the same string in two llocations)
<headius> trying ti figure out what to use to make it unique that I have access to in both places 🤔
<byteit101[m]> Class name? Ruby class object_id?
<headius> the latter would work I think
<headius> hmm unsure how to get to the Ruby class from the JavaProxyClass
<byteit101[m]> this.metaClass?
<headius> oh duh that would be it
<enebo[m]> headius: you can also outline the logic there since this is unlikely to normally occur and won't impact method size as much
<headius> yeah I will look at some refactoring once this works
<headius> still not finding the right metaclass... it is JavaProxyClass in this call
<lopex[m]> headius: very interesting
<lopex[m]> so the complexity of x86 doesnt count very much it appears
<lopex[m]> enebo: ^^
<enebo[m]> lopex: TL;DR
<enebo[m]> x86 is just RISC beneath or something?
<lopex[m]> enebo: the variable instruction sets are mostly solved wrt fetch/exec etc
<lopex[m]> perf wise
<lopex[m]> and the logic doesnt dominate the die on cpus
<enebo[m]> lopex: but Arm will win from using less heat
<lopex[m]> yeah, sure
<lopex[m]> enebo: also, it's all about iset iterations, the younger the set is the simpler it is, but eventually all end up with junk
<enebo[m]> lopex: then they release Leg
<headius> woot, it works
<lopex[m]> Leg ?
<headius> this is kinda nasty but both cases pass now
<enebo[m]> HAHAHAH
<enebo[m]> A newer appendage
<headius> gist updated
<enebo[m]> Followed by the AI chip Head
<enebo[m]> headius: nice so each method will be mangled uniquely and called appropriate at the site with that name
<lopex[m]> ah
<headius> Right
<lopex[m]> enebo: you think that ai chip thing is a fad?
<headius> The instance check here would be nice to eliminate by revisiting the IR but this might be close enough for release
<lopex[m]> I have no opinion
<enebo[m]> if (method instanceof InstanceMethodInvoker && self instanceof JavaProxy) callsomethinginjavamethod
<enebo[m]> then it can be a return
<enebo[m]> for JI super you will do a second instanceof but that is ok
<byteit101[m]> > it is JavaProxyClass in this call
<byteit101[m]> unsure which you are referring to, but the JPC doesn't exist yet in generateSuperBridges
<byteit101[m]> but looks like you abandoned that attempt
<enebo[m]> lopex: I have no opinion on AI chips but I largely because I don't care and I also have no idea of actual limitations (like how far can Tesla take their hardware)
<lopex[m]> enebo: which I dont care as well
<byteit101[m]> headius: oh hmm, the JPC doesn't get the rubyclass (clazz not saved in the new JPC in JPC:519
<enebo[m]> headius: for IR so long as we know it is an InstanceMethodInvoker we can modify the instr I guess
<enebo[m]> lopex: My original joke was just that there will always be new platforms displacing old ones
<byteit101[m]> headius: If you want to save the RubyClass in the JPC, you'll need to add a new arg to the ctor
<enebo[m]> lopex: I think the historical issue is getting a new platform off the ground to make tooling etc but those costs will just keep dropping so I expect more hardware variety as time moves forward
<lopex[m]> enebo: but the beer will never change
<lopex[m]> enebo: we have shortages of American beers here now
<enebo[m]> lopex: you need to come to America one day for beers...It changes too much
<lopex[m]> enebo: the shifts in styles you mean ?
<enebo[m]> lopex: I ordered beer from Belgium on Friday and got it here yesterday. An expensive experiment!
<enebo[m]> lopex: just saying if you accumulate baggage which slowly affects the platform they can put out a new system
<lopex[m]> enebo: here, it was all about hazy ipas lately which I dont like that much
<enebo[m]> lopex: A lot of hardware is making sure old software continues to work but as time moves on I think language portablity will move beyond C
<enebo[m]> lopex: NE/Hazy IPAs are massive her too and I am over them but don't dislike them
<lopex[m]> enebo: I'm leaning towards barleys now.. and RISes etc
<enebo[m]> lopex: most beers I am seeing a big increase in ABV 8+% is very common now
<lopex[m]> enebo: I like either light beers or heavy ones
<enebo[m]> I bought an Italian RIS that is like 12%..That will be an adventure
<lopex[m]> enebo: summer IPAs are still good for me
<enebo[m]> lopex: This summer I have gotten more Hefes (well not more than IPAs) as I enjoy them in the summer
<lopex[m]> enebo: bleh, on last weekend I ordered 0.3L 20%+ icebock, it was too much of that
<enebo[m]> HAHAH
<lopex[m]> enebo: I was driking it for like 3 hours
<enebo[m]> 20% is largely a syrupy liquer
<headius> I really loved the hazies for a while but now they're all so same-y
<headius> I'd like to see something new
<enebo[m]> GOSE!
<headius> Or just a return to good old fashioned hoppy double ipas
<headius> Yeah eff that
<lopex[m]> also juicy IPAs are common here too
<lopex[m]> now
<headius> Milkshake ipas tried to take over here but lactose just isn't for everybody
<enebo[m]> There are a lot of double IPAs but they are pretty split between hazy/not
<headius> I don't like the mouth coating or texture of milkshakes
<lopex[m]> headius: I also liked good double IPAs but I guess I;'m to old for that now
<enebo[m]> more juicy but I like the old piney ones
<headius> Yeah
<lopex[m]> yeah piny is good
<enebo[m]> and some with a little malt
<enebo[m]> It is one reason I will still buy centennial IPA from time to time
<enebo[m]> yeah I am not buying from Surly
<enebo[m]> well not much
<headius> I got some axe man the other day and it was nice to return to a traditional piney double IPA
<headius> Even though surly seems to have screwed that recipe up a little
<basshelal[m]> headius: Ok I think I've done everything I can, I put them all in separate PRs
<basshelal[m]> headius: I'm not 100% about this though
<basshelal[m]> Need to get a FreeBSD image running to see if `freebsd-version -u` is actually different from a java `os.version` or `uname` because if not then we can use my new version methods to check instead of using `exec` and launching a new process or whatever
<basshelal[m]> When the PRs get merged the next thing we could do is use our new APIs in the places you referenced, I could try to do that later, just hope there are tests to ensure I don't break anything
<headius> byteit101 thank you for your help and patience, I feel like I have to relearn this stuff every time I go back in
<basshelal[m]> Dogfooding is awesome
<headius> I will distill this fix down a bit and then see how it goes in testing
<byteit101[m]> No problem! And glad I could be of assistance fixing this, and making the original JI PR work in general
<headius> There will certainly be other issues but it's still so much cleaner than the old stuff
<byteit101[m]> Indeed, I remember being exicited I could delete that old file
<basshelal[m]> I have a FreeBSD image!
<basshelal[m]> No major difference between `freebsd-version -u` and regular system property `` except _maybe_ if you did a kernel update the `freebsd-version -u` will report the new kernel and not the old one. _Maybe_!
<basshelal[m]> Not sure if this is a killer feature or not, we'd have to ask the FreeBSD users, likely so though because the person who added it probably knows what's best for FreeBSD though if you can headius ask a FreeBSD expert/user if it's an absolutely necessary feature to have, if not we can use `Platform.getVersionMajor()` for that FreeBSDPOSIX hack.
<basshelal[m]> Otherwise I'd say it's happy days! Everything I've added should be ok as far as I can tell and once they're all merged and pushed into maven, we can use our own APIs to clean up a lot of the internal code and keep it uniform