Skip to content

Commit

Permalink
Showing 13 changed files with 162 additions and 131 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -40,7 +40,7 @@ For [`rbenv`](https://github.com/sstephenson/rbenv) you will need the
package manager can provide these. Then you can run:

```
$ rbenv install jruby-9.0.5.0
$ rbenv install jruby-9.1.2.0
```

For [`rvm`](https://rvm.io) you can simply do:
77 changes: 0 additions & 77 deletions bin/jruby-cext-c

This file was deleted.

5 changes: 3 additions & 2 deletions ci.hocon
Original file line number Diff line number Diff line change
@@ -264,7 +264,7 @@ test-cexts: {
downloads: {
JVMCI_JAVA_HOME: {
name: labsjdk,
version: "8u92-jvmci-0.16",
version: "8u92-jvmci-0.17",
platformspecific: true
}
}
@@ -279,7 +279,8 @@ test-cexts: {
[mx, --java-home, "$JVMCI_JAVA_HOME", build],
[cd, ../..],
[mv, temp_mx, mx.jruby]
[mx, sclone, --kind, git, "https://github.com/jruby/jruby-truffle-gem-test-pack.git", jruby-truffle-gem-test-pack]
[mx, sclone, --kind, git, "https://github.com/jruby/jruby-truffle-gem-test-pack.git", jruby-truffle-gem-test-pack],
${jt} [build, cexts]
]

environment: {
Binary file removed lib/ruby/truffle/cext/ruby.su
Binary file not shown.
2 changes: 1 addition & 1 deletion spec/ruby/optional/capi/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -110,7 +110,7 @@ def compile_extension_jruby_truffle(name)
f.puts "out: #{output_file}"
end

system "#{RbConfig::CONFIG['bindir']}/jruby", "#{RbConfig::CONFIG['bindir']}/jruby-cext-c", extension_path
system "#{RbConfig::CONFIG['bindir']}/jruby", "#{RbConfig::CONFIG['bindir']}/../tool/jt.rb", 'cextc', extension_path

output_file
ensure
1 change: 0 additions & 1 deletion spec/truffle/tags/core/array/element_set_tags.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
fails:Array#[]= sets elements in the range arguments when passed ranges
fails:Array#[]= calls to_ary on its rhs argument for multi-element sets
1 change: 0 additions & 1 deletion spec/truffle/tags/core/array/hash_tags.txt

This file was deleted.

57 changes: 29 additions & 28 deletions spec/truffle/truffle.mspec
Original file line number Diff line number Diff line change
@@ -27,34 +27,6 @@ class MSpecScript
set :flags, flags
end

set :capi, [
"spec/ruby/optional/capi",

# Incorrect C code for spec?
"^spec/ruby/optional/capi/data_spec.rb",

# Requires 'ruby/encoding.h'
"^spec/ruby/optional/capi/encoding_spec.rb",

# Requires 'ruby/io.h'
"^spec/ruby/optional/capi/io_spec.rb",

# Incorrect C code for spec?
"^spec/ruby/optional/capi/proc_spec.rb",

# Requires 'ruby/re.h'
"^spec/ruby/optional/capi/regexp_spec.rb",

# Requires 'ruby/intern.h'
"^spec/ruby/optional/capi/struct_spec.rb",

# Requires 'ruby/thread.h'
"^spec/ruby/optional/capi/thread_spec.rb",

# Missing symbol @Init_typed_data_spec.
"^spec/ruby/optional/capi/typed_data_spec.rb"
]

set :command_line, [
"spec/ruby/command_line"
]
@@ -104,6 +76,35 @@ class MSpecScript
]

set :capi, [
"spec/ruby/optional/capi",

# Fixnum boundaries do not match
"^spec/ruby/optional/capi/bignum_spec.rb",

# Incorrect C code for spec?
"^spec/ruby/optional/capi/data_spec.rb",

# Requires 'ruby/encoding.h'
"^spec/ruby/optional/capi/encoding_spec.rb",

# Requires 'ruby/io.h'
"^spec/ruby/optional/capi/io_spec.rb",

# Requires 'ruby/re.h'
"^spec/ruby/optional/capi/regexp_spec.rb",

# Requires 'ruby/intern.h'
"^spec/ruby/optional/capi/struct_spec.rb",

# Requires 'ruby/thread.h'
"^spec/ruby/optional/capi/thread_spec.rb",

# Missing symbol @Init_typed_data_spec.
"^spec/ruby/optional/capi/typed_data_spec.rb"
]

# A subset of the C-API with passing specs for development
set :capi_dev, [
"spec/ruby/optional/capi/array_spec.rb",
"spec/ruby/optional/capi/class_spec.rb",
"spec/ruby/optional/capi/module_spec.rb",
68 changes: 61 additions & 7 deletions tool/jt.rb
Original file line number Diff line number Diff line change
@@ -16,11 +16,13 @@
require 'fileutils'
require 'json'
require 'timeout'
require 'yaml'

GRAALVM_VERSION = '0.12'

JRUBY_DIR = File.expand_path('../..', __FILE__)
M2_REPO = File.expand_path('~/.m2/repository')
SULONG_DIR = ENV['SULONG_DIR']

JDEBUG_PORT = 51819
JDEBUG = "-J-agentlib:jdwp=transport=dt_socket,server=y,address=#{JDEBUG_PORT},suspend=y"
@@ -307,6 +309,13 @@ def maven_options(*options)
end
return [maven_options, options]
end

def mx(dir, *args)
command = ['mx', '-p', dir]
command.push *['--java-home', ENV['JVMCI_JAVA_HOME']] if ENV['JVMCI_JAVA_HOME']
command.push *args
sh *command
end

def mspec(command, *args)
env_vars = {}
@@ -330,8 +339,9 @@ def help
puts 'jt checkout name checkout a different Git branch and rebuild'
puts 'jt bootstrap [options] run the build system\'s bootstrap phase'
puts 'jt build [options] build'
puts 'jt build truffle [options] build only the Truffle part, assumes the rest is up-to-date'
puts 'jt rebuild [options] clean and build'
puts ' truffle build only the Truffle part, assumes the rest is up-to-date'
puts ' cexts build the cext backend (set SULONG_DIR and mabye USE_SYSTEM_CLANG)'
puts ' --offline use the build pack to build offline'
puts 'jt clean clean'
puts 'jt irb irb'
@@ -348,7 +358,8 @@ def help
puts ' --exec use exec rather than system'
puts 'jt e 14 + 2 evaluate an expression'
puts 'jt puts 14 + 2 evaluate and print an expression'
puts 'jt test run all mri tests, specs and integration tests'
puts 'jt cextc directory clang-args compile the C extension in directory, with optional extra clang arguments'
puts 'jt test run all mri tests, specs and integration tests (set SULONG_DIR, and maybe USE_SYSTEM_CLANG)'
puts 'jt test tck [--jdebug] run the Truffle Compatibility Kit tests'
puts 'jt test mri run mri tests'
puts 'jt test specs run all specs'
@@ -393,7 +404,8 @@ def help
puts ' JVMCI_JAVA_HOME The Java with JVMCI to use with GRAAL_HOME'
puts ' GRAALVM_RELEASE_BIN Default GraalVM executable when using a released version of Truffle (such as on master)'
puts ' GRAAL_HOME_TRUFFLE_HEAD Default Graal directory when using a snapshot version of Truffle (such as on truffle-head)'
puts ' SULONG_DIR The Sulong source repository, if you want to run bin/jruby-cext-c'
puts ' SULONG_DIR The Sulong source repository, if you want to run cextc'
puts ' USE_SYSTEM_CLANG Use the system clang rather than Sulong\'s when compiling C extensions'
puts ' GRAAL_JS_JAR The location of trufflejs.jar'
puts ' SL_JAR The location of truffle-sl.jar'
end
@@ -415,6 +427,8 @@ def build(*options)
case project
when 'truffle'
mvn env, *maven_options, '-pl', 'truffle', 'package'
when 'cexts'
cextc "#{JRUBY_DIR}/truffle/src/main/c/cext"
when nil
mvn env, *maven_options, 'package'
else
@@ -520,6 +534,45 @@ def command_puts(*args)
def command_p(*args)
e 'p begin', *args, 'end'
end

def cextc(cext_dir, *clang_opts)
config_file = File.join(cext_dir, '.jruby-cext-build.yml')

unless File.exist?(config_file)
abort "There is no .jruby-cext-build.yml in #{cext_dir} at the moment - I don't know how to build it"
end

config = YAML.load_file(config_file)
config_src = config['src']

if config_src.start_with?('$GEM_HOME/')
src = Dir[ENV['GEM_HOME'] + config_src['$GEM_HOME'.size..-1]]
else
src = Dir[File.join(cext_dir, config_src)]
end

out = File.expand_path(config['out'], cext_dir)
lls = []

src.each do |src|
ll = File.join(File.dirname(out), File.basename(src, '.*') + '.ll')

clang_args = ["-I#{SULONG_DIR}/include", '-Ilib/ruby/truffle/cext', '-S', '-emit-llvm', *clang_opts, src, '-o', ll]
opt_args = ['-S', '-mem2reg', ll, '-o', ll]

if ENV['USE_SYSTEM_CLANG']
sh 'clang', *clang_args
sh 'opt', *opt_args
else
mx SULONG_DIR, 'su-clang', *clang_args
mx SULONG_DIR, 'su-opt', *opt_args
end

lls.push ll
end

mx SULONG_DIR, 'su-link', '-o', out, *lls
end

def test(*args)
path, *rest = args
@@ -606,7 +659,7 @@ def test_cexts(*args)
output_file = 'cext-output.txt'
['minimum', 'method', 'module'].each do |gem_name|
dir = "#{JRUBY_DIR}/test/truffle/cexts/#{gem_name}"
sh Utilities.find_jruby, "#{JRUBY_DIR}/bin/jruby-cext-c", dir
cextc dir
name = File.basename(dir)
run '--graal', '-I', "#{dir}/lib", "#{dir}/bin/#{name}", :out => output_file
unless File.read(output_file) == File.read("#{dir}/expected.txt")
@@ -622,7 +675,7 @@ def test_cexts(*args)
['psd_native', ['chunky_png-1.3.6', 'oily_png-1.2.0', 'bindata-2.3.1', 'hashie-3.4.4', 'psd-enginedata-1.1.1', 'psd-2.1.2', 'psd_native-1.1.3'], ['oily_png', 'psd_native']]
].each do |gem_name, dependencies, libs|
config = "#{JRUBY_DIR}/test/truffle/cexts/#{gem_name}"
sh Utilities.find_jruby, "#{JRUBY_DIR}/bin/jruby-cext-c", config, '-Werror=implicit-function-declaration'
cextc config, '-Werror=implicit-function-declaration'
arguments = []
run '--graal',
*(dependencies.map { |d| ['-I', "#{ENV['GEM_HOME']}/gems/#{d}/lib"] }.flatten),
@@ -1027,8 +1080,9 @@ def main(args)
send(args.shift)
when "build"
command = [args.shift]
command << args.shift if args.first == "truffle"
command << args.shift if args.first == "--offline"
while ['truffle', 'cexts', '--offline'].include?(args.first)
command << args.shift
end
send(*command)
end

10 changes: 0 additions & 10 deletions truffle/src/main/c/cext/README.md

This file was deleted.

Original file line number Diff line number Diff line change
@@ -31,6 +31,7 @@
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.runtime.Helpers;
import org.jruby.truffle.Layouts;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.builtins.CoreClass;
@@ -88,8 +89,10 @@
import org.jruby.truffle.language.objects.TaintNodeGen;
import org.jruby.truffle.language.yield.YieldNode;
import org.jruby.util.Memo;

import java.util.Arrays;
import java.util.Comparator;

import static org.jruby.truffle.core.array.ArrayHelpers.createArray;
import static org.jruby.truffle.core.array.ArrayHelpers.getSize;
import static org.jruby.truffle.core.array.ArrayHelpers.getStore;
@@ -461,6 +464,15 @@ public Object setOtherArray(VirtualFrame frame, DynamicObject array, int rawStar
for (int i = 0; i < tailSize; i++) {
write(array, endOfReplacementInArray + i, read(tailCopy, i));
}
} else {
// If no tail, array will grow, and the replacement is empty,
// we need to append nils from index arraySize to index (start - 1).
// E.g. a = [1,2,3]; a[5,1] = []; a == [1,2,3,nil,nil]
if(replacementSize == 0 && arraySize < start){
for(int i = arraySize; i < start; i++){
write(array, i, nil());
}
}
}

// Set size
@@ -852,7 +864,6 @@ public Object eachOther(VirtualFrame frame, DynamicObject array, DynamicObject b
public abstract static class EachWithIndexNode extends YieldingCoreMethodNode {

@Specialization(guards = "isNullArray(array)")

public DynamicObject eachWithIndexNull(DynamicObject array, DynamicObject block) {
return array;
}
@@ -911,6 +922,53 @@ protected Object fillFallback(VirtualFrame frame, DynamicObject array, Object[]

}

@CoreMethod(names = "hash_internal")
public abstract static class HashNode extends ArrayCoreMethodNode {

@Child private ToIntNode toIntNode;

@Specialization(guards = "isNullArray(array)")
public long hashNull(DynamicObject array) {
final int size = 0;
long h = Helpers.hashStart(getContext().getJRubyRuntime(), size);
h = Helpers.murmurCombine(h, System.identityHashCode(ArrayNodes.class));
return Helpers.hashEnd(h);
}

@Specialization(guards = "strategy.matches(array)", limit = "ARRAY_STRATEGIES")
public long hash(VirtualFrame frame, DynamicObject array,
@Cached("of(array)") ArrayStrategy strategy,
@Cached("createMethodCall()") CallDispatchHeadNode toHashNode) {
final int size = getSize(array);
// TODO BJF Jul 4, 2016 Seed could be chosen in advance to avoid branching
long h = Helpers.hashStart(getContext().getJRubyRuntime(), size);
h = Helpers.murmurCombine(h, System.identityHashCode(ArrayNodes.class));
final ArrayMirror store = strategy.newMirror(array);

for (int n = 0; n < size; n++) {
final Object value = store.get(n);
final long valueHash = toLong(frame, toHashNode.call(frame, value, "hash", null));
h = Helpers.murmurCombine(h, valueHash);
}

return Helpers.hashEnd(h);
}

private long toLong(VirtualFrame frame, Object indexObject) {
if (toIntNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
toIntNode = insert(ToIntNode.create());
}
final Object result = toIntNode.executeIntOrLong(frame, indexObject);
if (result instanceof Integer) {
return (long) (int) result;
} else {
return (long) result;
}
}

}

@CoreMethod(names = "include?", required = 1)
public abstract static class IncludeNode extends ArrayCoreMethodNode {

Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@
import org.jruby.truffle.RubyLanguage;
import org.jruby.truffle.core.array.ArrayOperations;
import org.jruby.truffle.language.control.JavaException;
import org.jruby.truffle.language.control.RaiseException;

public class FeatureLoader {

@@ -130,6 +131,11 @@ public void ensureCExtImplementationLoaded(VirtualFrame frame, IndirectCallNode
@TruffleBoundary
private CallTarget getCExtLibRuby() {
final String path = context.getJRubyRuntime().getJRubyHome() + "/lib/ruby/truffle/cext/ruby.su";

if (!new File(path).exists()) {
throw new RaiseException(context.getCoreExceptions().internalError("This JRuby distribution does not have the C extension implementation file ruby.su", null));
}

try {
return parseSource(context.getSourceLoader().load(path));
} catch (IOException e) {
4 changes: 2 additions & 2 deletions truffle/src/main/ruby/core/array.rb
Original file line number Diff line number Diff line change
@@ -460,7 +460,7 @@ def hash
begin
objects[id] = true

each { |x| hash_val = ((hash_val & mask) << 1) ^ x.hash }
hash_val = self.hash_internal
ensure
objects.delete id
end
@@ -472,7 +472,7 @@ def hash
objects[:__detect_outermost_recursion__] = true
objects[id] = true

each { |x| hash_val = ((hash_val & mask) << 1) ^ x.hash }
hash_val = self.hash_internal

# An inner version will raise to return back here, indicating that
# the whole structure is recursive. In which case, abondon most of

0 comments on commit 31477c7

Please sign in to comment.