Skip to content

Commit bbdc90b

Browse files
committed
Start moving shape reference into shaped objects
In order to evolve the shape of objects as more instance variables are discovered, we need to be able to access multiple different shaped instances with their own layouts. Previously, only one shape could be associated with a given class, based on a static inspection of all instance variable accesses in the class's hierarchy. In order to keep stale-shaped objects functional, this commit adds a shape reference to all shaped RubyObject subtypes. With this we can allocate a first object using no instance vars (falling back on the default varTable layout) and as instance vars are encountered modify allocation to create wider object shapes. The step here simply adds the shape reference to all shaped objects; evolving that shape and updating the allocator will come in future commits.
1 parent ba72707 commit bbdc90b

File tree

3 files changed

+75
-12
lines changed

3 files changed

+75
-12
lines changed

core/src/main/java/org/jruby/RubyBasicObject.java

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,10 @@ public static RubyClass getMetaClass(IRubyObject arg) {
467467
return ((RubyBasicObject) arg).metaClass;
468468
}
469469

470+
public VariableTableManager getShape() {
471+
return metaClass.getVariableTableManager();
472+
}
473+
470474
/** rb_singleton_class
471475
*
472476
* Note: this method is specialized for RubyFixnum, RubySymbol,
@@ -1045,7 +1049,7 @@ public IRubyObject id() {
10451049
* object is frozen.
10461050
*/
10471051
protected long getObjectId() {
1048-
return metaClass.getRealClass().getVariableTableManager().getObjectId(this);
1052+
return getShape().getObjectId(this);
10491053
}
10501054

10511055
/** rb_obj_inspect
@@ -1123,7 +1127,7 @@ private RubyString inspectObj(final Ruby runtime, RubyString part) {
11231127
final ThreadContext context = runtime.getCurrentContext();
11241128

11251129
boolean first = true;
1126-
for (Map.Entry<String, VariableAccessor> entry : metaClass.getVariableTableManager().getVariableAccessorsForRead().entrySet()) {
1130+
for (Map.Entry<String, VariableAccessor> entry : getShape().getVariableAccessorsForRead().entrySet()) {
11271131
Object value = entry.getValue().get(this);
11281132
if (!(value instanceof IRubyObject)) continue;
11291133
RubySymbol symbol = runtime.newSymbol(entry.getKey());
@@ -1281,15 +1285,15 @@ public Object getVariable(int index) {
12811285
public void setVariable(int index, Object value) {
12821286
ensureInstanceVariablesSettable();
12831287
if (index < 0) return;
1284-
metaClass.getVariableTableManager().setVariableInternal(this, index, value);
1288+
getShape().setVariableInternal(this, index, value);
12851289
}
12861290

12871291
public final Object getFFIHandle() {
1288-
return metaClass.getVariableTableManager().getFFIHandle(this);
1292+
return getShape().getFFIHandle(this);
12891293
}
12901294

12911295
public final void setFFIHandle(Object value) {
1292-
metaClass.getVariableTableManager().setFFIHandle(this, value);
1296+
getShape().setFFIHandle(this, value);
12931297
}
12941298

12951299
//
@@ -1303,7 +1307,7 @@ public final void setFFIHandle(Object value) {
13031307
*/
13041308
@Override
13051309
public boolean hasVariables() {
1306-
return metaClass.getVariableTableManager().hasVariables(this);
1310+
return getShape().hasVariables(this);
13071311
}
13081312

13091313
/**
@@ -1313,7 +1317,7 @@ public boolean hasVariables() {
13131317
* @return true if there are set instance variables, false otherwise
13141318
*/
13151319
protected boolean hasInstanceVariables() {
1316-
return metaClass.getVariableTableManager().hasInstanceVariables(this);
1320+
return getShape().hasInstanceVariables(this);
13171321
}
13181322

13191323
/**
@@ -1376,7 +1380,7 @@ protected Object variableTableStore(String name, Object value) {
13761380
* table, and returning the removed value.
13771381
*/
13781382
protected Object variableTableRemove(String name) {
1379-
return metaClass.getVariableTableManager().clearVariable(this, name);
1383+
return getShape().clearVariable(this, name);
13801384
}
13811385

13821386
/**
@@ -1447,7 +1451,7 @@ public Object removeInternalVariable(String name) {
14471451
*/
14481452
@Override
14491453
public void syncVariables(IRubyObject other) {
1450-
metaClass.getVariableTableManager().syncVariables(this, other);
1454+
getShape().syncVariables(this, other);
14511455
}
14521456

