Permalink
Browse files

Performance improvements for defined? logic.

* Return a cached, frozen string rather than recreating each time.
* Cache variable accessors for ivar defined? checks.
  • Loading branch information...
1 parent 8a309ad commit b03d0bc89aefca13deaff7a568e5d9118a9ca2a8 @headius headius committed Sep 17, 2012
Showing with 364 additions and 159 deletions.
  1. +19 −13 src/org/jruby/Ruby.java
  2. +4 −2 src/org/jruby/ast/AndNode.java
  3. +4 −2 src/org/jruby/ast/AssignableNode.java
  4. +4 −2 src/org/jruby/ast/AttrAssignNode.java
  5. +6 −4 src/org/jruby/ast/BackRefNode.java
  6. +3 −3 src/org/jruby/ast/CallNoArgNode.java
  7. +4 −2 src/org/jruby/ast/CallNode.java
  8. +6 −5 src/org/jruby/ast/ClassVarNode.java
  9. +7 −2 src/org/jruby/ast/Colon2ConstNode.java
  10. +2 −1 src/org/jruby/ast/Colon2ImplicitNode.java
  11. +6 −2 src/org/jruby/ast/Colon2MethodNode.java
  12. +5 −3 src/org/jruby/ast/Colon3Node.java
  13. +4 −2 src/org/jruby/ast/ConstNode.java
  14. +4 −3 src/org/jruby/ast/DNode.java
  15. +5 −3 src/org/jruby/ast/DVarNode.java
  16. +2 −2 src/org/jruby/ast/DefinedNode.java
  17. +10 −2 src/org/jruby/ast/FCallNode.java
  18. +4 −2 src/org/jruby/ast/FalseNode.java
  19. +4 −2 src/org/jruby/ast/GlobalVarNode.java
  20. +11 −5 src/org/jruby/ast/InstVarNode.java
  21. +4 −2 src/org/jruby/ast/LocalVarNode.java
  22. +4 −2 src/org/jruby/ast/Match2Node.java
  23. +3 −2 src/org/jruby/ast/Match3Node.java
  24. +2 −1 src/org/jruby/ast/NewlineNode.java
  25. +4 −2 src/org/jruby/ast/NilNode.java
  26. +4 −2 src/org/jruby/ast/Node.java
  27. +3 −2 src/org/jruby/ast/NotNode.java
  28. +7 −5 src/org/jruby/ast/NthRefNode.java
  29. +4 −2 src/org/jruby/ast/OpAsgnAndNode.java
  30. +4 −2 src/org/jruby/ast/OpAsgnOrNode.java
  31. +4 −2 src/org/jruby/ast/OrNode.java
  32. +4 −2 src/org/jruby/ast/SelfNode.java
  33. +4 −2 src/org/jruby/ast/SuperNode.java
  34. +4 −2 src/org/jruby/ast/TrueNode.java
  35. +4 −2 src/org/jruby/ast/VCallNode.java
  36. +4 −2 src/org/jruby/ast/YieldNode.java
  37. +4 −2 src/org/jruby/ast/ZSuperNode.java
  38. +12 −0 src/org/jruby/ast/executable/AbstractScript.java
  39. +9 −1 src/org/jruby/ast/executable/RuntimeCache.java
  40. +33 −31 src/org/jruby/compiler/ASTCompiler.java
  41. +5 −4 src/org/jruby/compiler/ASTCompiler19.java
  42. +2 −0 src/org/jruby/compiler/BodyCompiler.java
  43. +2 −0 src/org/jruby/compiler/CacheCompiler.java
  44. +15 −12 src/org/jruby/compiler/impl/BaseBodyCompiler.java
  45. +16 −0 src/org/jruby/compiler/impl/InheritedCacheCompiler.java
  46. +1 −1 src/org/jruby/evaluator/ASTInterpreter.java
  47. +2 −2 src/org/jruby/ir/instructions/defined/MethodDefinedInstr.java
  48. +10 −9 src/org/jruby/javasupport/util/RuntimeHelpers.java
  49. +16 −1 src/org/jruby/runtime/callsite/CachingCallSite.java
  50. +60 −0 src/org/jruby/util/DefinedMessage.java
