Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into truffle-head
- Loading branch information
Showing
72 changed files
with
1,974 additions
and
1,503 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
100 changes: 100 additions & 0 deletions
100
core/src/main/java/org/jruby/ir/passes/OptimizeDelegationPass.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package org.jruby.ir.passes; | ||
|
||
import org.jruby.ir.IRClosure; | ||
import org.jruby.ir.IRScope; | ||
import org.jruby.ir.IRFlags; | ||
import org.jruby.ir.instructions.*; | ||
import org.jruby.ir.operands.Operand; | ||
import org.jruby.ir.operands.Variable; | ||
import org.jruby.ir.representations.BasicBlock; | ||
|
||
import java.util.*; | ||
|
||
public class OptimizeDelegationPass extends CompilerPass { | ||
public static List<Class<? extends CompilerPass>> DEPENDENCIES = Arrays.<Class<? extends CompilerPass>>asList(CFGBuilder.class); | ||
|
||
@Override | ||
public String getLabel() { | ||
return "Delegated Variable Removal"; | ||
} | ||
|
||
@Override | ||
public List<Class<? extends CompilerPass>> getDependencies() { | ||
return DEPENDENCIES; | ||
} | ||
|
||
@Override | ||
public Object execute(IRScope s, Object... data) { | ||
for (IRClosure c: s.getClosures()) { | ||
run(c, false, true); | ||
} | ||
|
||
s.computeScopeFlags(); | ||
|
||
if (s.getFlags().contains(IRFlags.BINDING_HAS_ESCAPED)) | ||
return null; | ||
|
||
if (!s.getFlags().contains(IRFlags.RECEIVES_CLOSURE_ARG)) | ||
return null; | ||
|
||
optimizeDelegatedVars(s); | ||
|
||
return true; | ||
} | ||
|
||
@Override | ||
public boolean invalidate(IRScope s) { | ||
// Not reversible right now | ||
return false; | ||
} | ||
|
||
private static void optimizeDelegatedVars(IRScope s) { | ||
Map<Operand, Operand> unusedExplicitBlocks = new HashMap<Operand, Operand>(); | ||
|
||
for (BasicBlock bb: s.cfg().getBasicBlocks()) { | ||
for (Instr i: bb.getInstrs()) { | ||
if (i instanceof ReifyClosureInstr) { | ||
ReifyClosureInstr ri = (ReifyClosureInstr) i; | ||
unusedExplicitBlocks.put(ri.getResult(), ri.getSource()); | ||
} else { | ||
Iterator<Operand> it = unusedExplicitBlocks.keySet().iterator(); | ||
while (it.hasNext()) { | ||
Variable explicitBlock = (Variable) it.next(); | ||
if (usesVariableAsNonClosureArg(i, explicitBlock)) { | ||
it.remove(); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
for (BasicBlock bb: s.cfg().getBasicBlocks()) { | ||
ListIterator<Instr> instrs = bb.getInstrs().listIterator(); | ||
while (instrs.hasNext()) { | ||
Instr i = instrs.next(); | ||
if (i instanceof ReifyClosureInstr) { | ||
ReifyClosureInstr ri = (ReifyClosureInstr) i; | ||
Variable procVar = ri.getResult(); | ||
Operand blockVar = unusedExplicitBlocks.get(procVar); | ||
|
||
if (blockVar != null) { | ||
ri.markDead(); | ||
instrs.set(new CopyInstr(procVar, blockVar)); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
private static boolean usesVariableAsNonClosureArg(Instr i, Variable v) { | ||
List<Variable> usedVariables = i.getUsedVariables(); | ||
if (usedVariables.contains(v)) { | ||
if (i instanceof ClosureAcceptingInstr) { | ||
return usedVariables.indexOf(v) != usedVariables.lastIndexOf(v) || | ||
v != ((ClosureAcceptingInstr) i).getClosureArg(); | ||
} else | ||
return true; | ||
} | ||
return false; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Provided by default |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
# code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
# redistribute it and/or modify it under the terms of the: | ||
# | ||
# Eclipse Public License version 1.0 | ||
# GNU General Public License version 2 | ||
# GNU Lesser General Public License version 2.1 | ||
|
||
# Empty thread file - everything is loaded by default at the moment |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# https://github.com/jruby/jruby/issues/2574 | ||
describe 'Local variable assignments should not get clobbered' do | ||
it 'returns the right value for array literals' do | ||
a = 0 | ||
b = [a,a=1] | ||
expect(b).to eq([0,1]) | ||
end | ||
|
||
it 'returns the right value for hash literals' do | ||
a = 0 | ||
b = { a => a, (a = 1) => a } # => { 1 => 1 } (MRI: {0=>0, 1=>1}) | ||
c = { a => a, a => (a = 2) } # => { 2 => 2 } (MRI: {1=>2}) | ||
expect(b).to eq({0=>0, 1=>1}) | ||
expect(c).to eq({1=>2}) | ||
end | ||
end | ||
|
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,5 @@ | ||
fails:Array#flatten returns a one-dimensional flattening recursively | ||
fails:Array#flatten takes an optional argument that determines the level of recursion | ||
fails:Array#flatten returns dup when the level of recursion is 0 | ||
fails:Array#flatten ignores negative levels | ||
fails:Array#flatten tries to convert passed Objects to Integers using #to_int | ||
fails:Array#flatten raises a TypeError when the passed Object can't be converted to an Integer | ||
fails:Array#flatten does not call flatten on elements | ||
fails:Array#flatten raises an ArgumentError on recursive arrays | ||
fails:Array#flatten flattens any element which responds to #to_ary, using the return value of said method | ||
fails:Array#flatten returns subclass instance for Array subclasses | ||
fails:Array#flatten returns a tainted array if self is tainted | ||
fails:Array#flatten returns an untrusted array if self is untrusted | ||
fails:Array#flatten with a non-Array object in the Array ignores the return value of #to_ary if it is nil | ||
fails:Array#flatten with a non-Array object in the Array raises a TypeError if the return value of #to_ary is not an Array | ||
fails:Array#flatten! modifies array to produce a one-dimensional flattening recursively | ||
fails:Array#flatten! returns self if made some modifications | ||
fails:Array#flatten! returns nil if no modifications took place | ||
fails:Array#flatten! should not check modification by size | ||
fails:Array#flatten! takes an optional argument that determines the level of recursion | ||
fails:Array#flatten! returns nil when the level of recursion is 0 | ||
fails:Array#flatten! treats negative levels as no arguments | ||
fails:Array#flatten! tries to convert passed Objects to Integers using #to_int | ||
fails:Array#flatten! raises a TypeError when the passed Object can't be converted to an Integer | ||
fails:Array#flatten! does not call flatten! on elements | ||
fails:Array#flatten! raises an ArgumentError on recursive arrays | ||
fails:Array#flatten! flattens any elements which responds to #to_ary, using the return value of said method | ||
fails:Array#flatten! raises a RuntimeError on frozen arrays when the array is modified | ||
fails:Array#flatten! raises a RuntimeError on frozen arrays when the array would not be modified |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,2 @@ | ||
fails:Array#& creates an array with no duplicates | ||
fails:Array#& creates an array with elements in order they are first encountered | ||
fails:Array#& properly handles recursive arrays | ||
fails:Array#& determines equivalence between elements in the sense of eql? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1 @@ | ||
fails:Array#- tries to convert the passed arguments to Arrays using #to_ary | ||
fails:Array#- does not return subclass instance for Array subclasses | ||
fails:Array#- does not call to_ary on array subclasses | ||
fails:Array#- removes an item identified as equivalent via #hash and #eql? | ||
fails:Array#- doesn't remove an item with the same hash but not #eql? | ||
fails:Array#- properly handles recursive arrays |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.