Skip to content

Commit

Permalink
Fixes #3808. defined? poor performance
Browse files Browse the repository at this point in the history
As much as I dislike this fix it is exactly how MRI handles colon2
defined?.  The current impl is to basically call defined? on lhs of
a colon2 and if it is not nil then build lhs for realsies and then
use that live value to test the rhs.  This new mechanism is about 2x
as fast as const_given? now and about 150x faster than it was.

Ultimately, we need much cleaner mechanisms for how we access constants
or chains of constants so we can control: access Object, public/private,
autoload, and const_missing.  All of these are dimensions of access
which sometimes defined? wants and sometimes regular searches want.
enebo committed Jul 15, 2016
1 parent 19b74b2 commit 5ff8bd1
Showing 1 changed file with 17 additions and 5 deletions.
22 changes: 17 additions & 5 deletions core/src/main/java/org/jruby/ir/IRBuilder.java
Original file line number Diff line number Diff line change
@@ -1528,12 +1528,24 @@ public Operand buildGetDefinition(Node node) {

CodeBlock protectedCode = new CodeBlock() {
public Operand run() {
Operand v = colon instanceof Colon2Node ?
build(((Colon2Node)colon).getLeftNode()) : new ObjectClass();
if (!(colon instanceof Colon2Node)) { // colon3 (weird inheritance)
return addResultInstr(new RuntimeHelperCall(createTemporaryVariable(),
IS_DEFINED_CONSTANT_OR_METHOD, new Operand[] {new ObjectClass(), new FrozenString(name)}));
}

Variable tmpVar = createTemporaryVariable();
addInstr(new RuntimeHelperCall(tmpVar, IS_DEFINED_CONSTANT_OR_METHOD, new Operand[] {v, new FrozenString(name)}));
return tmpVar;
Label bad = getNewLabel();
Label done = getNewLabel();
Variable result = createTemporaryVariable();
Operand test = buildGetDefinition(((Colon2Node) colon).getLeftNode());
addInstr(BEQInstr.create(test, manager.getNil(), bad));
Operand lhs = build(((Colon2Node) colon).getLeftNode());
addInstr(new RuntimeHelperCall(result, IS_DEFINED_CONSTANT_OR_METHOD, new Operand[] {lhs, new FrozenString(name)}));
addInstr(new JumpInstr(done));
addInstr(new LabelInstr(bad));
addInstr(new CopyInstr(result, manager.getNil()));
addInstr(new LabelInstr(done));

return result;
}
};

0 comments on commit 5ff8bd1

Please sign in to comment.