View
@@ -118,6 +118,7 @@
import org.jruby.runtime.scope.ManyVarsDynamicScope;
import org.jruby.threading.DaemonThreadFactory;
import org.jruby.util.ByteList;
+import org.jruby.util.DefinedMessage;
import org.jruby.util.IOInputStream;
import org.jruby.util.IOOutputStream;
import org.jruby.util.JRubyClassLoader;
@@ -143,19 +144,7 @@
import java.net.BindException;
import java.nio.channels.ClosedChannelException;
import java.security.SecureRandom;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.IdentityHashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-import java.util.Stack;
-import java.util.Vector;
-import java.util.WeakHashMap;
+import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.SynchronousQueue;
@@ -1112,6 +1101,9 @@ private void init() {
// Initialize all the core classes
bootstrap();
+
+ // set up defined messages
+ initDefinedMessages();
irManager = new IRManager();
@@ -1162,6 +1154,14 @@ private void bootstrap() {
initExceptions();
}
+ private void initDefinedMessages() {
+ for (DefinedMessage definedMessage : DefinedMessage.values()) {
+ RubyString str = RubyString.newString(this, ByteList.create(definedMessage.getText()));
+ str.setFrozen(true);
+ definedMessages.put(definedMessage, str);
+ }
+ }
+
private void initRoot() {
boolean oneNine = is1_9();
// Bootstrap the top of the hierarchy
@@ -4219,6 +4219,10 @@ public void setFFI(FFI ffi) {
this.ffi = ffi;
}
+ public RubyString getDefinedMessage(DefinedMessage definedMessage) {
+ return definedMessages.get(definedMessage);
+ }
+
@Deprecated
public int getSafeLevel() {
return 0;
@@ -4475,4 +4479,6 @@ public void secure(int level) {
private FFI ffi;
private JavaProxyClassFactory javaProxyClassFactory;
+
+ private EnumMap<DefinedMessage, RubyString> definedMessages = new EnumMap<DefinedMessage, RubyString>(DefinedMessage.class);
}
@@ -34,12 +34,14 @@
import java.util.List;
import org.jruby.Ruby;
+import org.jruby.RubyString;
import org.jruby.ast.visitor.NodeVisitor;
import org.jruby.lexer.yacc.ISourcePosition;
import org.jruby.runtime.Block;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
+import org.jruby.util.DefinedMessage;
/**
* Represents a && (and) operator.
@@ -96,11 +98,11 @@ public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject se
}
@Override
- public ByteList definition(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
+ public RubyString definition(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
if (!context.runtime.is1_9()) {
return super.definition(runtime, context, self, aBlock);
} else {
- return EXPRESSION_BYTELIST;
+ return runtime.getDefinedMessage(DefinedMessage.EXPRESSION);
}
}
}
@@ -31,13 +31,15 @@
package org.jruby.ast;
import org.jruby.Ruby;
+import org.jruby.RubyString;
import org.jruby.ast.types.IArityNode;
import org.jruby.lexer.yacc.ISourcePosition;
import org.jruby.runtime.Arity;
import org.jruby.runtime.Block;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
+import org.jruby.util.DefinedMessage;
/**
* Base class of any node which can be assigned to.
@@ -81,7 +83,7 @@ public Arity getArity() {
}
@Override
- public ByteList definition(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
- return ASSIGNMENT_BYTELIST;
+ public RubyString definition(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
+ return runtime.getDefinedMessage(DefinedMessage.ASSIGNMENT);
}
}
@@ -33,6 +33,7 @@
import org.jruby.Ruby;
import org.jruby.RubyArray;
import org.jruby.RubyClass;
+import org.jruby.RubyString;
import org.jruby.ast.types.INameNode;
import org.jruby.ast.visitor.NodeVisitor;
import org.jruby.evaluator.ASTInterpreter;
@@ -48,6 +49,7 @@
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
+import org.jruby.util.DefinedMessage;
/**
* Node that represents an assignment of either an array element or attribute.
@@ -256,7 +258,7 @@ private IRubyObject otherAssign(Ruby runtime, ThreadContext context, IRubyObject
}
@Override
- public ByteList definition(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
+ public RubyString definition(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
if (receiverNode.definition(runtime, context, self, aBlock) != null) {
try {
IRubyObject receiver = receiverNode.interpret(runtime, context, self, aBlock);
@@ -267,7 +269,7 @@ public ByteList definition(Ruby runtime, ThreadContext context, IRubyObject self
if (visibility != Visibility.PRIVATE &&
(visibility != Visibility.PROTECTED || metaClass.getRealClass().isInstance(self))) {
if (metaClass.isMethodBound(name, false)) {
- return ASTInterpreter.getArgumentDefinition(runtime, context, argsNode, ASSIGNMENT_BYTELIST, self, aBlock);
+ return ASTInterpreter.getArgumentDefinition(runtime, context, argsNode, runtime.getDefinedMessage(DefinedMessage.ASSIGNMENT), self, aBlock);
}
}
} catch (JumpException e) {
@@ -36,12 +36,14 @@
import org.jruby.Ruby;
import org.jruby.RubyMatchData;
import org.jruby.RubyRegexp;
+import org.jruby.RubyString;
import org.jruby.ast.visitor.NodeVisitor;
import org.jruby.lexer.yacc.ISourcePosition;
import org.jruby.runtime.Block;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
+import org.jruby.util.DefinedMessage;
/**
* Regexp back reference:
@@ -57,12 +59,12 @@
private final char type;
/** ByteList for the name of this backref global */
- private final ByteList nameByteList;
+ private final DefinedMessage definedMessage;
public BackRefNode(ISourcePosition position, int type) {
super(position);
this.type = (char) type;
- this.nameByteList = ByteList.create("$" + (char)type);
+ this.definedMessage = DefinedMessage.byText("$" + (char)type);
}
public NodeType getNodeType() {
@@ -110,11 +112,11 @@ public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject se
}
@Override
- public ByteList definition(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
+ public RubyString definition(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
IRubyObject backref = context.getCurrentScope().getBackRef(runtime);
if (backref instanceof RubyMatchData) {
- return context.runtime.is1_9() ? GLOBAL_VARIABLE_BYTELIST : nameByteList;
+ return runtime.getDefinedMessage(runtime.is1_9() ? DefinedMessage.GLOBAL_VARIABLE : definedMessage);
}
return null;
}
@@ -34,6 +34,7 @@
import org.jruby.Ruby;
import org.jruby.RubyClass;
+import org.jruby.RubyString;
import org.jruby.exceptions.JumpException;
import org.jruby.internal.runtime.methods.DynamicMethod;
import org.jruby.javasupport.util.RuntimeHelpers;
@@ -69,8 +70,7 @@ public Node setIterNode(Node iterNode) {
}
@Override
- public ByteList definition(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
- ByteList definition = null;
+ public RubyString definition(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
if (getReceiverNode().definition(runtime, context, self, aBlock) != null) {
try {
IRubyObject receiver = getReceiverNode().interpret(runtime, context, self, aBlock);
@@ -79,6 +79,6 @@ public ByteList definition(Ruby runtime, ThreadContext context, IRubyObject self
}
}
- return definition;
+ return null;
}
}
@@ -37,6 +37,7 @@
import org.jruby.Ruby;
import org.jruby.RubyArray;
import org.jruby.RubyClass;
+import org.jruby.RubyString;
import org.jruby.ast.types.INameNode;
import org.jruby.ast.visitor.NodeVisitor;
import org.jruby.evaluator.ASTInterpreter;
@@ -52,6 +53,7 @@
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
+import org.jruby.util.DefinedMessage;
/**
* A method or operator call.
@@ -171,7 +173,7 @@ public IRubyObject assign(Ruby runtime, ThreadContext context, IRubyObject self,
}
@Override
- public ByteList definition(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
+ public RubyString definition(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
if (receiverNode.definition(runtime, context, self, aBlock) != null) {
try {
IRubyObject receiver = receiverNode.interpret(runtime, context, self, aBlock);
@@ -182,7 +184,7 @@ public ByteList definition(Ruby runtime, ThreadContext context, IRubyObject self
if (visibility != Visibility.PRIVATE &&
(visibility != Visibility.PROTECTED || metaClass.getRealClass().isInstance(self))) {
if (!method.isUndefined()) {
- return ASTInterpreter.getArgumentDefinition(runtime, context, getArgsNode(), METHOD_BYTELIST, self, aBlock);
+ return ASTInterpreter.getArgumentDefinition(runtime, context, getArgsNode(), context.runtime.getDefinedMessage(DefinedMessage.METHOD), self, aBlock);
}
}
} catch (JumpException excptn) {
@@ -36,6 +36,7 @@
import org.jruby.MetaClass;
import org.jruby.Ruby;
import org.jruby.RubyModule;
+import org.jruby.RubyString;
import org.jruby.ast.types.INameNode;
import org.jruby.ast.visitor.NodeVisitor;
import org.jruby.evaluator.ASTInterpreter;
@@ -44,6 +45,7 @@
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
+import org.jruby.util.DefinedMessage;
/**
* Access to a class variable.
@@ -94,20 +96,19 @@ public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject se
}
@Override
- public ByteList definition(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
- //RubyModule module = context.getRubyClass();
+ public RubyString definition(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
RubyModule module = context.getCurrentScope().getStaticScope().getModule();
if (module == null && self.getMetaClass().isClassVarDefined(name)) {
- return CLASS_VARIABLE_BYTELIST;
+ return runtime.getDefinedMessage(DefinedMessage.CLASS_VARIABLE);
} else if (module.isClassVarDefined(name)) {
- return CLASS_VARIABLE_BYTELIST;
+ return runtime.getDefinedMessage(DefinedMessage.CLASS_VARIABLE);
}
IRubyObject attached = module.isSingleton() ? ((MetaClass)module).getAttached() : null;
if (attached instanceof RubyModule && ((RubyModule) attached).isClassVarDefined(name)) {
- return CLASS_VARIABLE_BYTELIST;
+ return runtime.getDefinedMessage(DefinedMessage.CLASS_VARIABLE);
}
return null;
@@ -7,13 +7,15 @@
import org.jruby.Ruby;
import org.jruby.RubyModule;
+import org.jruby.RubyString;
import org.jruby.exceptions.JumpException;
import org.jruby.javasupport.util.RuntimeHelpers;
import org.jruby.lexer.yacc.ISourcePosition;
import org.jruby.runtime.Block;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
+import org.jruby.util.DefinedMessage;
/**
*
@@ -39,10 +41,13 @@ public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject se
}
@Override
- public ByteList definition(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
+ public RubyString definition(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
IRubyObject lastError = context.getErrorInfo();
try {
- if (RuntimeHelpers.isModuleAndHasConstant(leftNode.interpret(runtime, context, self, aBlock), name)) return CONSTANT_BYTELIST;
+ if (RuntimeHelpers.isModuleAndHasConstant(
+ leftNode.interpret(runtime, context, self, aBlock), name)) {
+ return runtime.getDefinedMessage(DefinedMessage.CONSTANT);
+ }
} catch (JumpException e) {
// replace lastError
context.setErrorInfo(lastError);
@@ -30,6 +30,7 @@
import org.jruby.Ruby;
import org.jruby.RubyModule;
+import org.jruby.RubyString;
import org.jruby.lexer.yacc.ISourcePosition;
import org.jruby.runtime.Block;
import org.jruby.runtime.ThreadContext;
@@ -69,7 +70,7 @@ public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject se
* appear to be a ConstNode.
*/
@Override
- public ByteList definition(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
+ public RubyString definition(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
assert false: "definition should not ever happen for Colon2ImplicitNode";
return null;
}
@@ -6,13 +6,15 @@
package org.jruby.ast;
import org.jruby.Ruby;
+import org.jruby.RubyString;
import org.jruby.exceptions.JumpException;
import org.jruby.javasupport.util.RuntimeHelpers;
import org.jruby.lexer.yacc.ISourcePosition;
import org.jruby.runtime.Block;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
+import org.jruby.util.DefinedMessage;
/**
* Represents a constant path which ends in a method (e.g. Foo::bar). Note: methods with
@@ -31,9 +33,11 @@ public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject se
}
@Override
- public ByteList definition(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
+ public RubyString definition(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
try {
- if (hasMethod(leftNode.interpret(runtime, context, self, aBlock))) return METHOD_BYTELIST;
+ if (hasMethod(leftNode.interpret(runtime, context, self, aBlock))) {
+ return runtime.getDefinedMessage(DefinedMessage.METHOD);
+ }
} catch (JumpException e) {
}
Oops, something went wrong.

0 comments on commit b03d0bc

Please sign in to comment.