Skip to content

Commit 232f2a3

Browse files
committed
[GR-17457] Initialize RubyClass#instanceShape directly in the constructor
PullRequest: truffleruby/2110
2 parents 95af24a + 0410729 commit 232f2a3

File tree

7 files changed

+117
-117
lines changed

7 files changed

+117
-117
lines changed

src/main/java/org/truffleruby/core/CoreLibrary.java

Lines changed: 67 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.concurrent.ConcurrentHashMap;
2424
import java.util.concurrent.ConcurrentMap;
2525

26+
import com.oracle.truffle.api.object.Shape;
2627
import org.jcodings.specific.USASCIIEncoding;
2728
import org.jcodings.transcode.EConvFlags;
2829
import org.truffleruby.Layouts;
@@ -319,16 +320,12 @@ public CoreLibrary(RubyContext context) {
319320
// Create the cyclic classes and modules
320321

321322
classClass = ClassNodes.createClassClass(context);
322-
classClass.instanceShape = language.classShape;
323323

324-
basicObjectClass = ClassNodes.createBootClass(context, classClass, Nil.INSTANCE, "BasicObject");
325-
basicObjectClass.instanceShape = language.basicObjectShape;
326-
327-
objectClass = ClassNodes.createBootClass(context, classClass, basicObjectClass, "Object");
328-
objectClass.instanceShape = language.basicObjectShape;
329-
330-
moduleClass = ClassNodes.createBootClass(context, classClass, objectClass, "Module");
331-
moduleClass.instanceShape = language.moduleShape;
324+
basicObjectClass = ClassNodes
325+
.createBootClass(context, classClass, Nil.INSTANCE, "BasicObject", language.basicObjectShape);
326+
objectClass = ClassNodes
327+
.createBootClass(context, classClass, basicObjectClass, "Object", language.basicObjectShape);
328+
moduleClass = ClassNodes.createBootClass(context, classClass, objectClass, "Module", language.moduleShape);
332329

333330
// Close the cycles
334331
// Set superclass of Class to Module
@@ -343,8 +340,7 @@ public CoreLibrary(RubyContext context) {
343340
// Create Exception classes
344341

345342
// Exception
346-
exceptionClass = defineClass("Exception");
347-
exceptionClass.instanceShape = RubyLanguage.exceptionShape;
343+
exceptionClass = defineClass("Exception", RubyLanguage.exceptionShape);
348344

349345
// fatal
350346
defineClass(exceptionClass, "fatal");
@@ -384,14 +380,11 @@ public CoreLibrary(RubyContext context) {
384380
defineClass(ioErrorClass, "EOFError");
385381

386382
// StandardError > NameError
387-
nameErrorClass = defineClass(standardErrorClass, "NameError");
388-
nameErrorClass.instanceShape = RubyLanguage.nameErrorShape;
389-
noMethodErrorClass = defineClass(nameErrorClass, "NoMethodError");
390-
noMethodErrorClass.instanceShape = RubyLanguage.noMethodErrorShape;
383+
nameErrorClass = defineClass(standardErrorClass, "NameError", RubyLanguage.nameErrorShape);
384+
noMethodErrorClass = defineClass(nameErrorClass, "NoMethodError", RubyLanguage.noMethodErrorShape);
391385

392386
// StandardError > SystemCallError
393-
systemCallErrorClass = defineClass(standardErrorClass, "SystemCallError");
394-
systemCallErrorClass.instanceShape = RubyLanguage.systemCallErrorShape;
387+
systemCallErrorClass = defineClass(standardErrorClass, "SystemCallError", RubyLanguage.systemCallErrorShape);
395388

396389
errnoModule = defineModule("Errno");
397390

@@ -424,66 +417,49 @@ public CoreLibrary(RubyContext context) {
424417

425418
// Classes defined in Object
426419

427-
arrayClass = defineClass("Array");
428-
arrayClass.instanceShape = RubyLanguage.arrayShape;
429-
bindingClass = defineClass("Binding");
430-
bindingClass.instanceShape = RubyLanguage.bindingShape;
431-
RubyClass conditionVariableClass = defineClass("ConditionVariable");
432-
conditionVariableClass.instanceShape = RubyLanguage.conditionVariableShape;
420+
arrayClass = defineClass("Array", RubyLanguage.arrayShape);
421+
bindingClass = defineClass("Binding", RubyLanguage.bindingShape);
422+
defineClass("ConditionVariable", RubyLanguage.conditionVariableShape);
433423
defineClass("Data"); // Needed by Socket::Ifaddr and defined in core MRI
434424
dirClass = defineClass("Dir");
435-
encodingClass = defineClass("Encoding");
436-
encodingClass.instanceShape = RubyLanguage.encodingShape;
425+
encodingClass = defineClass("Encoding", RubyLanguage.encodingShape);
437426
falseClass = defineClass("FalseClass");
438-
fiberClass = defineClass("Fiber");
439-
fiberClass.instanceShape = RubyLanguage.fiberShape;
427+
fiberClass = defineClass("Fiber", RubyLanguage.fiberShape);
440428
defineModule("FileTest");
441-
hashClass = defineClass("Hash");
442-
hashClass.instanceShape = RubyLanguage.hashShape;
443-
matchDataClass = defineClass("MatchData");
444-
matchDataClass.instanceShape = RubyLanguage.matchDataShape;
445-
methodClass = defineClass("Method");
446-
methodClass.instanceShape = RubyLanguage.methodShape;
447-
RubyClass mutexClass = defineClass("Mutex");
448-
mutexClass.instanceShape = RubyLanguage.mutexShape;
429+
hashClass = defineClass("Hash", RubyLanguage.hashShape);
430+
matchDataClass = defineClass("MatchData", RubyLanguage.matchDataShape);
431+
methodClass = defineClass("Method", RubyLanguage.methodShape);
432+
defineClass("Mutex", RubyLanguage.mutexShape);
449433
nilClass = defineClass("NilClass");
450-
procClass = defineClass("Proc");
451-
procClass.instanceShape = RubyLanguage.procShape;
434+
procClass = defineClass("Proc", RubyLanguage.procShape);
452435

453436
processModule = defineModule("Process");
454-
RubyClass queueClass = defineClass("Queue");
455-
queueClass.instanceShape = RubyLanguage.queueShape;
456-
RubyClass sizedQueueClass = defineClass(queueClass, "SizedQueue");
457-
sizedQueueClass.instanceShape = RubyLanguage.sizedQueueShape;
458-
rangeClass = defineClass("Range");
459-
rangeClass.instanceShape = RubyLanguage.objectRangeShape;
460-
461-
regexpClass = defineClass("Regexp");
462-
regexpClass.instanceShape = RubyLanguage.regexpShape;
463-
stringClass = defineClass("String");
464-
stringClass.instanceShape = RubyLanguage.stringShape;
437+
RubyClass queueClass = defineClass("Queue", RubyLanguage.queueShape);
438+
defineClass(queueClass, "SizedQueue", RubyLanguage.sizedQueueShape);
439+
rangeClass = defineClass("Range", RubyLanguage.objectRangeShape);
440+
441+
regexpClass = defineClass("Regexp", RubyLanguage.regexpShape);
442+
stringClass = defineClass("String", RubyLanguage.stringShape);
465443
symbolClass = defineClass("Symbol");
466444

467-
threadClass = defineClass("Thread");
445+
threadClass = defineClass("Thread", RubyLanguage.threadShape);
468446
DynamicObjectLibrary.getUncached().put(threadClass, "@report_on_exception", true);
469447
DynamicObjectLibrary.getUncached().put(threadClass, "@abort_on_exception", false);
470-
threadClass.instanceShape = RubyLanguage.threadShape;
471448

472449
RubyClass threadBacktraceClass = defineClass(threadClass, objectClass, "Backtrace");
473-
threadBacktraceLocationClass = defineClass(threadBacktraceClass, objectClass, "Location");
474-
threadBacktraceLocationClass.instanceShape = RubyLanguage.threadBacktraceLocationShape;
475-
RubyClass timeClass = defineClass("Time");
476-
timeClass.instanceShape = RubyLanguage.timeShape;
450+
threadBacktraceLocationClass = defineClass(
451+
threadBacktraceClass,
452+
objectClass,
453+
"Location",
454+
RubyLanguage.threadBacktraceLocationShape);
455+
defineClass("Time", RubyLanguage.timeShape);
477456
trueClass = defineClass("TrueClass");
478-
unboundMethodClass = defineClass("UnboundMethod");
479-
unboundMethodClass.instanceShape = RubyLanguage.unboundMethodShape;
480-
ioClass = defineClass("IO");
481-
ioClass.instanceShape = RubyLanguage.ioShape;
457+
unboundMethodClass = defineClass("UnboundMethod", RubyLanguage.unboundMethodShape);
458+
ioClass = defineClass("IO", RubyLanguage.ioShape);
482459
defineClass(ioClass, "File");
483460
structClass = defineClass("Struct");
484461

485-
final RubyClass tracePointClass = defineClass("TracePoint");
486-
tracePointClass.instanceShape = RubyLanguage.tracePointShape;
462+
defineClass("TracePoint", RubyLanguage.tracePointShape);
487463

488464
// Modules
489465

@@ -494,8 +470,7 @@ public CoreLibrary(RubyContext context) {
494470
defineModule("Math");
495471
objectSpaceModule = defineModule("ObjectSpace");
496472

497-
weakMapClass = defineClass(objectSpaceModule, objectClass, "WeakMap");
498-
weakMapClass.instanceShape = RubyLanguage.weakMapShape;
473+
weakMapClass = defineClass(objectSpaceModule, objectClass, "WeakMap", RubyLanguage.weakMapShape);
499474

500475
// The rest
501476

@@ -505,11 +480,13 @@ public CoreLibrary(RubyContext context) {
505480
encodingErrorClass,
506481
"UndefinedConversionError");
507482

508-
encodingConverterClass = defineClass(encodingClass, objectClass, "Converter");
509-
encodingConverterClass.instanceShape = RubyLanguage.encodingConverterShape;
483+
encodingConverterClass = defineClass(
484+
encodingClass,
485+
objectClass,
486+
"Converter",
487+
RubyLanguage.encodingConverterShape);
510488
final RubyModule truffleRubyModule = defineModule("TruffleRuby");
511-
RubyClass atomicReferenceClass = defineClass(truffleRubyModule, objectClass, "AtomicReference");
512-
atomicReferenceClass.instanceShape = RubyLanguage.atomicReferenceShape;
489+
defineClass(truffleRubyModule, objectClass, "AtomicReference", RubyLanguage.atomicReferenceShape);
513490
truffleModule = defineModule("Truffle");
514491
truffleInternalModule = defineModule(truffleModule, "Internal");
515492
graalErrorClass = defineClass(truffleModule, exceptionClass, "GraalError");
@@ -559,33 +536,31 @@ public CoreLibrary(RubyContext context) {
559536
defineModule(truffleModule, "ReadlineHistory");
560537
truffleThreadOperationsModule = defineModule(truffleModule, "ThreadOperations");
561538
defineModule(truffleModule, "WeakRefOperations");
562-
handleClass = defineClass(truffleModule, objectClass, "Handle");
563-
handleClass.instanceShape = RubyLanguage.handleShape;
539+
handleClass = defineClass(truffleModule, objectClass, "Handle", RubyLanguage.handleShape);
564540
warningModule = defineModule("Warning");
565541

566-
bigDecimalClass = defineClass(numericClass, "BigDecimal");
567-
bigDecimalClass.instanceShape = RubyLanguage.bigDecimalShape;
542+
bigDecimalClass = defineClass(numericClass, "BigDecimal", RubyLanguage.bigDecimalShape);
568543
bigDecimalOperationsModule = defineModule(truffleModule, "BigDecimalOperations");
569544

570545
truffleFFIModule = defineModule(truffleModule, "FFI");
571546
RubyClass truffleFFIAbstractMemoryClass = defineClass(truffleFFIModule, objectClass, "AbstractMemory");
572-
truffleFFIPointerClass = defineClass(truffleFFIModule, truffleFFIAbstractMemoryClass, "Pointer");
573-
truffleFFIPointerClass.instanceShape = RubyLanguage.truffleFFIPointerShape;
547+
truffleFFIPointerClass = defineClass(
548+
truffleFFIModule,
549+
truffleFFIAbstractMemoryClass,
550+
"Pointer",
551+
RubyLanguage.truffleFFIPointerShape);
574552
truffleFFINullPointerErrorClass = defineClass(truffleFFIModule, runtimeErrorClass, "NullPointerError");
575553

576554
truffleTypeModule = defineModule(truffleModule, "Type");
577555

578-
byteArrayClass = defineClass(truffleModule, objectClass, "ByteArray");
579-
byteArrayClass.instanceShape = RubyLanguage.byteArrayShape;
556+
byteArrayClass = defineClass(truffleModule, objectClass, "ByteArray", RubyLanguage.byteArrayShape);
580557
defineClass(truffleModule, objectClass, "StringData");
581558
defineClass(encodingClass, objectClass, "Transcoding");
582-
randomizerClass = defineClass(truffleModule, objectClass, "Randomizer");
583-
randomizerClass.instanceShape = RubyLanguage.randomizerShape;
559+
randomizerClass = defineClass(truffleModule, objectClass, "Randomizer", RubyLanguage.randomizerShape);
584560

585561
// Standard library
586562

587-
digestClass = defineClass(truffleModule, basicObjectClass, "Digest");
588-
digestClass.instanceShape = RubyLanguage.digestShape;
563+
digestClass = defineClass(truffleModule, basicObjectClass, "Digest", RubyLanguage.digestShape);
589564

590565
// Include the core modules
591566

@@ -781,12 +756,24 @@ private RubyClass defineClass(String name) {
781756
return defineClass(objectClass, name);
782757
}
783758

759+
private RubyClass defineClass(String name, Shape instanceShape) {
760+
return defineClass(objectClass, name, instanceShape);
761+
}
762+
784763
private RubyClass defineClass(RubyClass superclass, String name) {
785-
return ClassNodes.createInitializedRubyClass(context, null, objectClass, superclass, name);
764+
return defineClass(superclass, name, superclass.instanceShape);
765+
}
766+
767+
private RubyClass defineClass(RubyClass superclass, String name, Shape instanceShape) {
768+
return ClassNodes.createInitializedRubyClass(context, null, objectClass, superclass, name, instanceShape);
786769
}
787770

788771
private RubyClass defineClass(RubyModule lexicalParent, RubyClass superclass, String name) {
789-
return ClassNodes.createInitializedRubyClass(context, null, lexicalParent, superclass, name);
772+
return defineClass(lexicalParent, superclass, name, superclass.instanceShape);
773+
}
774+
775+
private RubyClass defineClass(RubyModule lexicalParent, RubyClass superclass, String name, Shape instanceShape) {
776+
return ClassNodes.createInitializedRubyClass(context, null, lexicalParent, superclass, name, instanceShape);
790777
}
791778

792779
private RubyModule defineModule(String name) {

src/main/java/org/truffleruby/core/klass/ClassNodes.java

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*/
1010
package org.truffleruby.core.klass;
1111

12+
import com.oracle.truffle.api.object.Shape;
1213
import org.truffleruby.RubyContext;
1314
import org.truffleruby.builtins.CoreMethod;
1415
import org.truffleruby.builtins.CoreMethodArrayArgumentsNode;
@@ -53,8 +54,18 @@ public static RubyClass createClassClass(RubyContext context) {
5354
/** This constructor supports initialization and solves boot-order problems and should not normally be used from
5455
* outside this class. */
5556
@TruffleBoundary
56-
public static RubyClass createBootClass(RubyContext context, RubyClass classClass, Object superclass, String name) {
57-
final RubyClass rubyClass = new RubyClass(classClass, context, null, null, name, false, null, superclass);
57+
public static RubyClass createBootClass(RubyContext context, RubyClass classClass, Object superclass, String name,
58+
Shape instanceShape) {
59+
final RubyClass rubyClass = new RubyClass(
60+
classClass,
61+
context,
62+
null,
63+
null,
64+
name,
65+
false,
66+
null,
67+
superclass,
68+
instanceShape);
5869
rubyClass.fields.setFullName(name);
5970

6071
if (superclass != Nil.INSTANCE) {
@@ -81,12 +92,13 @@ public static RubyClass createSingletonClassOfObject(RubyContext context, Source
8192
superclass,
8293
name,
8394
true,
84-
attached));
95+
attached,
96+
null));
8597
}
8698

8799
@TruffleBoundary
88100
public static RubyClass createInitializedRubyClass(RubyContext context, SourceSection sourceSection,
89-
RubyModule lexicalParent, RubyClass superclass, String name) {
101+
RubyModule lexicalParent, RubyClass superclass, String name, Shape instanceShape) {
90102
assert superclass != null;
91103
final RubyClass rubyClass = createRubyClass(
92104
context,
@@ -96,7 +108,8 @@ public static RubyClass createInitializedRubyClass(RubyContext context, SourceSe
96108
superclass,
97109
name,
98110
false,
99-
null);
111+
null,
112+
instanceShape);
100113
ensureItHasSingletonClassCreated(context, rubyClass);
101114
return rubyClass;
102115
}
@@ -109,7 +122,8 @@ public static RubyClass createRubyClass(RubyContext context,
109122
RubyClass superclass,
110123
String name,
111124
boolean isSingleton,
112-
RubyDynamicObject attached) {
125+
RubyDynamicObject attached,
126+
Shape instanceShape) {
113127
assert superclass != null;
114128
final RubyClass rubyClass = new RubyClass(
115129
classClass,
@@ -119,7 +133,8 @@ public static RubyClass createRubyClass(RubyContext context,
119133
name,
120134
isSingleton,
121135
attached,
122-
superclass);
136+
superclass,
137+
instanceShape);
123138

124139
if (lexicalParent != null) {
125140
rubyClass.fields.getAdoptedByLexicalParent(context, lexicalParent, name, null);
@@ -129,11 +144,6 @@ public static RubyClass createRubyClass(RubyContext context,
129144

130145
rubyClass.setSuperClass(superclass);
131146

132-
// Singleton classes cannot be instantiated
133-
if (!isSingleton) {
134-
setInstanceShape(rubyClass, superclass);
135-
}
136-
137147
return rubyClass;
138148
}
139149

@@ -145,13 +155,20 @@ public static RubyClass createUninitializedRubyClass(RubyContext context,
145155
throw CompilerDirectives.shouldNotReachHere("Subclasses of class Class are forbidden in Ruby");
146156
}
147157

148-
final RubyClass rubyClass = new RubyClass(classClass, context, sourceSection, null, null, false, null, null);
158+
final RubyClass rubyClass = new RubyClass(
159+
classClass,
160+
context,
161+
sourceSection,
162+
null,
163+
null,
164+
false,
165+
null,
166+
null,
167+
context.getCoreLibrary().objectClass.instanceShape);
149168

150169
// For Class.allocate, set it in the fields but not in RubyClass#superclass to mark as not yet initialized
151170
rubyClass.fields.setSuperClass(context.getCoreLibrary().objectClass);
152171

153-
setInstanceShape(rubyClass, context.getCoreLibrary().objectClass);
154-
155172
assert !rubyClass.isInitialized();
156173
return rubyClass;
157174
}
@@ -161,15 +178,9 @@ public static void initialize(RubyContext context, RubyClass rubyClass, RubyClas
161178
assert !rubyClass.isSingleton : "Singleton classes can only be created internally";
162179

163180
rubyClass.setSuperClass(superclass);
181+
rubyClass.instanceShape = superclass.instanceShape;
164182

165183
ensureItHasSingletonClassCreated(context, rubyClass);
166-
167-
setInstanceShape(rubyClass, superclass);
168-
}
169-
170-
public static void setInstanceShape(RubyClass rubyClass, RubyClass baseClass) {
171-
assert !rubyClass.isSingleton : "Singleton classes cannot be instantiated";
172-
rubyClass.instanceShape = baseClass.instanceShape;
173184
}
174185

175186
private static RubyClass ensureItHasSingletonClassCreated(RubyContext context, RubyClass rubyClass) {
@@ -223,7 +234,8 @@ private static RubyClass createSingletonClass(RubyContext context, RubyClass rub
223234
singletonSuperclass,
224235
name,
225236
true,
226-
rubyClass);
237+
rubyClass,
238+
null);
227239
SharedObjects.propagate(context, rubyClass, metaClass);
228240
rubyClass.setMetaClass(metaClass);
229241

0 commit comments

Comments
 (0)