14531457
//
@@ -2956,7 +2960,7 @@ private void writeObject(ObjectOutputStream oos) throws IOException {
29562960
oos.defaultWriteObject();
29572961
oos.writeUTF(metaClass.getName());
29582962

2959-
metaClass.getVariableTableManager().serializeVariables(this, oos);
2963+
getShape().serializeVariables(this, oos);
29602964
}
29612965

29622966
/**
@@ -2982,7 +2986,7 @@ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFound
29822986
ois.defaultReadObject();
29832987
metaClass = (RubyClass)ruby.getClassFromPath(ois.readUTF());
29842988

2985-
metaClass.getVariableTableManager().deserializeVariables(this, ois);
2989+
getShape().deserializeVariables(this, ois);
29862990
}
29872991

29882992
/**
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
***** BEGIN LICENSE BLOCK *****
3+
* Version: EPL 2.0/GPL 2.0/LGPL 2.1
4+
*
5+
* The contents of this file are subject to the Eclipse Public
6+
* License Version 2.0 (the "License"); you may not use this file
7+
* except in compliance with the License. You may obtain a copy of
8+
* the License at http://www.eclipse.org/legal/epl-v20.html
9+
*
10+
* Software distributed under the License is distributed on an "AS
11+
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
12+
* implied. See the License for the specific language governing
13+
* rights and limitations under the License.
14+
*
15+
* Copyright (C) 2001 Chad Fowler <chadfowler@chadfowler.com>
16+
* Copyright (C) 2001 Alan Moore <alan_moore@gmx.net>
17+
* Copyright (C) 2001-2002 Benoit Cerrina <b.cerrina@wanadoo.fr>
18+
* Copyright (C) 2001-2004 Jan Arne Petersen <jpetersen@uni-bonn.de>
19+
* Copyright (C) 2002-2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
20+
* Copyright (C) 2004-2006 Thomas E Enebo <enebo@acm.org>
21+
* Copyright (C) 2004-2005 Charles O Nutter <headius@headius.com>
22+
* Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
23+
* Copyright (C) 2006 Ola Bini <ola.bini@ki.se>
24+
* Copyright (C) 2006 Miguel Covarrubias <mlcovarrubias@gmail.com>
25+
* Copyright (C) 2007 MenTaLguY <mental@rydia.net>
26+
* Copyright (C) 2007 William N Dortch <bill.dortch@gmail.com>
27+
*
28+
* Alternatively, the contents of this file may be used under the terms of
29+
* either of the GNU General Public License Version 2 or later (the "GPL"),
30+
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31+
* in which case the provisions of the GPL or the LGPL are applicable instead
32+
* of those above. If you wish to allow use of your version of this file only
33+
* under the terms of either the GPL or the LGPL, and not to allow others to
34+
* use your version of this file under the terms of the EPL, indicate your
35+
* decision by deleting the provisions above and replace them with the notice
36+
* and other provisions required by the GPL or the LGPL. If you do not delete
37+
* the provisions above, a recipient may use your version of this file under
38+
* the terms of any one of the EPL, the GPL or the LGPL.
39+
***** END LICENSE BLOCK *****/
40+
41+
package org.jruby;
42+
43+
import org.jruby.runtime.ivars.VariableTableManager;
44+
45+
public abstract class RubyObjectShaped extends RubyObject {
46+
public RubyObjectShaped(Ruby runtime, RubyClass metaClass) {
47+
super(runtime, metaClass);
48+
49+
variableTableManager = metaClass.getVariableTableManager();
50+
}
51+
52+
@Override
53+
public VariableTableManager getShape() {
54+
return variableTableManager;
55+
}
56+
57+
private final VariableTableManager variableTableManager;
58+
}

core/src/main/java/org/jruby/specialized/RubyObjectSpecializer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.jruby.Ruby;
3333
import org.jruby.RubyClass;
3434
import org.jruby.RubyObject;
35+
import org.jruby.RubyObjectShaped;
3536
import org.jruby.runtime.Helpers;
3637
import org.jruby.runtime.ObjectAllocator;
3738
import org.jruby.runtime.builtin.IRubyObject;
@@ -157,7 +158,7 @@ public static ObjectAllocator specializeForVariables(RubyClass klass, Set<String
157158

158159
private static Class generateInternal(int size, final String clsPath) {
159160
// ensure only one thread will attempt to generate and define the new class
160-
final String baseName = p(RubyObject.class);
161+
final String baseName = p(RubyObjectShaped.class);
161162

162163
final JiteClass jiteClass = new JiteClass(clsPath, baseName, new String[0]) {{
163164
for (int i = 0; i < size; i++) {

0 commit comments

Comments
 (0)