Skip to content

[GR-52676] Use Panama for upcalls #3532

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/cext/ABI_check.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1
2
18 changes: 17 additions & 1 deletion lib/truffle/truffle/cext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,15 @@ def self.init_libtrufflerubytrampoline(libtrampoline)

init_functions = libtrampoline[:rb_tr_trampoline_init_functions]
init_functions = Primitive.interop_eval_nfi('(env,(string):pointer):void').bind(init_functions)
init_functions.call(-> name { LIBTRUFFLERUBY[name] })
if Truffle::Boot.get_option 'cexts-panama' and Primitive.vm_java_version >= 22 and !TruffleRuby.native?
init_functions.call(-> name {
closure = LIBTRUFFLERUBY[name].createNativeClosure('panama')
keep_alive << closure
closure
})
else
init_functions.call(-> name { LIBTRUFFLERUBY[name] })
end

init_constants = libtrampoline[:rb_tr_trampoline_init_global_constants]
init_constants = Primitive.interop_eval_nfi('((string):pointer):void').bind(init_constants)
Expand Down Expand Up @@ -1784,6 +1792,14 @@ def rb_f_notimplement
raise NotImplementedError, "#{function}() function is unimplemented on this machine"
end

def rb_bug(message)
raise Exception, "rb_bug: #{message}"
end

def rb_fatal(message)
raise Exception, "rb_fatal: #{message}"
end

def test_kwargs(kwargs, raise_error)
return false if Primitive.nil?(kwargs)

