Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 08f18038f049
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 03fb36a49eed
Choose a head ref
  • 7 commits
  • 9 files changed
  • 1 contributor

Commits on Jul 2, 2016

  1. Copy the full SHA
    04625e1 View commit details
  2. Copy the full SHA
    e6fe2e8 View commit details

Commits on Jul 3, 2016

  1. Copy the full SHA
    f0d8f65 View commit details
  2. 4
    Copy the full SHA
    1156a26 View commit details
  3. Copy the full SHA
    9bf37ca View commit details
  4. Copy the full SHA
    3e292b4 View commit details
  5. Copy the full SHA
    03fb36a View commit details
33 changes: 20 additions & 13 deletions bin/jruby-cext-c
Original file line number Diff line number Diff line change
@@ -19,35 +19,42 @@ unless SULONG_DIR
end

def mx(command, *args)
command = "mx -p #{SULONG_DIR} --vm server #{command} #{args.join(' ')}"
command = "mx -p #{SULONG_DIR} #{command} #{args.join(' ')}"
puts "$ #{command}"
`#{command}`
end

CEXT_DIR = ARGV[0]
cext_dir = ARGV[0]

unless CEXT_DIR
unless cext_dir
abort 'You need to pass the directory of a C extension so I can build it'
end

CONFIG_FILE = File.join(CEXT_DIR, '.jruby-cext-build.yml')
config_file = File.join(cext_dir, '.jruby-cext-build.yml')

unless File.exist?(CONFIG_FILE)
unless File.exist?(config_file)
abort "There is no .jruby-cext-build.yml in this C extension at the moment - I don't know how to build it"
end

CONFIG = YAML.load_file(CONFIG_FILE)
config = YAML.load_file(config_file)

SRC = Dir[File.join(CEXT_DIR, CONFIG['src'])]
OUT = File.expand_path(CONFIG['out'], CEXT_DIR)
config_src = config['src']

LL = []
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')
src.each do |src|
ll = File.join(File.dirname(out), File.basename(src, '.*') + '.ll')
mx 'su-clang', "-I#{SULONG_DIR}/include", '-Ilib/ruby/truffle/cext', '-S', '-emit-llvm', src, '-o', ll
mx 'su-opt', '-S', '-mem2reg', ll, '-o', ll
LL.push ll
lls.push ll
end

mx 'su-link', '-o', OUT, *LL
mx 'su-link', '-o', out, *lls
20 changes: 15 additions & 5 deletions ci.hocon
Original file line number Diff line number Diff line change
@@ -230,6 +230,20 @@ server-benchmarks: {
] ${post-process-and-upload-results}
}

test-gems: {
environment: {
GEM_HOME: jruby-truffle-gem-test-pack/gems
}

setup: ${common-setup} [
[mx, sclone, --kind, git, "https://github.com/jruby/jruby-truffle-gem-test-pack.git", jruby-truffle-gem-test-pack]
]

run: [
${jt} [test, gems]
]
}

