Skip to content

Commit

Permalink
Store encoding symbols in SymbolTable
Browse files Browse the repository at this point in the history
This is the first of many globally-used symbols to be added to the
SymbolTable. This commit also moves creation of the SymbolTable to
just after the creation of the Symbol class, so these global
symbols can be final references.
  • Loading branch information
headius committed May 26, 2024
1 parent a0c98df commit ca1a856
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 6 deletions.
3 changes: 2 additions & 1 deletion core/src/main/java/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@ private Ruby(RubyInstanceConfig config) {
encodingService = new EncodingService(this);

symbolClass = RubySymbol.createSymbolClass(this);
symbolTable = new RubySymbol.SymbolTable(this);

threadGroupClass = profile.allowClass("ThreadGroup") ? RubyThreadGroup.createThreadGroupClass(this) : null;
threadClass = profile.allowClass("Thread") ? RubyThread.createThreadClass(this) : null;
Expand Down Expand Up @@ -5349,7 +5350,7 @@ public RubyClass getData() {

private final ObjectSpace objectSpace = new ObjectSpace();

private final RubySymbol.SymbolTable symbolTable = new RubySymbol.SymbolTable(this);
private final RubySymbol.SymbolTable symbolTable;

private boolean abortOnException = false; // Thread.abort_on_exception
private boolean reportOnException = true; // Thread.report_on_exception
Expand Down
27 changes: 27 additions & 0 deletions core/src/main/java/org/jruby/RubySymbol.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import org.jruby.runtime.callsite.RefinedCachingCallSite;
import org.jruby.runtime.encoding.EncodingCapable;
import org.jruby.runtime.encoding.MarshalEncoding;
import org.jruby.runtime.marshal.MarshalCommon;
import org.jruby.runtime.marshal.UnmarshalStream;
import org.jruby.runtime.opto.OptoFactory;
import org.jruby.util.ByteList;
Expand Down Expand Up @@ -1005,12 +1006,16 @@ public static final class SymbolTable {
private int threshold;
private final float loadFactor;
private final Ruby runtime;
private final RubySymbol encodingSymbolE;
private final RubySymbol encodingSymbol;

public SymbolTable(Ruby runtime) {
this.runtime = runtime;
this.loadFactor = DEFAULT_LOAD_FACTOR;
this.threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
this.symbolTable = new SymbolEntry[DEFAULT_INITIAL_CAPACITY];
this.encodingSymbolE = createSymbol(MarshalCommon.SYMBOL_ENCODING_SPECIAL, false);
this.encodingSymbol = createSymbol(MarshalCommon.SYMBOL_ENCODING, false);
}

// note all fields are final -- rehash creates new entries when necessary.
Expand Down Expand Up @@ -1064,6 +1069,20 @@ public RubySymbol getSymbol(String name, boolean hard) {
return symbol;
}

/**
* Create a new symbol without looking for an existing one.
*
* Primarily used for core symbols used repeatedly from Java. Use only when you know there is no existing
* symbol.
*
* @param name name of the symbol
* @param hard whether to mark it as a hard reference
* @return a new symbol after inserting it into the symbol table
*/
public RubySymbol createSymbol(String name, boolean hard) {
return createSymbol(name, symbolBytesFromString(runtime, name), javaStringHashCode(name), hard);
}

public RubySymbol getSymbol(ByteList bytes) {
return getSymbol(bytes, false);
}
Expand Down Expand Up @@ -1192,6 +1211,14 @@ public RubySymbol fastGetSymbol(String internedName, boolean hard) {
return symbol;
}

public RubySymbol getEncodingSymbolE() {
return encodingSymbolE;
}

public RubySymbol getEncodingSymbol() {
return encodingSymbol;
}

private static SymbolEntry getEntryFromTable(SymbolEntry[] table, int hash) {
return table[getIndex(hash, table)];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class MarshalCommon {
static final char TYPE_IVAR = 'I';
static final char TYPE_LINK = '@';

static final String SYMBOL_ENCODING_SPECIAL = "E";
static final String SYMBOL_ENCODING = "encoding";
public static final String SYMBOL_ENCODING_SPECIAL = "E";
public static final String SYMBOL_ENCODING = "encoding";
static final String RUBY2_KEYWORDS_FLAG = "K";
}
6 changes: 3 additions & 3 deletions core/src/main/java/org/jruby/runtime/marshal/NewMarshal.java
Original file line number Diff line number Diff line change
Expand Up @@ -557,13 +557,13 @@ private static void dumpVariable(NewMarshal marshal, ThreadContext context, Ruby
public void writeEncoding(ThreadContext context, RubyOutputStream out, Encoding encoding) {
Ruby runtime = context.runtime;
if (encoding == null || encoding == USASCIIEncoding.INSTANCE) {
writeAndRegisterSymbol(out, RubySymbol.newSymbol(runtime, SYMBOL_ENCODING_SPECIAL));
writeAndRegisterSymbol(out, runtime.getSymbolTable().getEncodingSymbolE());
writeObjectData(context, out, runtime.getFalse());
} else if (encoding == UTF8Encoding.INSTANCE) {
writeAndRegisterSymbol(out, RubySymbol.newSymbol(runtime, SYMBOL_ENCODING_SPECIAL));
writeAndRegisterSymbol(out, runtime.getSymbolTable().getEncodingSymbolE());
writeObjectData(context, out, runtime.getTrue());
} else {
writeAndRegisterSymbol(out, RubySymbol.newSymbol(runtime, SYMBOL_ENCODING));
writeAndRegisterSymbol(out, runtime.getSymbolTable().getEncodingSymbol());
RubyString encodingString = new RubyString(runtime, runtime.getString(), encoding.getName());
writeObjectData(context, out, encodingString);
}
Expand Down

0 comments on commit ca1a856

Please sign in to comment.