Skip to content

Commit

Permalink
Merge pull request #8545 from enebo/alloc_again
Browse files Browse the repository at this point in the history
Reduce getRuntime() and make alloc use TC
  • Loading branch information
enebo authored Dec 24, 2024
2 parents 4e8f7e3 + fb41bdc commit 45e9520
Show file tree
Hide file tree
Showing 36 changed files with 242 additions and 199 deletions.
19 changes: 10 additions & 9 deletions core/src/main/java/org/jruby/MetaClass.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.jruby.util.log.Logger;
import org.jruby.util.log.LoggerFactory;

import static org.jruby.api.Access.classClass;
import static org.jruby.api.Error.typeError;

public final class MetaClass extends RubyClass {
Expand All @@ -46,7 +47,7 @@ public MetaClass(Ruby runtime, RubyClass superClass, IRubyObject attached) {
}

/**
* rb_class_boot for meta classes ({@link #makeMetaClass(RubyClass)})
* rb_class_boot for meta classes ({@link #makeMetaClass(ThreadContext, RubyClass)})
*/
MetaClass(Ruby runtime, RubyClass superClass, RubyBasicObject attached) {
super(runtime, superClass, false);
Expand Down Expand Up @@ -104,8 +105,8 @@ public boolean isSingleton() {
* @return singleton-class for this (singleton) class
*/
@Override
public RubyClass makeMetaClass(RubyClass superClass) {
MetaClass klass = new MetaClass(runtime, getSuperSingletonMetaClass(), this);
public RubyClass makeMetaClass(ThreadContext context, RubyClass superClass) {
MetaClass klass = new MetaClass(context.runtime, getSuperSingletonMetaClass(context), this);
setMetaClass(klass);

// Foo.singleton_class.singleton_class: #<Class:#<Class:Foo>>
Expand All @@ -115,23 +116,23 @@ public RubyClass makeMetaClass(RubyClass superClass) {
return klass;
}

private RubyClass getSuperSingletonMetaClass() {
private RubyClass getSuperSingletonMetaClass(ThreadContext context) {
if (attached instanceof RubyClass att) {
RubyClass superClass = att.superClass();
if (superClass != null) superClass = superClass.getRealClass();
// #<Class:BasicObject>'s singleton class == Class.singleton_class
// Context should be safe here as we never make a metaclass from a metaclass before first TC is made.
var context = getRuntime().getCurrentContext();
if (superClass == null) return runtime.getClassClass().singletonClass(context);
return superClass.getMetaClass().singletonClass(context);
return superClass == null ?
classClass(context).singletonClass(context) :
superClass.getMetaClass().singletonClass(context);
}

return getSuperClass().getRealClass().getMetaClass(); // NOTE: is this correct?
}

@Override
RubyClass toSingletonClass(RubyBasicObject target) {
return attached == target ? this : super.toSingletonClass(target);
RubyClass toSingletonClass(ThreadContext context, RubyBasicObject target) {
return attached == target ? this : super.toSingletonClass(context, target);
}

@Override
Expand Down
16 changes: 8 additions & 8 deletions core/src/main/java/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
Expand Up @@ -335,11 +335,11 @@ private Ruby(RubyInstanceConfig config) {
classClass.setMetaClass(classClass);
refinementClass.setMetaClass(classClass);

var metaClass = basicObjectClass.makeMetaClassBootstrap(classClass, classClass);
metaClass = objectClass.makeMetaClassBootstrap(metaClass, classClass);
metaClass = moduleClass.makeMetaClassBootstrap(metaClass, classClass);
classClass.makeMetaClassBootstrap(metaClass, classClass);
refinementClass.makeMetaClassBootstrap(metaClass, classClass);
var metaClass = basicObjectClass.makeMetaClassBootstrap(this, classClass, classClass);
metaClass = objectClass.makeMetaClassBootstrap(this, metaClass, classClass);
metaClass = moduleClass.makeMetaClassBootstrap(this, metaClass, classClass);
classClass.makeMetaClassBootstrap(this, metaClass, classClass);
refinementClass.makeMetaClassBootstrap(this, metaClass, classClass);

RubyObject.finishObjectClass(objectClass);
RubyModule.finishModuleClass(moduleClass);
Expand All @@ -361,9 +361,9 @@ private Ruby(RubyInstanceConfig config) {

// nil, true, and false all are set in TC so they need to be created above (both class and instances).
// their methods are added afterward since no dispatch happens until after first TC is defined.
nilClass = RubyClass.newClassBootstrap(this, objectClass, "NilClass");
falseClass = RubyClass.newClassBootstrap(this, objectClass, "FalseClass");
trueClass = RubyClass.newClassBootstrap(this, objectClass, "TrueClass");
nilClass = RubyClass.newClassBootstrap(this, objectClass, classClass, "NilClass");
falseClass = RubyClass.newClassBootstrap(this, objectClass, classClass, "FalseClass");
trueClass = RubyClass.newClassBootstrap(this, objectClass, classClass, "TrueClass");

nilObject = new RubyNil(this, nilClass);
nilPrefilledArray = new IRubyObject[NIL_PREFILLED_ARRAY_SIZE];
Expand Down
43 changes: 19 additions & 24 deletions core/src/main/java/org/jruby/RubyArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -516,10 +516,9 @@ private void alloc(int length) {

private void realloc(ThreadContext context, int newLength, int valuesLength) {
unpack(context);
Ruby runtime = metaClass.runtime;
IRubyObject[] reallocated = IRubyObject.array(validateBufferLength(runtime, newLength));
IRubyObject[] reallocated = IRubyObject.array(validateBufferLength(context.runtime, newLength));
if (newLength > valuesLength) {
Helpers.fillNil(reallocated, valuesLength, newLength, runtime);
Helpers.fillNil(reallocated, valuesLength, newLength, context.runtime);
safeArrayCopy(context, values, begin, reallocated, 0, valuesLength); // elements and trailing nils
} else {
safeArrayCopy(context, values, begin, reallocated, 0, newLength); // ???
Expand Down Expand Up @@ -625,7 +624,7 @@ protected RubyArray<?> makeShared() {
}

private RubyArray makeShared(ThreadContext context, int beg, int len, RubyClass klass) {
return makeShared(context, beg, len, new RubyArray(klass.runtime, klass));
return makeShared(context, beg, len, new RubyArray(context.runtime, klass));
}

private final RubyArray makeShared(ThreadContext context, int beg, int len, RubyArray sharedArray) {
Expand Down Expand Up @@ -1131,7 +1130,7 @@ private void splice(ThreadContext context, int beg, int len, final RubyArray rpl
int valuesLength = values.length - begin;
if (beg >= realLength) {
len = beg + rlen;
if (len >= valuesLength) spliceRealloc(len, valuesLength);
if (len >= valuesLength) spliceRealloc(context, len, valuesLength);
try {
Helpers.fillNil(values, begin + realLength, begin + beg, context.runtime);
} catch (ArrayIndexOutOfBoundsException e) {
Expand All @@ -1141,7 +1140,7 @@ private void splice(ThreadContext context, int beg, int len, final RubyArray rpl
} else {
if (beg + len > realLength) len = realLength - beg;
int alen = realLength + rlen - len;
if (alen >= valuesLength) spliceRealloc(alen, valuesLength);
if (alen >= valuesLength) spliceRealloc(context, alen, valuesLength);

if (len != rlen) {
safeArrayCopy(context, values, begin + (beg + len), values, begin + beg + rlen, realLength - (beg + len));
Expand All @@ -1166,13 +1165,13 @@ private final void spliceOne(ThreadContext context, long beg, IRubyObject rpl) {
int valuesLength = values.length - begin;
if (beg >= realLength) {
int len = (int) beg + 1;
if (len >= valuesLength) spliceRealloc(len, valuesLength);
Helpers.fillNil(values, begin + realLength, begin + ((int) beg), metaClass.runtime);
if (len >= valuesLength) spliceRealloc(context, len, valuesLength);
Helpers.fillNil(values, begin + realLength, begin + ((int) beg), context.runtime);
realLength = len;
} else {
int len = beg > realLength ? realLength - (int) beg : 0;
int alen = realLength + 1 - len;
if (alen >= valuesLength) spliceRealloc(alen, valuesLength);
if (alen >= valuesLength) spliceRealloc(context, alen, valuesLength);

if (len == 0) {
safeArrayCopy(context, values, begin + (int) beg, values, begin + (int) beg + 1, realLength - (int) beg);
Expand All @@ -1183,33 +1182,29 @@ private final void spliceOne(ThreadContext context, long beg, IRubyObject rpl) {
safeArraySet(context, values, begin + (int) beg, rpl);
}

private void spliceRealloc(int length, int valuesLength) {
Ruby runtime = metaClass.runtime;

int tryLength = calculateBufferLength(runtime, valuesLength);
private void spliceRealloc(ThreadContext context, int length, int valuesLength) {
int tryLength = calculateBufferLength(context.runtime, valuesLength);
int len = length > tryLength ? length : tryLength;
IRubyObject[] vals = IRubyObject.array(len);
System.arraycopy(values, begin, vals, 0, realLength);

// only fill if there actually will remain trailing storage
if (len > length) {
Helpers.fillNil(vals, length, len, runtime);
Helpers.fillNil(vals, length, len, context.runtime);
}
begin = 0;
values = vals;
}

private void unshiftRealloc(ThreadContext context, int valuesLength) {
Ruby runtime = metaClass.runtime;

int newLength = valuesLength >> 1;
if (newLength < ARRAY_DEFAULT_SIZE) newLength = ARRAY_DEFAULT_SIZE;

newLength = addBufferLength(runtime, valuesLength, newLength);
newLength = addBufferLength(context.runtime, valuesLength, newLength);

IRubyObject[] vals = IRubyObject.array(newLength);
safeArrayCopy(context, values, begin, vals, 1, valuesLength);
Helpers.fillNil(vals, valuesLength + 1, newLength, runtime);
Helpers.fillNil(vals, valuesLength + 1, newLength, context.runtime);
values = vals;
begin = 0;
}
Expand Down Expand Up @@ -3773,11 +3768,11 @@ private void setValuesFrom(ThreadContext context, RubyHash hash) {
}
}

private void clearValues(final int from, final int to) {
private void clearValues(ThreadContext context, final int from, final int to) {
try {
Helpers.fillNil(values, begin + from, begin + to, metaClass.runtime);
Helpers.fillNil(values, begin + from, begin + to, context.runtime);
} catch (ArrayIndexOutOfBoundsException ex) {
throw concurrentModification(getRuntime().getCurrentContext(), ex);
throw concurrentModification(context, ex);
}
}

Expand All @@ -3793,7 +3788,7 @@ public IRubyObject uniq_bang(ThreadContext context) {
unpack(context);

setValuesFrom(context, hash);
clearValues(newLength, realLength);
clearValues(context, newLength, realLength);
realLength = newLength;

return this;
Expand All @@ -3814,7 +3809,7 @@ public IRubyObject uniq_bang(ThreadContext context, Block block) {
unpack(context);

setValuesFrom(context, hash);
clearValues(newLength, realLength);
clearValues(context, newLength, realLength);
realLength = newLength;

return this;
Expand Down Expand Up @@ -5798,7 +5793,7 @@ public boolean add(Object element) {
}

public boolean add(ThreadContext context, Object element) {
append(context, JavaUtil.convertJavaToUsableRubyObject(metaClass.runtime, element));
append(context, JavaUtil.convertJavaToUsableRubyObject(context.runtime, element));
return true;
}

Expand Down
22 changes: 14 additions & 8 deletions core/src/main/java/org/jruby/RubyBasicObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -478,21 +478,26 @@ public RubyClass getSingletonClass() {
// MRI: rb_singleton_class
@JRubyAPI
public RubyClass singletonClass(ThreadContext context) {
RubyClass klass = metaClass.toSingletonClass(this);
RubyClass klass = metaClass.toSingletonClass(context, this);

if (isFrozen()) klass.setFrozen(true);

return klass;
}

@Deprecated(since = "10.0")
public RubyClass makeMetaClass(RubyClass superClass) {
return makeMetaClass(getCurrentContext(), superClass);
}

/** rb_make_metaclass
*
* Will create a new meta class, insert this in the chain of
* classes for this specific object, and return the generated meta
* class.
*/
public RubyClass makeMetaClass(RubyClass superClass) {
MetaClass klass = new MetaClass(getRuntime(), superClass, this); // rb_class_boot
public RubyClass makeMetaClass(ThreadContext context, RubyClass superClass) {
MetaClass klass = new MetaClass(context.runtime, superClass, this); // rb_class_boot
setMetaClass(klass);

klass.setMetaClass(superClass.getRealClass().metaClass);
Expand All @@ -503,13 +508,13 @@ public RubyClass makeMetaClass(RubyClass superClass) {
/**
* This will create a new metaclass. This is only used during bootstrapping before
* the initial ThreadContext is defined. Normal needs of making a metaclass should use
* {@link RubyBasicObject#makeMetaClass(RubyClass)}
* {@link RubyBasicObject#makeMetaClass(ThreadContext, RubyClass)}
* @param superClass
* @param Class
* @return
*/
public RubyClass makeMetaClassBootstrap(RubyClass superClass, RubyClass Class) {
MetaClass klass = new MetaClass(getRuntime(), superClass, Class, this); // rb_class_boot
public RubyClass makeMetaClassBootstrap(Ruby runtime, RubyClass superClass, RubyClass Class) {
MetaClass klass = new MetaClass(runtime, superClass, Class, this); // rb_class_boot
setMetaClass(klass);

klass.setMetaClass(superClass.getRealClass().metaClass);
Expand Down Expand Up @@ -1279,7 +1284,7 @@ public IRubyObject addFinalizer(ThreadContext context, IRubyObject f) {

finalizer = new Finalizer(fixnumId);
setInternalVariable("__finalizer__", finalizer);
getRuntime().addFinalizer(finalizer);
context.runtime.addFinalizer(finalizer);
}
return finalizer.addFinalizer(context, f);
}
Expand Down Expand Up @@ -2471,9 +2476,10 @@ public IRubyObject singleton_method(IRubyObject name) {
* m = l.method("hello")
* m.call #=&gt; "Hello, {@literal @}iv = Fred"
*/
@Deprecated(since = "10.0")
public IRubyObject method(IRubyObject name) {
final RubySymbol symbol = TypeConverter.checkID(name);
return getMetaClass().newMethod(getRuntime().getCurrentContext(), this, symbol.idString(), null, true, null, true, true);
return getMetaClass().newMethod(getCurrentContext(), this, symbol.idString(), null, true, null, true, true);
}

@Deprecated(since = "10.0")
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/RubyBignum.java
Original file line number Diff line number Diff line change
Expand Up @@ -1162,7 +1162,7 @@ public IRubyObject to_f() {

@Deprecated
public IRubyObject abs() {
return abs(metaClass.runtime.getCurrentContext());
return abs(getCurrentContext());
}

/** rb_big_abs
Expand Down
27 changes: 16 additions & 11 deletions core/src/main/java/org/jruby/RubyClass.java
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ public static RubyClass newClass(Ruby runtime, RubyClass superClass, String name
allocator(allocator).
baseName(name);

clazz.makeMetaClass(superClass.getMetaClass());
clazz.makeMetaClass(context, superClass.getMetaClass());
if (setParent) clazz.setParent(parent);
parent.defineConstant(context, name, clazz);
superClass.invokeInherited(context, superClass, clazz);
Expand All @@ -549,7 +549,7 @@ public static RubyClass newClass(ThreadContext context, RubyClass superClass, St
RubyClass clazz = newClass(context, superClass, null).
allocator(allocator).
baseName(name);
clazz.makeMetaClass(superClass.getMetaClass());
clazz.makeMetaClass(context, superClass.getMetaClass());
if (setParent) clazz.setParent(parent);
parent.setConstant(context, name, clazz, file, line);
superClass.invokeInherited(context, superClass, clazz);
Expand All @@ -571,7 +571,7 @@ public static RubyClass newClass(ThreadContext context, RubyClass superClass, St
RubyClass clazz = newClass(context, superClass, extraCallSites).
allocator(allocator).
baseName(name);
clazz.makeMetaClass(superClass.getMetaClass());
clazz.makeMetaClass(context, superClass.getMetaClass());
if (setParent) clazz.setParent(parent);
parent.setConstant(context, name, clazz, BUILTIN_CONSTANT, -1);
superClass.invokeInherited(context, superClass, clazz);
Expand All @@ -587,21 +587,26 @@ public static RubyClass newClass(ThreadContext context, RubyClass superClass, St
* @param name the name of the new class
* @return the new class.
*/
public static RubyClass newClassBootstrap(Ruby runtime, RubyClass Object, String name) {
public static RubyClass newClassBootstrap(Ruby runtime, RubyClass Object, RubyClass Class, String name) {
RubyClass clazz = new RubyClass(runtime, Object).
allocator(NOT_ALLOCATABLE_ALLOCATOR).
baseName(name);
clazz.makeMetaClass(Object.getMetaClass());
clazz.makeMetaClassBootstrap(runtime, Object.getMetaClass(), Class);
Object.defineConstantBootstrap(name, clazz);
return clazz;
}

@Deprecated(since = "10.0")
RubyClass toSingletonClass(RubyBasicObject target) {
return toSingletonClass(getCurrentContext(), target);
}

/**
* @see #singletonClass(ThreadContext)
*/
RubyClass toSingletonClass(RubyBasicObject target) {
RubyClass toSingletonClass(ThreadContext context, RubyBasicObject target) {
// replaced after makeMetaClass with MetaClass's toSingletonClass
return target.makeMetaClass(this);
return target.makeMetaClass(context, this);
}

static boolean notVisibleAndNotMethodMissing(DynamicMethod method, String name, IRubyObject caller, CallType callType) {
Expand Down Expand Up @@ -1066,12 +1071,12 @@ public IRubyObject initialize(ThreadContext context, IRubyObject superObject, Bl
private RubyClass initializeCommon(ThreadContext context, RubyClass superClazz, Block block) {
superClass(superClazz);
allocator = superClazz.allocator;
makeMetaClass(superClazz.getMetaClass());
makeMetaClass(context, superClazz.getMetaClass());
superClazz.addSubclass(this);

marshal = superClazz.marshal;

superClazz.invokeInherited(runtime.getCurrentContext(), superClazz, this);
superClazz.invokeInherited(context, superClazz, this);
super.initialize(context, block);

return this;
Expand Down Expand Up @@ -1431,7 +1436,7 @@ private void checkNotInitialized(ThreadContext context) {
*/
@Deprecated
public static void checkInheritable(IRubyObject superClass) {
checkInheritable(superClass.getRuntime().getCurrentContext(), superClass);
checkInheritable(((RubyBasicObject) superClass).getCurrentContext(), superClass);
}

public static void checkInheritable(ThreadContext context, IRubyObject superClass) {
Expand Down Expand Up @@ -2859,7 +2864,7 @@ public void smartDump(NewMarshal stream, ThreadContext context, NewMarshal.RubyO
// recache
CacheEntry entry = searchWithCache("respond_to?");
DynamicMethod method = entry.method;
if (!method.equals(runtime.getRespondToMethod()) && !method.isUndefined()) {
if (!method.equals(context.runtime.getRespondToMethod()) && !method.isUndefined()) {

// custom respond_to?, always do slow default marshaling
tuple = (cachedDumpMarshal = new MarshalTuple(null, MarshalType.DEFAULT_SLOW, generation));
Expand Down
Loading

0 comments on commit 45e9520

Please sign in to comment.