Skip to content

Strange (JIT?) behaviour causing assignment function to be called twice in Rails #937

Closed
kenips opened this Issue Aug 1, 2013 · 1 comment

2 participants

@kenips
kenips commented Aug 1, 2013

I'm quite lost on this one - so any help would be appreciated. Essentially I have a Rails model with one of its attribute overridden (say options)

  def options=(arg)
    #some processing
    Rails.logger.warn "I'm in options"
    super
  end

Running this code I'm seeing a strange behaviour that "I'm in options" gets printed TWICE. It happens usually after a cold start (that rails is running but no requests have been made for a while). Once the code is hot it only prints "I'm in options" once.

I haven't logged any of this error in staging yet (where code is preloaded), so it's very likely that this is only impacted by cold start.

Any idea? /cc @headius

@headius headius added a commit that referenced this issue Sep 3, 2013
@headius headius Use proper original name for frame created via indy logic.
Super still uses frame name to do the lookup of the superclass's
method, so when super is present we have to push a frame with the
name of the currently-executing method. Normally this is the name
at the call site, but when the call is to an aliased method the
original name must be used to invoke the actual method. In the
non-indy logic, this is done by calling through AliasMethod, which
inserts the original name into the call path for use in frames. In
the indy logic, where we unwrap AliasMethod to bind more directly,
we were not carrying along the original name and were always using
the name at the call site. This caused the target method to have
the aliased name in its frame and to attempt to super up that name
instead of the original name.

The fix was to propagate the original name from method unwrapping
through to all places where framing is needed.

In the future, the super name will be statically calculated for
most cases, since it does not change for normal method
definitions.

Fixes #802 and #937.
484b4b4
@headius
JRuby Team member
headius commented Sep 3, 2013

Looking at this again, I'm pretty sure the fix for #801 will fix this issue as well.
#802 was caused by invokedynamic call logic not putting the original name of an aliased method into that method's call frame. As a result, super would attempt to super up the original name, which caused NoMethodError.

In this case, I think it's possible that the super call looped back on itself via some other alias or wrapper method, but in doing so it got the proper "options=" name on its frame the second time through. As a result, you would see it called twice but then dispatch properly to the superclass.

I'm optimistically marking this as fixed, since it's too similar to #802 to ignore. HOWEVER...if it's at all possible for you to verify your app against JRuby master, it would give me more confidence that it's fixed.

@headius headius closed this Sep 3, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.