From c409a46774261787c02e6b9bf74d84b4879cc434 Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Sat, 12 Sep 2026 21:56:42 +0200 Subject: [PATCH] Omit the stacktrace for JOniException unless -Dorg.joni.enableStackTrace=true * The stacktrace is not very useful and is very expensive, for example for Regexp#to_s on a Regexp like /(?i:a)|(?i:b)/. * On ruby-bench's railsbench it accounts for about 8% of the request time. * Rails master has been improved to use #source instead, https://github.com/rails/rails/pull/58678, but that doesn't affect existing releases. * The stacktrace can be re-enabled with the org.joni.enableStackTrace system property, e.g. for debugging JOni itself. Co-Authored-By: Claude Fable 5.1 --- src/org/joni/Config.java | 5 +++++ src/org/joni/exception/JOniException.java | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/org/joni/Config.java b/src/org/joni/Config.java index 90eec0ba..66a69417 100644 --- a/src/org/joni/Config.java +++ b/src/org/joni/Config.java @@ -74,6 +74,11 @@ public interface Config extends org.jcodings.Config { int CHECK_STRING_THRESHOLD_LEN = ConfigSupport.getInt("joni.check_string_threshold_len", 7); int CHECK_BUFF_MAX_SIZE = ConfigSupport.getInt("joni.check_buff_max_size", 0x4000); + // Whether JOniException and its subclasses record a stack trace when thrown. + // Filling in the stack trace is expensive and the Java stack trace is rarely useful + // (e.g. for a regexp syntax error), so it is disabled by default. + boolean ENABLE_STACK_TRACE = ConfigSupport.getBoolean("org.joni.enableStackTrace", false); + PrintStream log = System.out; PrintStream err = System.err; diff --git a/src/org/joni/exception/JOniException.java b/src/org/joni/exception/JOniException.java index c2c5d479..3a34086c 100644 --- a/src/org/joni/exception/JOniException.java +++ b/src/org/joni/exception/JOniException.java @@ -19,10 +19,24 @@ */ package org.joni.exception; +import org.joni.Config; + public class JOniException extends RuntimeException{ private static final long serialVersionUID = -6027192180014164667L; public JOniException(String message) { super(message); } + + // The stacktrace is not very useful and is very expensive, + // for example for Regexp#to_s on a Regexp like /(?i:a)|(?i:b)/, + // so it is omitted unless -Dorg.joni.enableStackTrace=true + @Override + public final Throwable fillInStackTrace() { + if (Config.ENABLE_STACK_TRACE) { + return super.fillInStackTrace(); + } else { + return this; + } + } }