Skip to content

Commit

Permalink
[Truffle] Added a new internal method for taking ownership of an arra…
Browse files Browse the repository at this point in the history
…y store from another array.

This is intended to be a faster version of Array#replace when we know that the source array won't be used anywhere else.
nirvdrum committed May 27, 2016
1 parent ff0d735 commit c36096b
Showing 3 changed files with 58 additions and 8 deletions.
3 changes: 3 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/core/CoreLibrary.java
Original file line number Diff line number Diff line change
@@ -33,6 +33,7 @@
import org.jruby.truffle.builtins.CoreMethodNodeManager;
import org.jruby.truffle.core.array.ArrayNodes;
import org.jruby.truffle.core.array.ArrayNodesFactory;
import org.jruby.truffle.core.array.TruffleArrayNodesFactory;
import org.jruby.truffle.core.basicobject.BasicObjectNodesFactory;
import org.jruby.truffle.core.binding.BindingNodesFactory;
import org.jruby.truffle.core.binding.TruffleBindingNodesFactory;
@@ -585,6 +586,7 @@ public CoreLibrary(RubyContext context) {
defineModule(truffleModule, "Graal");
defineModule(truffleModule, "Ropes");
defineModule(truffleModule, "GC");
defineModule(truffleModule, "Array");
final DynamicObject attachments = defineModule(truffleModule, "Attachments");
defineModule(attachments, "Internal");
defineModule(truffleModule, "Boot");
@@ -758,6 +760,7 @@ public void addCoreMethods() {
coreMethodNodeManager.addCoreMethodNodes(TruffleProcessNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(TruffleDebugNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(TruffleBindingNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(TruffleArrayNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(BCryptNodesFactory.getFactories());

coreMethodNodeManager.allMethodInstalled();
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2016 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
*/
package org.jruby.truffle.core.array;

import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.object.DynamicObject;
import org.jruby.truffle.builtins.CoreClass;
import org.jruby.truffle.builtins.CoreMethod;
import org.jruby.truffle.builtins.CoreMethodArrayArgumentsNode;

import static org.jruby.truffle.core.array.ArrayHelpers.getSize;
import static org.jruby.truffle.core.array.ArrayHelpers.getStore;
import static org.jruby.truffle.core.array.ArrayHelpers.setStoreAndSize;

@CoreClass("Truffle::Array")
public class TruffleArrayNodes {

@CoreMethod(names = "take_ownership_of_store", onSingleton = true, required = 2)
public abstract static class TakeOwnershipOfStoreNode extends CoreMethodArrayArgumentsNode {

@Specialization(guards = "array == other")
public DynamicObject takeOwnershipOfStoreNoOp(DynamicObject array, DynamicObject other) {
return array;
}

@Specialization(guards = { "array != other", "isRubyArray(other)" })
public DynamicObject takeOwnershipOfStore(DynamicObject array, DynamicObject other) {
final int size = getSize(other);
final Object store = getStore(other);
setStoreAndSize(array, store, size);
setStoreAndSize(other, null, 0);

return array;
}

}

}
18 changes: 10 additions & 8 deletions truffle/src/main/ruby/core/array.rb
Original file line number Diff line number Diff line change
@@ -811,7 +811,7 @@ def flatten!(level=-1)

out = new_reserved size
if recursively_flatten(self, out, level)
replace(out)
Truffle::Array.take_ownership_of_store(self, out)
return self
end

@@ -987,7 +987,7 @@ def keep_if(&block)

Truffle.check_frozen

replace select(&block)
Truffle::Array.take_ownership_of_store(self, select(&block))
end

def last(n=undefined)
@@ -1337,7 +1337,7 @@ def rotate!(cnt=1)
return self if length == 0 || length == 1

ary = rotate(cnt)
replace ary
Truffle::Array.take_ownership_of_store(self, ary)
end

class SampleRandom
@@ -1467,7 +1467,7 @@ def select!(&block)
Truffle.check_frozen

ary = select(&block)
replace ary unless size == ary.size
Truffle::Array.take_ownership_of_store(self, ary) unless size == ary.size
end

def set_index(index, ent, fin=undefined)
@@ -1748,7 +1748,7 @@ def sort_by!(&block)

return to_enum(:sort_by!) { size } unless block_given?

replace sort_by(&block)
Truffle::Array.take_ownership_of_store(self, sort_by(&block))
end

# Sorts this Array in-place. See #sort.
@@ -2044,7 +2044,7 @@ def mergesort!
width *= 2
end

replace(source) if source != self
Truffle::Array.take_ownership_of_store(self, source)

self
end
@@ -2108,7 +2108,7 @@ def mergesort_block!(block)
width *= 2
end

replace(source) if source != self
Truffle::Array.take_ownership_of_store(self, source)

self
end
@@ -2397,7 +2397,9 @@ def element_reference_fallback(method_name, args)
end

def sort!(&block)
replace sort(&block)
Truffle.check_frozen

Truffle::Array.take_ownership_of_store(self, sort(&block))
end
public :sort!
end

0 comments on commit c36096b

Please sign in to comment.