Skip to content

Instantly share code, notes, and snippets.

@headius
Forked from wycats/call-site.java
Created January 23, 2009 06:50
Show Gist options
  • Save headius/50918 to your computer and use it in GitHub Desktop.
Save headius/50918 to your computer and use it in GitHub Desktop.
package org.jruby.runtime.callsite;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.RubyClass;
import org.jruby.runtime.Visibility;
public class RespondToCallSite extends NormalCachingCallSite {
private String lastString;
private CacheEntry respondEntry;
private IRubyObject respondsTo;
public RespondToCallSite() {
super("respond_to?");
}
@Override
public IRubyObject call(ThreadContext context, IRubyObject caller, IRubyObject self, IRubyObject name) {
RubyClass klass = self.getMetaClass();
if (cache.typeOk(klass) && cache.method == context.getRuntime().getRespondToMethod()) {
String newString = name.asJavaString();
if (lastString != newString || !respondEntry.typeOk(klass)) {
lastString = newString;
respondEntry = klass.searchWithCache(methodName);
respondsTo = respondEntry.method.isUndefined() ? context.getRuntime().getTrue() : context.getRuntime().getFalse();
}
return respondsTo;
} else {
return super.call(context, caller, self, name);
}
}
@Override
public IRubyObject call(ThreadContext context, IRubyObject caller, IRubyObject self, IRubyObject name, IRubyObject bool) {
RubyClass klass = self.getMetaClass();
if (cache.typeOk(klass) && cache.method == context.getRuntime().getRespondToMethod()) {
String newString = name.asJavaString();
if (lastString != newString || !respondEntry.typeOk(klass)) {
lastString = newString;
respondEntry = klass.searchWithCache(methodName);
boolean checkVisibility = !bool.isTrue();
if (!respondEntry.method.isUndefined()) {
respondsTo = !(checkVisibility && respondEntry.method.getVisibility() == Visibility.PRIVATE)? context.getRuntime().getTrue() : context.getRuntime().getFalse();
} else {
respondsTo = context.getRuntime().getFalse();
}
}
return respondsTo;
} else {
return super.call(context, caller, self, name, bool);
}
}
}
Index: src/org/jruby/RubyInstanceConfig.java
===================================================================
--- src/org/jruby/RubyInstanceConfig.java (revision 8874)
+++ src/org/jruby/RubyInstanceConfig.java (working copy)
@@ -217,6 +217,8 @@
= SafePropertyAccessor.getProperty("jruby.jit.exclude");
public static boolean nativeEnabled = true;
+ public static final boolean YEHUDA_FAIL
+ = SafePropertyAccessor.getBoolean("yehuda.fail");
public static interface LoadServiceCreator {
LoadService create(Ruby runtime);
diff --git a/src/org/jruby/Ruby.java b/src/org/jruby/Ruby.java
index 5918031..18e5534 100644
--- a/src/org/jruby/Ruby.java
+++ b/src/org/jruby/Ruby.java
@@ -132,6 +132,7 @@ import org.jruby.util.io.ChannelDescriptor;
import com.kenai.constantine.Constant;
import com.kenai.constantine.ConstantSet;
+import org.jruby.internal.runtime.methods.DynamicMethod;
/**
* The Ruby object represents the top-level of a JRuby "instance" in a given VM.
@@ -1331,11 +1332,11 @@ public final class Ruby {
}
}
- Object getRespondToMethod() {
+ public Object getRespondToMethod() {
return respondToMethod;
}
- void setRespondToMethod(Object rtm) {
+ public void setRespondToMethod(Object rtm) {
this.respondToMethod = rtm;
}
#r000 ecx : parm 0: org/jruby/runtime/callsite/RespondToCallSite:NotNull *
#r005 edx : parm 1: org/jruby/runtime/ThreadContext:exact *
#r049 esp+92: pad0, owned by CALLER
#r048 esp+88: parm 4: org/jruby/runtime/builtin/IRubyObject *
#r047 esp+84: parm 3: org/jruby/runtime/builtin/IRubyObject *
#r046 esp+80: parm 2: org/jruby/runtime/builtin/IRubyObject *
# -- Old esp -- Framesize: 80 --
#r045 esp+76: return address
#r044 esp+72: pad2, in_preserve
#r043 esp+68: pad2, in_preserve
#r042 esp+64: Fixed slot 0
#r065 esp+60: spill
#r064 esp+56: spill
#r063 esp+52: spill
#r062 esp+48: spill
#r061 esp+44: spill
#r060 esp+40: spill
#r059 esp+36: spill
#r058 esp+32: spill
#r057 esp+28: spill
#r056 esp+24: spill
#r055 esp+20: spill
#r054 esp+16: spill
#r053 esp+12: outgoing argument
#r052 esp+ 8: outgoing argument
#r051 esp+ 4: outgoing argument
#r050 esp+ 0: outgoing argument
#
000 N708: # B1 <- BLOCK HEAD IS JUNK Freq: 15000
000 CMP EAX,[ECX+4] # Inline cache check
JNE SharedRuntime::handle_ic_miss_stub
NOP
NOP
NOP
000
00c B1: # B77 B2 <- BLOCK HEAD IS JUNK Freq: 15000
00c # stack bang
PUSHL EBP
SUB ESP,72 # Create frame
01a MOV [ESP + #16],ECX
01e MOV EAX,[ESP + #84]
022 MOV EBX,[EAX + #4]
025 NullCheck EAX
025
025 B2: # B4 B3 <- B1 Freq: 15000
025 CMPu EBX,precise klass org/jruby/RubyFixnum: 0x0848a508:Constant:exact *
02b Jne,us B4 P=0.427461 C=-1.000000
02b
02d B3: # B6 <- B2 Freq: 8588.08
02d #checkcastPP of EAX
02d MOV EBX,[EAX + #12] ! Field org/jruby/RubyBasicObject.metaClass
030 MOV [ESP + #28],EAX
034 JMP,s B6
034
036 B4: # B76 B5 <- B2 Freq: 6411.9
036 CMPu EBX,precise klass org/jruby/RubyObject: 0x0848a578:Constant:exact *
03c Jne,u B76 P=0.000001 C=-1.000000
03c
042 B5: # B6 <- B4 Freq: 6411.9
042 #checkcastPP of EAX
042 MOV EBX,[EAX + #12] ! Field org/jruby/RubyBasicObject.metaClass
045 MOV [ESP + #28],EAX
045
049 B6: # B75 B7 <- B3 B5 Freq: 15000
049 MOV EBP,[ECX + #16] ! Field Volatileorg/jruby/runtime/callsite/CachingCallSite.cache
04c MEMBAR-acquire
04c MOV EDI,[EBP + #8] ! Field org/jruby/runtime/callsite/CacheEntry.generation
04f NullCheck EBP
04f
04f B7: # B74 B8 <- B6 Freq: 15000
04f MOV EAX,[EBX + #56] ! Field org/jruby/RubyModule.generation
052 NullCheck EBX
052
052 B8: # B73 B9 <- B7 Freq: 14999.9
052 MOV ECX,[EAX + #8] ! Field Volatileorg/jruby/RubyModule$Generation.hash
055 NullCheck EAX
055
055 B9: # B55 B10 <- B8 Freq: 14999.9
055 MEMBAR-acquire
055 CMP EDI,ECX
057 Jne B55 P=0.000000 C=6701.000000
057
05d B10: # B54 B11 <- B9 Freq: 14999.9
05d MOV ECX,[ESP + #16]
061 MOV EDI,[ECX + #16] ! Field Volatileorg/jruby/runtime/callsite/CachingCallSite.cache
064 MEMBAR-acquire
064 MOV ECX,[EDI + #12] ! Field org/jruby/runtime/callsite/CacheEntry.method
067 NullCheck EDI
067
067 B11: # B53 B12 <- B10 Freq: 14999.9
067 MOV EBP,EDX
069 MOV EAX,[EDX + #40] ! Field org/jruby/runtime/ThreadContext.runtime
06c NullCheck EDX
06c
06c B12: # B52 B13 <- B11 Freq: 14999.9
06c MOV EDX,[EAX + #604] ! Field org/jruby/Ruby.respondToMethod
072 NullCheck EAX
072
072 B13: # B21 B14 <- B12 Freq: 14999.9
072 CMPu ECX,EDX
074 Jne,us B21 P=0.427419 C=15004.000000
074
076 B14: # B51 B15 <- B13 Freq: 8588.64
076 MOV EDI,[ESP + #88]
07a MOV EAX,[EDI + #4]
07d NullCheck EDI
07d
07d B15: # B50 B16 <- B14 Freq: 8588.63
07d CMPu EAX,precise klass org/jruby/RubySymbol: 0x0848a658:Constant:exact *
083 Jne,u B50 P=0.000001 C=-1.000000
083
089 B16: # B35 B17 <- B15 Freq: 8588.62
089 #checkcastPP of EDI
089 MOV EAX,[ESP + #16]
08d MOV EAX,[EAX + #20] ! Field org/jruby/runtime/callsite/RespondToCallSite.lastString
090 MOV EDX,[EDI + #24] ! Field org/jruby/RubySymbol.symbol
093 CMPu EAX,EDX
095 Jne,u B35 P=0.000000 C=8591.000000
095
09b B17: # B34 B18 <- B16 Freq: 8588.62
09b MOV ECX,[ESP + #16]
09f MOV EAX,[ECX + #24] ! Field org/jruby/runtime/callsite/RespondToCallSite.respondEntry
0a2 MOV ECX,[EAX + #8] ! Field org/jruby/runtime/callsite/CacheEntry.generation
0a5 NullCheck EAX
0a5
0a5 B18: # B33 B19 <- B17 Freq: 8588.61
0a5 MOV EAX,[EBX + #56] ! Field org/jruby/RubyModule.generation
0a8 MOV EDI,[EAX + #8] ! Field Volatileorg/jruby/RubyModule$Generation.hash
0ab NullCheck EAX
0ab
0ab B19: # B35 B20 <- B18 Freq: 8588.6
0ab MEMBAR-acquire
0ab CMP ECX,EDI
0ad Jne B35 P=0.000000 C=6701.000000
0ad
0b3 B20: # B32 <- B19 Freq: 8588.6
0b3 MOV EBX,[ESP + #16]
0b7 MOV EAX,[EBX + #28] ! Field org/jruby/runtime/callsite/RespondToCallSite.respondsTo
0ba JMP B32
0ba
0bf B21: # B72 B22 <- B13 B55 Freq: 6411.25
0bf MOV EBX,[EBP + #32] ! Field org/jruby/runtime/ThreadContext.calls
0c2 NullCheck EBP
0c2
0c2 B22: # B26 B23 <- B21 Freq: 6411.24
0c2 MOV ECX,EBX
0c4 INC ECX
0c5 MOV [EBP + #32],ECX ! Field org/jruby/runtime/ThreadContext.calls
0c8 TEST EBX,#255
0ce Jne,s B26 P=0.900000 C=-1.000000
0ce
0d0 B23: # B71 B24 <- B22 Freq: 641.124
0d0 MOV EDI,[EBP + #44] ! Field org/jruby/runtime/ThreadContext.thread
0d3 MOVSX8 EBX,[EDI + #24] ! Field Volatileorg/jruby/RubyThread.killed
0d7 NullCheck EDI
0d7
0d7 B24: # B56 B25 <- B23 Freq: 641.123
0d7 MEMBAR-acquire
0d7 TEST EBX,EBX
0d9 Jne B56 P=0.000000 C=6701.000000
0d9
0df B25: # B58 B26 <- B57 B24 Freq: 641.123
0df MOV EBX,[EDI + #48] ! Field org/jruby/RubyThread.receivedException
0e2 TEST EBX,EBX
0e4 Jne B58 P=0.000000 C=6701.000000
0e4
0ea B26: # B67 B27 <- B59 B25 B22 Freq: 6411.24
0ea MOV ECX,[ESP + #28]
0ee MOV EAX,(oop)-1
CALL,dynamic org.jruby.runtime.builtin.IRubyObject::getMetaClass
# org.jruby.runtime.callsite.CachingCallSite::pollAndGetClass @ bci:5 L[0]=_ L[1]=_ L[2]=_
# org.jruby.runtime.callsite.CachingCallSite::call @ bci:2 L[0]=esp + #16 L[1]=EBP L[2]=esp + #80 L[3]=esp + #28 L[4]=esp + #88 L[5]=_ L[6]=_
# org.jruby.runtime.callsite.RespondToCallSite::call @ bci:131 L[0]=_ L[1]=_ L[2]=_ L[3]=_ L[4]=_ L[5]=_ L[6]=_
# AllocatedObj(0x90f2b920)
AllocatedObj(0x90f2b920)
AllocatedObj(0x90f2b920)
AllocatedObj(0x90f2b920)
AllocatedObj(0x90f2b920)
0f8
0f8 B27: # B66 B28 <- B26 Freq: 6411.11
# Block is sole successor of call
0f8 MOV ECX,[ESP + #16]
0fc MOV EDI,[ECX + #16] ! Field Volatileorg/jruby/runtime/callsite/CachingCallSite.cache
0ff MEMBAR-acquire
0ff MOV EBX,[EDI + #8] ! Field org/jruby/runtime/callsite/CacheEntry.generation
102 NullCheck EDI
102
102 B28: # B65 B29 <- B27 Freq: 6411.1
102 MOV EDX,[EAX + #56] ! Field org/jruby/RubyModule.generation
105 NullCheck EAX
105
105 B29: # B64 B30 <- B28 Freq: 6411.1
105 MOV ESI,[EDX + #8] ! Field Volatileorg/jruby/RubyModule$Generation.hash
108 NullCheck EDX
108
108 B30: # B61 B31 <- B29 Freq: 6411.09
108 MEMBAR-acquire
108 CMP EBX,ESI
10a Jne B61 P=0.000000 C=6701.000000
10a
110 B31: # B60 B32 <- B30 Freq: 6411.09
110 MOV EBX,[ECX + #8] ! Field org/jruby/runtime/CallSite.methodName
113 MOV ECX,[EDI + #12] ! Field org/jruby/runtime/callsite/CacheEntry.method
116 MOV EDX,EBP
118 MOV EDI,[ESP + #28]
11c MOV [ESP + #0],EDI
11f MOV [ESP + #4],EAX
123 MOV [ESP + #8],EBX
127 MOV EBX,[ESP + #88]
12b MOV [ESP + #12],EBX
12f NOP # 3 bytes pad for loops and calls
132 MOV EAX,(oop)-1
CALL,dynamic org.jruby.internal.runtime.methods.DynamicMethod::call
# org.jruby.runtime.callsite.CachingCallSite::call @ bci:38 L[0]=_ L[1]=_ L[2]=_ L[3]=_ L[4]=_ L[5]=_ L[6]=_
# org.jruby.runtime.callsite.RespondToCallSite::call @ bci:131 L[0]=_ L[1]=_ L[2]=_ L[3]=_ L[4]=_ L[5]=_ L[6]=_
#
13c
13c B32: # N708 <- B44 B20 B31 B62 Freq: 14999.6
13c ADD ESP,72 # Destroy frame
POPL EBP
TEST PollPage,EAX ! Poll Safepoint
146 RET
public synchronized static CallSite getCallSite(String name) {
if (RubyInstanceConfig.YEHUDA_FAIL) {
if (name.equals("respond_to?")) {
return new RespondToCallSite();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment