Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Better fix for JRUBY-2186 and improvement to prevent things like JRUB…

…Y-4693.

JRUBY-2186 added logic to filter out singleton classes in completeion.rb. This commit just filters them during each_object, like MRI does.

JRUBY-4693 reported a perf issue with Float multiplication that turned out to be just running a benchmark in IRB. We originally turned ObjectSpace on in IRB to allow completion to work, but completion only uses each_object(Module). This commit makes that work as well as each_object(Class) did.
  • Loading branch information...
commit 9414a764ecf84b9c0f2871dabaf51b2036fc1b47 1 parent 0214bfb
@headius headius authored
View
6 bin/jirb
@@ -7,12 +7,6 @@
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
#
-if defined?(JRUBY_VERSION)
- require 'jruby/util'
- # useful for code completion
- JRuby::Util.objectspace = true
-end
-
require "irb"
if __FILE__ == $0
View
3  lib/ruby/1.8/irb/completion.rb
@@ -154,9 +154,6 @@ module InputCompletor
# func1.func2
candidates = []
ObjectSpace.each_object(Module){|m|
- # JRuby specific (JRUBY-2186)
- next unless m.respond_to?(:instance_methods)
-
begin
name = m.name
rescue Exception
View
18 src/org/jruby/Ruby.java
@@ -39,6 +39,7 @@
***** END LICENSE BLOCK *****/
package org.jruby;
+import org.jruby.util.func.Function1;
import java.io.ByteArrayInputStream;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -134,6 +135,7 @@
import org.jruby.javasupport.util.RuntimeHelpers;
import org.jruby.management.BeanManager;
import org.jruby.management.BeanManagerFactory;
+import org.jruby.runtime.CallBlock;
import org.jruby.threading.DaemonThreadFactory;
/**
@@ -737,6 +739,19 @@ public int allocSymbolId() {
public int allocModuleId() {
return moduleLastId.incrementAndGet();
}
+ public int allocModuleId(RubyModule module) {
+ synchronized (allModules) {
+ allModules.add(module);
+ }
+ return allocModuleId();
+ }
+ public void eachModule(Function1<Object, IRubyObject> func) {
+ synchronized (allModules) {
+ for (RubyModule module : allModules) {
+ func.apply(module);
+ }
+ }
+ }
/**
* Retrieve the module with the given name from the Object namespace.
@@ -3821,6 +3836,9 @@ public Object getHierarchyLock() {
private AtomicInteger symbolLastId = new AtomicInteger(128);
private AtomicInteger moduleLastId = new AtomicInteger(0);
+ // Weak map of all Modules in the system (and by extension, all Classes
+ private Set<RubyModule> allModules = new WeakHashSet<RubyModule>();
+
private Object respondToMethod;
private Map<String, DateTimeZone> timeZoneCache = new HashMap<String,DateTimeZone>();
View
4 src/org/jruby/RubyModule.java
@@ -212,7 +212,7 @@ public void addIncludingHierarchy(IncludedModuleWrapper hierarchy) {
*/
protected RubyModule(Ruby runtime, RubyClass metaClass, boolean objectSpace) {
super(runtime, metaClass, objectSpace);
- id = runtime.allocModuleId();
+ id = runtime.allocModuleId(this);
// if (parent == null) parent = runtime.getObject();
setFlag(USER7_F, !isClass());
generation = new Generation();
@@ -223,7 +223,7 @@ protected RubyModule(Ruby runtime, RubyClass metaClass, boolean objectSpace) {
*/
protected RubyModule(Ruby runtime, RubyClass metaClass, Generation generation, boolean objectSpace) {
super(runtime, metaClass, objectSpace);
- id = runtime.allocModuleId();
+ id = runtime.allocModuleId(this);
// if (parent == null) parent = runtime.getObject();
setFlag(USER7_F, !isClass());
this.generation = generation;
View
47 src/org/jruby/RubyObjectSpace.java
@@ -41,6 +41,7 @@
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
+import org.jruby.util.func.Function1;
@JRubyModule(name="ObjectSpace")
public class RubyObjectSpace {
@@ -112,40 +113,46 @@ public static IRubyObject id2ref(IRubyObject recv, IRubyObject id) {
}
}
- public static IRubyObject each_object(ThreadContext context, IRubyObject recv, IRubyObject[] args, Block block) {
- RubyModule rubyClass;
+ public static IRubyObject each_object(final ThreadContext context, IRubyObject recv, IRubyObject[] args, final Block block) {
+ RubyModule tmpClass;
if (args.length == 0) {
- rubyClass = recv.getRuntime().getObject();
+ tmpClass = recv.getRuntime().getObject();
} else {
if (!(args[0] instanceof RubyModule)) throw recv.getRuntime().newTypeError("class or module required");
- rubyClass = (RubyModule) args[0];
+ tmpClass = (RubyModule) args[0];
}
+ final RubyModule rubyClass = tmpClass;
Ruby runtime = recv.getRuntime();
- int count = 0;
- if (rubyClass != runtime.getClassClass()) {
+ final int[] count = {0};
+ if (rubyClass == runtime.getClassClass() ||
+ rubyClass == runtime.getModule()) {
+ runtime.eachModule(new Function1<Object, IRubyObject>() {
+ public Object apply(IRubyObject arg1) {
+ if (rubyClass.isInstance(arg1)) {
+ if (arg1 instanceof IncludedModuleWrapper ||
+ (arg1 instanceof RubyClass && ((RubyClass)arg1).isSingleton())) {
+ // do nothing for included wrappers or singleton classes
+ } else {
+ count[0]++;
+ block.yield(context, arg1);
+ }
+ }
+ return null;
+ }
+ });
+ } else {
if (!runtime.isObjectSpaceEnabled()) {
throw runtime.newRuntimeError("ObjectSpace is disabled; each_object will only work with Class, pass -X+O to enable");
}
Iterator iter = recv.getRuntime().getObjectSpace().iterator(rubyClass);
-
+
IRubyObject obj = null;
while ((obj = (IRubyObject)iter.next()) != null) {
- count++;
- block.yield(context, obj);
- }
- } else {
- Iterator iter = runtime.getObject().subclasses(true).iterator();
-
- while (iter.hasNext()) {
- IRubyObject obj = (IRubyObject)iter.next();
- if (obj instanceof RubyClass && ((RubyClass)obj).isIncluded()) {
- continue;
- }
- count++;
+ count[0]++;
block.yield(context, obj);
}
}
- return recv.getRuntime().newFixnum(count);
+ return recv.getRuntime().newFixnum(count[0]);
}
@JRubyMethod(name = "each_object", optional = 1, frame = true, module = true, visibility = Visibility.PRIVATE)
Please sign in to comment.
Something went wrong with that request. Please try again.