Skip to content

Instantly share code, notes, and snippets.

@calavera
Created November 24, 2009 12:13
Show Gist options
  • Save calavera/241829 to your computer and use it in GitHub Desktop.
Save calavera/241829 to your computer and use it in GitHub Desktop.
From 02eadbc2707e46914b28e5f040ffbbf8becf9888 Mon Sep 17 00:00:00 2001
From: David Calavera <david.calavera@gmail.com>
Date: Tue, 24 Nov 2009 13:11:25 +0100
Subject: [PATCH] fixes JRUBY-4268: speed-up yaml/yecht loading
---
src/org/jruby/Ruby.java | 25 +++++++++-----
src/org/jruby/RubyJRuby.java | 12 ++++++
src/org/jruby/ext/LateLoadingLibrary.java | 7 ++--
src/org/jruby/ext/LateLoadingScriptLibrary.java | 42 +++++++++++++++++++++++
src/org/jruby/runtime/load/LoadService.java | 21 +++++++++++-
5 files changed, 93 insertions(+), 14 deletions(-)
create mode 100644 src/org/jruby/ext/LateLoadingScriptLibrary.java
diff --git a/src/org/jruby/Ruby.java b/src/org/jruby/Ruby.java
index 3b09120..05b0c92 100644
--- a/src/org/jruby/Ruby.java
+++ b/src/org/jruby/Ruby.java
@@ -131,6 +131,7 @@ import com.kenai.constantine.platform.Errno;
import java.util.EnumSet;
import java.util.concurrent.atomic.AtomicLong;
import org.jruby.ast.RootNode;
+import org.jruby.ext.LateLoadingScriptLibrary;
import org.jruby.internal.runtime.methods.DynamicMethod;
import org.jruby.javasupport.util.RuntimeHelpers;
import org.jruby.management.BeanManager;
@@ -1396,15 +1397,21 @@ public final class Ruby {
runtime.getLoadService().require("jruby/openssl/stub");
}
});
-
- String[] builtins = {"yaml",
- "yaml/yecht", "yaml/baseemitter", "yaml/basenode",
- "yaml/compat", "yaml/constants", "yaml/dbm",
- "yaml/emitter", "yaml/encoding", "yaml/error",
- "yaml/rubytypes", "yaml/store", "yaml/stream",
- "yaml/stringio", "yaml/tag", "yaml/types",
- "yaml/yamlnode", "yaml/ypath",
- "jsignal", "generator", "prelude"};
+
+ String[] yamlBuiltins = {"yaml",
+ "yaml/yecht", "yaml/baseemitter", "yaml/basenode",
+ "yaml/compat", "yaml/constants", "yaml/dbm",
+ "yaml/emitter", "yaml/encoding", "yaml/error",
+ "yaml/rubytypes", "yaml/store", "yaml/stream",
+ "yaml/stringio", "yaml/tag", "yaml/types",
+ "yaml/yamlnode", "yaml/ypath"};
+ for (String library : yamlBuiltins) {
+ addBuiltinIfAllowed(library + ".rb",
+ new LateLoadingScriptLibrary(library,
+ "org.jruby.RubyJRuby$BuiltinScriptLibrary", getClassLoader()));
+ }
+
+ String[] builtins = {"jsignal", "generator", "prelude"};
for (String library : builtins) {
addBuiltinIfAllowed(library + ".rb", new BuiltinScript(library));
}
diff --git a/src/org/jruby/RubyJRuby.java b/src/org/jruby/RubyJRuby.java
index cfc6c93..8e33337 100644
--- a/src/org/jruby/RubyJRuby.java
+++ b/src/org/jruby/RubyJRuby.java
@@ -72,6 +72,7 @@ import org.objectweb.asm.util.TraceClassVisitor;
import java.util.Map;
import org.jruby.runtime.ExecutionContext;
import org.jruby.runtime.ObjectAllocator;
+import org.jruby.util.BuiltinScript;
/**
* Module which defines JRuby-specific methods for use.
@@ -117,6 +118,17 @@ public class RubyJRuby {
runtime.getString().defineAnnotatedMethods(JRubyStringExtensions.class);
}
+ public static class BuiltinScriptLibrary implements Library {
+ private final String library;
+ public BuiltinScriptLibrary(String library) {
+ this.library = library;
+ }
+
+ public void load(Ruby runtime, boolean wrap) throws IOException {
+ new BuiltinScript(library).load(runtime, wrap);
+ }
+ }
+
public static class ExtLibrary implements Library {
public void load(Ruby runtime, boolean wrap) throws IOException {
RubyJRuby.createJRubyExt(runtime);
diff --git a/src/org/jruby/ext/LateLoadingLibrary.java b/src/org/jruby/ext/LateLoadingLibrary.java
index 73f027a..9de1fb0 100644
--- a/src/org/jruby/ext/LateLoadingLibrary.java
+++ b/src/org/jruby/ext/LateLoadingLibrary.java
@@ -30,14 +30,13 @@ package org.jruby.ext;
import java.io.IOException;
import org.jruby.Ruby;
-import org.jruby.exceptions.RaiseException;
import org.jruby.runtime.load.Library;
import org.jruby.runtime.load.LoadService;
public class LateLoadingLibrary implements Library {
- private final String libraryName;
- private final String className;
- private ClassLoader classLoader;
+ protected final String libraryName;
+ protected final String className;
+ protected ClassLoader classLoader;
public LateLoadingLibrary(String libraryName, String className, ClassLoader classLoader) {
this.libraryName = libraryName;
diff --git a/src/org/jruby/ext/LateLoadingScriptLibrary.java b/src/org/jruby/ext/LateLoadingScriptLibrary.java
new file mode 100644
index 0000000..2cfa814
--- /dev/null
+++ b/src/org/jruby/ext/LateLoadingScriptLibrary.java
@@ -0,0 +1,42 @@
+/*
+ **** BEGIN LICENSE BLOCK *****
+ * Version: CPL 1.0/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Common Public
+ * License Version 1.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * Copyright (C) 2007 JRuby Community
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the CPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the CPL, the GPL or the LGPL.
+ ***** END LICENSE BLOCK *****/package org.jruby.ext;
+
+import java.io.IOException;
+import org.jruby.Ruby;
+import org.jruby.runtime.load.LoadService;
+
+public class LateLoadingScriptLibrary extends LateLoadingLibrary {
+ public LateLoadingScriptLibrary(String libraryName, String className, ClassLoader classLoader) {
+ super(libraryName, className, classLoader);
+ }
+
+ public synchronized void load(Ruby runtime, boolean wrap) throws IOException {
+ LoadService.reflectedScriptLoad(runtime, libraryName, className, classLoader, wrap);
+ }
+}
diff --git a/src/org/jruby/runtime/load/LoadService.java b/src/org/jruby/runtime/load/LoadService.java
index e51f063..3af7364 100644
--- a/src/org/jruby/runtime/load/LoadService.java
+++ b/src/org/jruby/runtime/load/LoadService.java
@@ -332,12 +332,31 @@ public class LoadService {
* @param wrap Whether to wrap top-level in an anonymous module
*/
public static void reflectedLoad(Ruby runtime, String libraryName, String className, ClassLoader classLoader, boolean wrap) {
+ loadLibraryCommon(runtime, libraryName, className, classLoader, wrap);
+ }
+
+ public static void reflectedScriptLoad(Ruby runtime, String libraryName, String className, ClassLoader classLoader, boolean wrap) {
+ loadLibraryCommon(runtime, libraryName, className, classLoader, wrap, libraryName);
+ }
+
+ private static void loadLibraryCommon(Ruby runtime, String libraryName, String className, ClassLoader classLoader, boolean wrap, Object... args) {
try {
if (classLoader == null && Ruby.isSecurityRestricted()) {
classLoader = runtime.getInstanceConfig().getLoader();
}
- Library library = (Library) classLoader.loadClass(className).newInstance();
+ Library library = null;
+ if (args != null && args.length > 0) {
+ java.util.Collection<Class> classes = new ArrayList<Class>();
+ for (Object arg : args) {
+ classes.add(arg.getClass());
+ }
+
+ library = (Library) classLoader.loadClass(className)
+ .getConstructor(classes.toArray(new Class[classes.size()])).newInstance(args);
+ } else {
+ library = (Library) classLoader.loadClass(className).newInstance();
+ }
library.load(runtime, false);
} catch (RaiseException re) {
--
1.6.0.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment