Skip to content

Commit 8f181ea

Browse files
committed
Collapse Shape class hierarchy.
1 parent 3fbceee commit 8f181ea

File tree

18 files changed

+1385
-1603
lines changed

18 files changed

+1385
-1603
lines changed

truffle/src/com.oracle.truffle.api.object.test/src/com/oracle/truffle/object/basic/test/DOTestAsserts.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,11 @@
4949
import java.util.HashMap;
5050
import java.util.Iterator;
5151
import java.util.Map;
52+
import java.util.NoSuchElementException;
5253
import java.util.regex.Matcher;
5354
import java.util.regex.Pattern;
5455
import java.util.stream.Collectors;
56+
import java.util.stream.Stream;
5557

5658
import org.junit.Assert;
5759

@@ -71,7 +73,9 @@ public static <T> T invokeGetter(String methodName, Object receiver) {
7173
@SuppressWarnings("unchecked")
7274
public static <T> T invokeMethod(String methodName, Object receiver, Object... args) {
7375
try {
74-
Method method = Arrays.stream(receiver.getClass().getMethods()).filter(m -> m.getName().equals(methodName)).findFirst().get();
76+
Method method = Stream.concat(Arrays.stream(receiver.getClass().getMethods()), Arrays.stream(receiver.getClass().getDeclaredMethods())).filter(
77+
m -> m.getName().equals(methodName)).findFirst().orElseThrow(
78+
() -> new NoSuchElementException("Method " + methodName + " not found in " + receiver.getClass()));
7579
method.setAccessible(true);
7680
return (T) method.invoke(receiver, args);
7781
} catch (IllegalAccessException | InvocationTargetException e) {
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package com.oracle.truffle.api.object;
42+
43+
abstract sealed class BaseAllocator implements LocationImpl.LocationVisitor permits ExtAllocator {
44+
protected final LayoutImpl layout;
45+
protected int objectArraySize;
46+
protected int objectFieldSize;
47+
protected int primitiveFieldSize;
48+
protected int primitiveArraySize;
49+
protected int depth;
50+
protected boolean shared;
51+
52+
protected BaseAllocator(LayoutImpl layout) {
53+
this.layout = layout;
54+
}
55+
56+
protected BaseAllocator(Shape shape) {
57+
this(shape.getLayout());
58+
this.objectArraySize = shape.getObjectArraySize();
59+
this.objectFieldSize = shape.getObjectFieldSize();
60+
this.primitiveFieldSize = shape.getPrimitiveFieldSize();
61+
this.primitiveArraySize = shape.getPrimitiveArraySize();
62+
this.depth = shape.getDepth();
63+
this.shared = shape.isShared();
64+
}
65+
66+
protected abstract Location moveLocation(Location oldLocation);
67+
68+
/**
69+
* Creates a new location from a constant value. The value is stored in the shape rather than in
70+
* the object.
71+
*
72+
* @param value the constant value
73+
*/
74+
public Location constantLocation(Object value) {
75+
throw new UnsupportedOperationException();
76+
}
77+
78+
/**
79+
* Creates a new declared location with a default value. A declared location only assumes a type
80+
* after the first set (initialization).
81+
* <p>
82+
* Used by tests.
83+
*
84+
* @param value the default value
85+
*/
86+
public Location declaredLocation(Object value) {
87+
throw new UnsupportedOperationException();
88+
}
89+
90+
/**
91+
* Creates a new location compatible with the given initial value.
92+
* <p>
93+
* Used by tests.
94+
*/
95+
public abstract Location locationForValue(Object value);
96+
97+
protected abstract Location locationForValueUpcast(Object value, Location oldLocation, int putFlags);
98+
99+
/**
100+
* Creates a new location for a fixed type. It can only be assigned to values of this type.
101+
* <p>
102+
* Used by tests.
103+
*
104+
* @param type the Java type this location must be compatible with (may be primitive)
105+
*/
106+
public abstract Location locationForType(Class<?> type);
107+
108+
protected <T extends Location> T advance(T location0) {
109+
if (location0 instanceof LocationImpl location) {
110+
location.accept(this);
111+
assert layout.hasPrimitiveExtensionArray() || primitiveArraySize == 0;
112+
}
113+
depth++;
114+
return location0;
115+
}
116+
117+
/**
118+
* Reserves space for the given location, so that it will not be available to subsequently
119+
* allocated locations.
120+
*/
121+
public BaseAllocator addLocation(Location location) {
122+
advance(location);
123+
return this;
124+
}
125+
126+
@Override
127+
public void visitObjectField(int index, int count) {
128+
objectFieldSize = Math.max(objectFieldSize, index + count);
129+
}
130+
131+
@Override
132+
public void visitObjectArray(int index, int count) {
133+
objectArraySize = Math.max(objectArraySize, index + count);
134+
}
135+
136+
@Override
137+
public void visitPrimitiveArray(int index, int count) {
138+
primitiveArraySize = Math.max(primitiveArraySize, index + count);
139+
}
140+
141+
@Override
142+
public void visitPrimitiveField(int index, int count) {
143+
primitiveFieldSize = Math.max(primitiveFieldSize, index + count);
144+
}
145+
}

truffle/src/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/Debug.java

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,11 @@
5454
import java.util.Set;
5555
import java.util.concurrent.ConcurrentLinkedQueue;
5656

57-
@SuppressWarnings("deprecation")
5857
class Debug {
5958

60-
private static Collection<ShapeImpl> allShapes;
59+
private static Collection<Shape> allShapes;
6160

62-
static void trackShape(ShapeImpl newShape) {
61+
static void trackShape(Shape newShape) {
6362
allShapes.add(newShape);
6463
}
6564

@@ -68,14 +67,14 @@ static void trackObject(DynamicObject obj) {
6867
ShapeProfiler.getInstance().track(obj);
6968
}
7069

71-
static Iterable<ShapeImpl> getAllShapes() {
70+
static Iterable<Shape> getAllShapes() {
7271
return allShapes;
7372
}
7473

7574
private static void dumpDOT() throws FileNotFoundException, UnsupportedEncodingException {
7675
try (PrintWriter out = new PrintWriter(getOutputFile("dot"), "UTF-8")) {
7776
GraphvizShapeVisitor visitor = new GraphvizShapeVisitor();
78-
for (ShapeImpl shape : getAllShapes()) {
77+
for (Shape shape : getAllShapes()) {
7978
visitor.visitShape(shape);
8079
}
8180
out.println(visitor);
@@ -91,13 +90,13 @@ static String getId(Shape shape) {
9190
}
9291

9392
interface DebugShapeVisitor<R> {
94-
default R visitShape(ShapeImpl shape) {
95-
Map<Transition, ShapeImpl> snapshot = new LinkedHashMap<>();
93+
default R visitShape(Shape shape) {
94+
Map<Transition, Shape> snapshot = new LinkedHashMap<>();
9695
shape.forEachTransition(snapshot::put);
9796
return visitShape(shape, Collections.unmodifiableMap(snapshot));
9897
}
9998

100-
R visitShape(ShapeImpl shape, Map<? extends Transition, ? extends ShapeImpl> transitions);
99+
R visitShape(Shape shape, Map<? extends Transition, ? extends Shape> transitions);
101100
}
102101

103102
static class GraphvizShapeVisitor implements DebugShapeVisitor<GraphvizShapeVisitor> {
@@ -109,7 +108,7 @@ static class GraphvizShapeVisitor implements DebugShapeVisitor<GraphvizShapeVisi
109108
}
110109

111110
@Override
112-
public GraphvizShapeVisitor visitShape(ShapeImpl shape, Map<? extends Transition, ? extends ShapeImpl> transitions) {
111+
public GraphvizShapeVisitor visitShape(Shape shape, Map<? extends Transition, ? extends Shape> transitions) {
113112
if (!drawn.add(shape)) {
114113
return this;
115114
}
@@ -139,8 +138,8 @@ public GraphvizShapeVisitor visitShape(ShapeImpl shape, Map<? extends Transition
139138
}
140139
sb.append("];");
141140

142-
for (Entry<? extends Transition, ? extends ShapeImpl> entry : transitions.entrySet()) {
143-
ShapeImpl dst = entry.getValue();
141+
for (Entry<? extends Transition, ? extends Shape> entry : transitions.entrySet()) {
142+
Shape dst = entry.getValue();
144143
this.visitShape(dst);
145144
assert drawn.contains(dst);
146145

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package com.oracle.truffle.api.object;
42+
43+
final class DebugCounters {
44+
private DebugCounters() {
45+
}
46+
47+
static final DebugCounter shapeCount = DebugCounter.create("Shapes allocated total");
48+
static final DebugCounter shapeCacheHitCount = DebugCounter.create("Shape cache hits");
49+
static final DebugCounter shapeCacheMissCount = DebugCounter.create("Shape cache misses");
50+
static final DebugCounter shapeCacheExpunged = DebugCounter.create("Shape cache expunged");
51+
static final DebugCounter shapeCacheWeakKeys = DebugCounter.create("Shape cache weak keys");
52+
static final DebugCounter propertyAssumptionsCreated = DebugCounter.create("Property assumptions created");
53+
static final DebugCounter propertyAssumptionsRemoved = DebugCounter.create("Property assumptions removed");
54+
static final DebugCounter propertyAssumptionsBlocked = DebugCounter.create("Property assumptions blocked");
55+
static final DebugCounter transitionSingleEntriesCreated = DebugCounter.create("Transition single-entry maps created");
56+
static final DebugCounter transitionMapsCreated = DebugCounter.create("Transition multi-entry maps created");
57+
}

0 commit comments

Comments
 (0)