builds: [
{name: ruby-test-fast} ${common} ${gate-caps} {run: [${jt} [test, fast]]},
{name: ruby-test-specs-command-line} ${common} ${gate-caps} {run: [${jt} [test, specs, ":command_line"]]},
@@ -238,11 +252,7 @@ builds: [
{name: ruby-test-specs-library} ${common} ${gate-caps} {run: [${jt} [test, specs, ":library"]]},
{name: ruby-test-specs-truffle} ${common} ${gate-caps} {run: [${jt} [test, specs, ":truffle"]]},
{name: ruby-test-integration} ${common} ${gate-caps} {run: [${jt} [test, integration]]},
{name: ruby-test-gems} ${common} ${gate-caps} {
setup: ${common-setup} [[mx, sclone, --kind, git, "https://github.com/jruby/jruby-truffle-gem-test-pack.git", jruby-truffle-gem-test-pack]]
environment: {GEM_HOME: jruby-truffle-gem-test-pack/gems}
run: [${jt} [test, gems]]
},
{name: ruby-test-gems} ${common} ${gate-caps} ${test-gems},
{name: ruby-test-tck} ${common} ${gate-caps} {run: [${jt} [test, tck]]},
{name: ruby-test-tarball} ${common} ${gate-caps} {run: [${jt} [tarball]]},

2 changes: 2 additions & 0 deletions test/truffle/cexts/oily_png/.jruby-cext-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
src: $GEM_HOME/gems/oily_png-1.2.0/ext/oily_png/*.c
out: lib/oily_png/oily_png.su
Empty file.
2 changes: 2 additions & 0 deletions test/truffle/cexts/psd_native/.jruby-cext-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
src: $GEM_HOME/gems/psd_native-1.1.3/ext/psd_native/*.c
out: lib/psd_native/psd_native.su
Empty file.
88 changes: 28 additions & 60 deletions tool/jt.rb
Original file line number Diff line number Diff line change
@@ -73,27 +73,21 @@ def self.find_graal_javacmd_and_options
vm_args = command_line.split
vm_args.pop # Drop "-version"
javacmd = vm_args.shift
if Dir.exist?(File.join(graal_home, 'mx.sulong'))
sulong_dependencies = File.join(graal_home, 'lib', '*')
sulong_jar = File.join(graal_home, 'build', 'sulong.jar')
nfi_classes = File.join(graal_home, '../graal-core/mxbuild/graal/com.oracle.nfi/bin')
vm_args << '-cp'
vm_args << [nfi_classes, sulong_dependencies, sulong_jar].join(':')
vm_args << '-XX:-UseJVMCIClassLoader'
end
options = vm_args.map { |arg| "-J#{arg}" }
else
raise 'set one of GRAALVM_BIN or GRAAL_HOME in order to use Graal'
end
[javacmd, options]
end

def self.find_sulong_graal(dir)
searches = [
"#{dir}/../jvmci/jdk*/product/bin/java",
"#{dir}/../graal-core/mx.imports/binary/jvmci/jdk*/product/bin/java"
].map { |path| File.expand_path(path) }

searches.each do |search|
java = Dir[search].first
return java if java
end

raise "couldn't find the Java build in the Sulong repository - you need to check it out and build it"
end

def self.find_graal_js
jar = ENV['GRAAL_JS_JAR']
return jar if jar
@@ -106,12 +100,6 @@ def self.find_sl
raise "couldn't find truffle-sl.jar - build Truffle and find it in there"
end

def self.find_sulong_dir
dir = ENV['SULONG_DIR']
return dir if dir
raise "couldn't find the Sulong repository - you need to check it out and build it"
end

def self.jruby_eclipse?
# tool/jruby_eclipse only works on release currently
ENV["JRUBY_ECLIPSE"] == "true" and !truffle_version.end_with?('SNAPSHOT')
@@ -356,7 +344,6 @@ def help
puts 'jt run [options] args... run JRuby with -X+T and args'
puts ' --graal use Graal (set either GRAALVM_BIN or GRAAL_HOME and maybe JVMCI_JAVA_HOME)'
puts ' --js add Graal.js to the classpath (set GRAAL_JS_JAR)'
puts ' --sulong add Sulong to the classpath (set SULONG_DIR, implies --graal but finds it from the SULONG_DIR)'
puts ' --asm show assembly (implies --graal)'
puts ' --server run an instrumentation server on port 8080'
puts ' --igv make sure IGV is running and dump Graal graphs after partial escape (implies --graal)'
@@ -379,7 +366,8 @@ def help
puts 'jt test integration TESTS runs the given integration tests'
puts 'jt test gems tests using gems'
puts 'jt test ecosystem tests using the wider ecosystem such as bundler, Rails, etc'
puts 'jt test cexts run C extension tests (set SULONG_DIR)'
puts 'jt test cexts run C extension tests'
puts ' (implies --graal, where Graal needs to include Sulong, and set SULONG_DIR to a built checkout of Sulong)'
puts 'jt test report :language build a report on language specs'
puts ' :core (results go into test/target/mspec-html-report)'
puts ' :library'
@@ -410,10 +398,9 @@ 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 ' GRAAL_JS_JAR The location of trufflejs.jar'
puts ' SL_JAR The location of truffle-sl.jar'
puts ' SULONG_DIR The location of a built checkout of the Sulong repository'
puts ' SULONG_CLASSPATH An explicit classpath to use for Sulong, rather than working it out from SULONG_DIR'
end

def checkout(branch)
@@ -486,10 +473,6 @@ def run(*args)
jruby_args << Utilities.find_graal_js
end

if args.delete('--sulong')
collect_sulong_args(env_vars, jruby_args)
end

if args.delete('--asm')
jruby_args += %w[-J-XX:+UnlockDiagnosticVMOptions -J-XX:CompileCommand=print,*::callRoot]
end
@@ -553,7 +536,7 @@ def test(*args)
test_gems
test_ecosystem 'HAS_REDIS' => 'true'
test_compiler
test_cexts if ENV['SULONG_DIR']
test_cexts
when 'compiler' then test_compiler(*rest)
when 'cexts' then test_cexts(*rest)
when 'report' then test_report(*rest)
@@ -622,17 +605,24 @@ def test_compiler(*args)
private :test_compiler

def test_cexts(*args)
output_file = 'cext-output.txt'
Dir["#{JRUBY_DIR}/test/truffle/cexts/*"].each do |dir|
sh Utilities.find_jruby, "#{JRUBY_DIR}/bin/jruby-cext-c", dir
name = File.basename(dir)
run '--sulong', '-I', "#{dir}/lib", "#{dir}/bin/#{name}", :out => output_file
unless File.read(output_file) == File.read("#{dir}/expected.txt")
abort "c extension #{dir} didn't work as expected"
begin
output_file = 'cext-output.txt'
['minimum', 'method', 'module'].each do |gem|
dir = "#{JRUBY_DIR}/test/truffle/cexts/#{gem}"
sh Utilities.find_jruby, "#{JRUBY_DIR}/bin/jruby-cext-c", 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")
abort "c extension #{dir} didn't work as expected"
end
end
ensure
File.delete output_file rescue nil
end
['oily_png', 'psd_native'].each do |gem|
config = "#{JRUBY_DIR}/test/truffle/cexts/#{gem}"
sh Utilities.find_jruby, "#{JRUBY_DIR}/bin/jruby-cext-c", config
end
ensure
File.delete output_file rescue nil
end
private :test_cexts

@@ -758,10 +748,6 @@ def test_specs(command, *args)
options += %w[--format spec/truffle/truffle_formatter.rb]
end

if args.delete('--sulong')
collect_sulong_args(env_vars, options, '-T')
end

if ENV['CI']
# Need lots of output to keep Travis happy
options += %w[--format specdoc]
@@ -1017,24 +1003,6 @@ def check_ambiguous_arguments
run({ "TRUFFLE_CHECK_AMBIGUOUS_OPTIONAL_ARGS" => "true" }, '-e', 'exit')
end

def collect_sulong_args(env_vars, args, arg_prefix='')
dir = Utilities.find_sulong_dir
env_vars["JAVACMD"] = Utilities.find_sulong_graal(dir)

if ENV["SULONG_CLASSPATH"]
args << "#{arg_prefix}-J-cp" << "#{arg_prefix}#{ENV["SULONG_CLASSPATH"]}"
else
truffle_jar = File.expand_path("../truffle/mxbuild/dists/truffle-api.jar", dir)
args << "#{arg_prefix}-J-Xbootclasspath/p:#{truffle_jar}"
nfi_classes = File.expand_path('../graal-core/mxbuild/graal/com.oracle.nfi/bin', dir)
args << "#{arg_prefix}-J-cp"
args << "#{arg_prefix}#{dir}/lib/*:#{dir}/build/sulong.jar:#{nfi_classes}"
end

args << "#{arg_prefix}-J-XX:-UseJVMCIClassLoader"
end
private :collect_sulong_args

end

class JT
Original file line number Diff line number Diff line change
@@ -105,52 +105,51 @@ protected boolean require(VirtualFrame frame, String feature,
}

final String mimeType = source.getMimeType();
switch (mimeType) {
case RubyLanguage.MIME_TYPE: {
final RubyRootNode rootNode = getContext().getCodeLoader().parse(
source,
UTF8Encoding.INSTANCE,
ParserContext.TOP_LEVEL,
null,
true,
this);

final CodeLoader.DeferredCall deferredCall = getContext().getCodeLoader().prepareExecute(
ParserContext.TOP_LEVEL,
DeclarationContext.TOP_LEVEL,
rootNode,
null,
coreLibrary().getMainObject());

deferredCall.call(frame, callNode);
break;
}

case RubyLanguage.CEXT_MIME_TYPE: {
featureLoader.ensureCExtImplementationLoaded(frame, callNode);

final CallTarget callTarget = featureLoader.parseSource(source);
callNode.call(frame, callTarget, new Object[] {});

final TruffleObject initFunction = getInitFunction(expandedPath);

if (!ForeignAccess.sendIsExecutable(isExecutableNode, frame, initFunction)) {
CompilerDirectives.transferToInterpreterAndInvalidate();
throw new UnsupportedOperationException();
}
if (RubyLanguage.MIME_TYPE.equals(mimeType)) {
final RubyRootNode rootNode = getContext().getCodeLoader().parse(
source,
UTF8Encoding.INSTANCE,
ParserContext.TOP_LEVEL,
null,
true,
this);

final CodeLoader.DeferredCall deferredCall = getContext().getCodeLoader().prepareExecute(
ParserContext.TOP_LEVEL,
DeclarationContext.TOP_LEVEL,
rootNode,
null,
coreLibrary().getMainObject());

deferredCall.call(frame, callNode);
} else if (RubyLanguage.CEXT_MIME_TYPE.equals(mimeType)) {
featureLoader.ensureCExtImplementationLoaded(frame, callNode);

final CallTarget callTarget = featureLoader.parseSource(source);
callNode.call(frame, callTarget, new Object[] {});

final TruffleObject initFunction = getInitFunction(expandedPath);

if (!ForeignAccess.sendIsExecutable(isExecutableNode, frame, initFunction)) {
CompilerDirectives.transferToInterpreterAndInvalidate();
throw new UnsupportedOperationException();
}

try {
ForeignAccess.sendExecute(executeNode, frame, initFunction);
} catch (InteropException e) {
CompilerDirectives.transferToInterpreterAndInvalidate();
throw new JavaException(e);
}
break;
try {
ForeignAccess.sendExecute(executeNode, frame, initFunction);
} catch (InteropException e) {
CompilerDirectives.transferToInterpreterAndInvalidate();
throw new JavaException(e);
}
} else {
errorProfile.enter();

default:
errorProfile.enter();
if (expandedPath.toLowerCase().endsWith(".su")) {
throw new RaiseException(cextSupportNotAvailable(expandedPath));
} else {
throw new RaiseException(unknownLanguage(expandedPath, mimeType));
}
}

addToLoadedFeatures(frame, pathString);
@@ -162,6 +161,13 @@ protected boolean require(VirtualFrame frame, String feature,
}
}

@TruffleBoundary
private DynamicObject cextSupportNotAvailable(String expandedPath) {
return getContext().getCoreExceptions().internalError(
"cext support is not available to load " + expandedPath,
callNode);
}

@TruffleBoundary
private DynamicObject unknownLanguage(String expandedPath, final String mimeType) {
return getContext().getCoreExceptions().internalError(
Original file line number Diff line number Diff line change
@@ -7,7 +7,6 @@
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/

package org.jruby.truffle.language.loader;

import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
@@ -45,16 +44,9 @@ public synchronized Source getSource(String canonicalPath) throws IOException {
public synchronized Source getBestSourceFuzzily(final String fuzzyPath) {
final List<Map.Entry<String, Source>> matches = new ArrayList<>(sources.entrySet());

Collections.sort(matches, new Comparator<Map.Entry<String, Source>>() {

@Override
public int compare(Map.Entry<String, Source> a, Map.Entry<String, Source> b) {
return Integer.compare(
lengthOfCommonPrefix(fuzzyPath, b.getKey()),
lengthOfCommonPrefix(fuzzyPath, a.getKey()));
}

});
Collections.sort(matches, (a, b) -> Integer.compare(
lengthOfCommonPrefix(fuzzyPath, b.getKey()),
lengthOfCommonPrefix(fuzzyPath, a.getKey())));

if (matches.isEmpty()) {
return null;