Expand Down
2 changes: 1 addition & 1 deletion spec/ruby/optional/capi/ext/kernel_spec.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ static VALUE kernel_spec_rb_eval_string_protect(VALUE self, VALUE str, VALUE ary
VALUE kernel_spec_rb_sys_fail(VALUE self, VALUE msg) {
errno = 1;
if (msg == Qnil) {
rb_sys_fail(0);
rb_sys_fail(NULL);
} else if (self != Qundef) {
rb_sys_fail(StringValuePtr(msg));
}
Expand Down
14 changes: 11 additions & 3 deletions src/main/c/cext/exception.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ VALUE rb_syserr_new_str(int n, VALUE mesg) {
return RUBY_CEXT_INVOKE("rb_syserr_new", INT2FIX(n), mesg);
}

VALUE make_errno_exc_str(VALUE mesg) {
static VALUE make_errno_exc_str(VALUE mesg) {
int n = errno;

errno = 0;
Expand Down Expand Up @@ -156,11 +156,19 @@ void rb_eof_error(void) {
}

void rb_tr_bug_va_list(const char *fmt, va_list args) {
rb_tr_not_implemented("rb_bug");
char buffer[1024];
vsnprintf(buffer, 1024, fmt, args);
VALUE message = rb_str_new_cstr(buffer);
RUBY_CEXT_INVOKE_NO_WRAP("rb_bug", message);
UNREACHABLE;
}

void rb_tr_fatal_va_list(const char *fmt, va_list args) {
rb_tr_not_implemented("rb_fatal");
char buffer[1024];
vsnprintf(buffer, 1024, fmt, args);
VALUE message = rb_str_new_cstr(buffer);
RUBY_CEXT_INVOKE_NO_WRAP("rb_fatal", message);
UNREACHABLE;
}

VALUE rb_make_exception(int argc, const VALUE *argv) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/truffleruby/cext/IsNativeObjectNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
public abstract class IsNativeObjectNode extends RubyBaseNode {

/** Returns true if handle was natively allocated. */
public abstract Object execute(Node node, Object handle);
public abstract boolean execute(Node node, Object handle);

@Specialization
static boolean isNativeObjectTaggedObject(long handle) {
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/org/truffleruby/cext/ValueWrapperManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ protected boolean isExecutable() {
}

@ExportMessage
protected Object execute(Object[] arguments,
protected ValueWrapper execute(Object[] arguments,
@Cached WrapNode wrapNode) {
return wrapNode.execute(arguments[0]);
}
Expand All @@ -450,7 +450,7 @@ protected boolean isExecutable() {
}

@ExportMessage
protected Object execute(Object[] arguments,
protected boolean execute(Object[] arguments,
@Cached IsNativeObjectNode isNativeObjectNode,
@Bind("$node") Node node) {
return isNativeObjectNode.execute(node, arguments[0]);
Expand All @@ -467,7 +467,7 @@ protected boolean isExecutable() {
}

@ExportMessage
protected Object execute(Object[] arguments,
protected long execute(Object[] arguments,
@CachedLibrary(limit = "1") InteropLibrary values) throws UnsupportedMessageException {
values.toNative(arguments[0]);
return values.asPointer(arguments[0]);
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/org/truffleruby/options/Options.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ public final class Options {
public final boolean CEXTS;
/** --cexts-lock=true */
public final boolean CEXT_LOCK;
/** --cexts-panama=false */
public final boolean CEXTS_PANAMA;
/** --options-log=false */
public final boolean OPTIONS_LOG;
/** --log-load=false */
Expand Down Expand Up @@ -250,6 +252,7 @@ public Options(Env env, OptionValues options, LanguageOptions languageOptions) {
BACKTRACE_ON_NEW_FIBER = options.get(OptionsCatalog.BACKTRACE_ON_NEW_FIBER_KEY);
CEXTS = options.get(OptionsCatalog.CEXTS_KEY);
CEXT_LOCK = options.get(OptionsCatalog.CEXT_LOCK_KEY);
CEXTS_PANAMA = options.get(OptionsCatalog.CEXTS_PANAMA_KEY);
OPTIONS_LOG = options.get(OptionsCatalog.OPTIONS_LOG_KEY);
LOG_LOAD = options.get(OptionsCatalog.LOG_LOAD_KEY);
LOG_AUTOLOAD = options.get(OptionsCatalog.LOG_AUTOLOAD_KEY);
Expand Down Expand Up @@ -386,6 +389,8 @@ public Object fromDescriptor(OptionDescriptor descriptor) {
return CEXTS;
case "ruby.cexts-lock":
return CEXT_LOCK;
case "ruby.cexts-panama":
return CEXTS_PANAMA;
case "ruby.options-log":
return OPTIONS_LOG;
case "ruby.log-load":
Expand Down
1 change: 1 addition & 0 deletions src/options.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ EXPERT:
# C extension options
CEXTS: [cexts, boolean, true, Enable use of C extensions]
CEXT_LOCK: [cexts-lock, boolean, true, Use a Global Lock when running C extensions]
CEXTS_PANAMA: [cexts-panama, boolean, false, 'Use Panama for native to Ruby calls in C extensions. Only available in --jvm mode on JDK 22+.']

# Debugging the values of options
OPTIONS_LOG: [options-log, boolean, false, Log the final value of all options]
Expand Down
12 changes: 12 additions & 0 deletions src/shared/java/org/truffleruby/shared/options/OptionsCatalog.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public final class OptionsCatalog {
public static final OptionKey<Boolean> BACKTRACE_ON_NEW_FIBER_KEY = new OptionKey<>(false);
public static final OptionKey<Boolean> CEXTS_KEY = new OptionKey<>(true);
public static final OptionKey<Boolean> CEXT_LOCK_KEY = new OptionKey<>(true);
public static final OptionKey<Boolean> CEXTS_PANAMA_KEY = new OptionKey<>(false);
public static final OptionKey<Boolean> OPTIONS_LOG_KEY = new OptionKey<>(false);
public static final OptionKey<Boolean> LOG_LOAD_KEY = new OptionKey<>(false);
public static final OptionKey<Boolean> LOG_AUTOLOAD_KEY = new OptionKey<>(false);
Expand Down Expand Up @@ -573,6 +574,14 @@ public final class OptionsCatalog {
.usageSyntax("")
.build();

public static final OptionDescriptor CEXTS_PANAMA = OptionDescriptor
.newBuilder(CEXTS_PANAMA_KEY, "ruby.cexts-panama")
.help("Use Panama for native to Ruby calls in C extensions. Only available in --jvm mode on JDK 22+.")
.category(OptionCategory.EXPERT)
.stability(OptionStability.EXPERIMENTAL)
.usageSyntax("")
.build();

public static final OptionDescriptor OPTIONS_LOG = OptionDescriptor
.newBuilder(OPTIONS_LOG_KEY, "ruby.options-log")
.help("Log the final value of all options")
Expand Down Expand Up @@ -1421,6 +1430,8 @@ public static OptionDescriptor fromName(String name) {
return CEXTS;
case "ruby.cexts-lock":
return CEXT_LOCK;
case "ruby.cexts-panama":
return CEXTS_PANAMA;
case "ruby.options-log":
return OPTIONS_LOG;
case "ruby.log-load":
Expand Down Expand Up @@ -1665,6 +1676,7 @@ public static OptionDescriptor[] allDescriptors() {
BACKTRACE_ON_NEW_FIBER,
CEXTS,
CEXT_LOCK,
CEXTS_PANAMA,
OPTIONS_LOG,
LOG_LOAD,
LOG_AUTOLOAD,
Expand Down
Loading