Skip to content

Commit 0862980

Browse files
committed
[GR-18163] Fix ObjectSpace._id2ref for Symbols and frozen String literals (#2358)
PullRequest: truffleruby/2666
2 parents a0c75e8 + beb45b8 commit 0862980

File tree

7 files changed

+54
-15
lines changed

7 files changed

+54
-15
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Compatibility:
2828
* Implement `Fiber#raise` (#2338).
2929
* Update `File.basename` to return new `String` instances (#2343).
3030
* Allow `Fiber#raise` after `Fiber#transfer` like Ruby 3.0 (#2342).
31+
* Fix `ObjectSpace._id2ref` for Symbols and frozen String literals (#2358).
3132

3233
Performance:
3334

spec/ruby/core/objectspace/_id2ref_spec.rb

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,43 @@
77
r.should == s
88
end
99

10-
it "retrieves an Integer by object_id" do
11-
f = 1
12-
r = ObjectSpace._id2ref(f.object_id)
13-
r.should == f
10+
it "retrieves true by object_id" do
11+
ObjectSpace._id2ref(true.object_id).should == true
12+
end
13+
14+
it "retrieves false by object_id" do
15+
ObjectSpace._id2ref(false.object_id).should == false
16+
end
17+
18+
it "retrieves nil by object_id" do
19+
ObjectSpace._id2ref(nil.object_id).should == nil
20+
end
21+
22+
it "retrieves a small Integer by object_id" do
23+
ObjectSpace._id2ref(1.object_id).should == 1
24+
ObjectSpace._id2ref((-42).object_id).should == -42
25+
end
26+
27+
it "retrieves a large Integer by object_id" do
28+
obj = 1 << 88
29+
ObjectSpace._id2ref(obj.object_id).should.equal?(obj)
1430
end
1531

1632
it "retrieves a Symbol by object_id" do
17-
s = :sym
18-
r = ObjectSpace._id2ref(s.object_id)
19-
r.should == s
33+
ObjectSpace._id2ref(:sym.object_id).should.equal?(:sym)
34+
end
35+
36+
it "retrieves a String by object_id" do
37+
obj = "str"
38+
ObjectSpace._id2ref(obj.object_id).should.equal?(obj)
39+
end
40+
41+
it "retrieves a frozen literal String by object_id" do
42+
ObjectSpace._id2ref("frozen string literal _id2ref".freeze.object_id).should.equal?("frozen string literal _id2ref".freeze)
43+
end
44+
45+
it "retrieves an Encoding by object_id" do
46+
ObjectSpace._id2ref(Encoding::UTF_8.object_id).should.equal?(Encoding::UTF_8)
2047
end
2148

2249
it 'raises RangeError when an object could not be found' do

src/main/java/org/truffleruby/core/objectspace/ObjectSpaceNodes.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.truffleruby.core.proc.RubyProc;
2626
import org.truffleruby.core.string.StringUtils;
2727
import org.truffleruby.core.symbol.RubySymbol;
28+
import org.truffleruby.language.ImmutableRubyObject;
2829
import org.truffleruby.language.NotProvided;
2930
import org.truffleruby.language.RubyDynamicObject;
3031
import org.truffleruby.language.RubyGuards;
@@ -80,8 +81,8 @@ protected Object id2Ref(long id) {
8081
long objectID = 0L;
8182
if (object instanceof RubyDynamicObject) {
8283
objectID = ObjectSpaceManager.readObjectID((RubyDynamicObject) object, objectLibrary);
83-
} else if (object instanceof RubySymbol) {
84-
objectID = ((RubySymbol) object).getObjectId();
84+
} else if (object instanceof ImmutableRubyObject) {
85+
objectID = ((ImmutableRubyObject) object).getObjectId();
8586
}
8687

8788
if (objectID == id) {

src/main/java/org/truffleruby/core/string/FrozenStringLiterals.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
import org.truffleruby.core.rope.Rope;
1818
import org.truffleruby.core.rope.RopeCache;
1919

20+
import java.util.Collection;
21+
2022
public class FrozenStringLiterals {
2123

2224
private final RopeCache ropeCache;
@@ -44,4 +46,9 @@ public ImmutableRubyString getFrozenStringLiteral(byte[] bytes, Encoding encodin
4446
}
4547
}
4648

49+
@TruffleBoundary
50+
public Collection<ImmutableRubyString> allFrozenStrings() {
51+
return values.values();
52+
}
53+
4754
}

src/main/java/org/truffleruby/core/symbol/SymbolNodes.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,11 @@ public abstract class SymbolNodes {
6363

6464
@CoreMethod(names = "all_symbols", onSingleton = true)
6565
public abstract static class AllSymbolsNode extends CoreMethodArrayArgumentsNode {
66-
66+
@TruffleBoundary
6767
@Specialization
6868
protected RubyArray allSymbols() {
69-
return createArray(getLanguage().symbolTable.allSymbols());
69+
return createArray(getLanguage().symbolTable.allSymbols().toArray());
7070
}
71-
7271
}
7372

7473
@CoreMethod(names = { "==", "eql?" }, required = 1)

src/main/java/org/truffleruby/core/symbol/SymbolTable.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,9 @@ public static String checkClassVariableName(
151151
}
152152

153153
@TruffleBoundary
154-
public Object[] allSymbols() {
155-
final Collection<RubySymbol> allSymbols = symbolMap.values();
154+
public Collection<RubySymbol> allSymbols() {
156155
// allSymbols is a private concrete collection not a view
157-
return allSymbols.toArray();
156+
return symbolMap.values();
158157
}
159158

160159
}

src/main/java/org/truffleruby/language/objects/ObjectGraph.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import java.util.Set;
1818

1919
import org.truffleruby.RubyContext;
20+
import org.truffleruby.RubyLanguage;
2021
import org.truffleruby.core.proc.RubyProc;
2122
import org.truffleruby.language.ImmutableRubyObject;
2223
import org.truffleruby.language.RubyDynamicObject;
@@ -112,6 +113,10 @@ public static Set<Object> stopAndGetRootObjects(String reason, RubyContext conte
112113
}
113114

114115
public static void visitContextRoots(RubyContext context, Set<Object> roots) {
116+
final RubyLanguage language = context.getLanguageSlow();
117+
roots.addAll(language.symbolTable.allSymbols());
118+
roots.addAll(language.frozenStringLiterals.allFrozenStrings());
119+
115120
// We do not want to expose the global object
116121
roots.addAll(context.getCoreLibrary().globalVariables.objectGraphValues());
117122
roots.addAll(context.getAtExitManager().getHandlers());

0 commit comments

Comments
 (0)