Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 246edd70fdbe
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0e392a9d7003
Choose a head ref
  • 8 commits
  • 21 files changed
  • 1 contributor

Commits on Apr 3, 2016

  1. Spec that frozen string literals don't change what defined? returns, …

    …to protect against implementations that desugar the call away.
    chrisseaton committed Apr 3, 2016
    Copy the full SHA
    a86c01e View commit details
  2. Copy the full SHA
    a2b6480 View commit details
  3. Copy the full SHA
    c3c20a1 View commit details
  4. Copy the full SHA
    7ca922c View commit details
  5. Copy the full SHA
    07fa8a4 View commit details
  6. Copy the full SHA
    321bb75 View commit details
  7. Copy the full SHA
    b211f5d View commit details
  8. Copy the full SHA
    0e392a9 View commit details
3 changes: 0 additions & 3 deletions spec/ruby/command_line/frozen_strings_tags.txt

This file was deleted.

4 changes: 4 additions & 0 deletions spec/ruby/core/string/freeze_spec.rb
Original file line number Diff line number Diff line change
@@ -11,4 +11,8 @@
"abc".object_id.should_not == "abc".object_id
end

it "being a special form doesn't change the value of defined?" do
defined?("abc".freeze).should == "method"
end

end
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 0 additions & 1 deletion spec/truffle/tags/core/string/freeze_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/language/string_tags.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
fails:Ruby String literals with a magic frozen comment produce the same object each time
slow:Ruby String literals with a magic frozen comment produce the same object each time
fails:Ruby String literals with a magic frozen comment produce the same object for literals with the same content
slow:Ruby String literals with a magic frozen comment produce the same object for literals with the same content
fails:Ruby String literals with a magic frozen comment produce the same object for literals with the same content in different files
slow:Ruby String literals with a magic frozen comment produce the same object for literals with the same content in different files
1 change: 1 addition & 0 deletions spec/truffle/truffle.mspec
Original file line number Diff line number Diff line change
@@ -71,6 +71,7 @@ class MSpecScript
set :backtrace_filter, /mspec\//

set :tags_patterns, [
[%r(^.*/command_line/), 'spec/truffle/tags/command_line/'],
[%r(^.*/language/), 'spec/truffle/tags/language/'],
[%r(^.*/core/), 'spec/truffle/tags/core/'],
[%r(^.*/library/), 'spec/truffle/tags/library/'],
6 changes: 6 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/RubyContext.java
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@
import org.jruby.truffle.core.rope.RopeTable;
import org.jruby.truffle.core.rubinius.RubiniusPrimitiveManager;
import org.jruby.truffle.core.string.CoreStrings;
import org.jruby.truffle.core.string.FrozenStrings;
import org.jruby.truffle.core.symbol.SymbolTable;
import org.jruby.truffle.core.thread.ThreadManager;
import org.jruby.truffle.extra.AttachmentsManager;
@@ -76,6 +77,7 @@ public class RubyContext extends ExecutionContext {
private final SourceCache sourceCache = new SourceCache(new SourceLoader(this));
private final CallStackManager callStack = new CallStackManager(this);
private final CoreStrings coreStrings = new CoreStrings(this);
private final FrozenStrings frozenStrings = new FrozenStrings(this);

private final CompilerOptions compilerOptions = Truffle.getRuntime().createCompilerOptions();

@@ -332,6 +334,10 @@ public CoreStrings getCoreStrings() {
return coreStrings;
}

public FrozenStrings getFrozenStrings() {
return frozenStrings;
}

public Object getClassVariableDefinitionLock() {
return classVariableDefinitionLock;
}
17 changes: 17 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/core/rope/RopeTable.java
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.locks.ReadWriteLock;
@@ -102,6 +103,22 @@ public Rope getRope(byte[] bytes, Encoding encoding, CodeRange codeRange) {
}
}

public boolean contains(Rope rope) {
lock.readLock().lock();

try {
for (Map.Entry<Key, WeakReference<Rope>> entry : ropesTable.entrySet()) {
if (entry.getValue().get() == rope) {
return true;
}
}
} finally {
lock.readLock().unlock();
}

return false;
}

public int getByteArrayReusedCount() {
return byteArrayReusedCount;
}
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@ public class CoreStrings {
public final CoreString GLOBAL_VARIABLE;
public final CoreString INSTANCE_VARIABLE;
public final CoreString LOCAL_VARIABLE;
public final CoreString METHOD;
public final CoreString NIL;
public final CoreString SELF;
public final CoreString TRUE;
@@ -33,6 +34,7 @@ public CoreStrings(RubyContext context) {
GLOBAL_VARIABLE = new CoreString(context, "global-variable");
INSTANCE_VARIABLE = new CoreString(context, "instance-variable");
LOCAL_VARIABLE = new CoreString(context, "local-variable");
METHOD = new CoreString(context, "method");
NIL = new CoreString(context, "nil");
SELF = new CoreString(context, "self");
TRUE = new CoreString(context, "true");
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.core.string;

import com.oracle.truffle.api.object.DynamicObject;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.Layouts;
import org.jruby.truffle.core.rope.Rope;

import java.util.Map;
import java.util.WeakHashMap;

public class FrozenStrings {

private final RubyContext context;

private final Map<Rope, DynamicObject> frozenStrings = new WeakHashMap<>();

public FrozenStrings(RubyContext context) {
this.context = context;
}

public synchronized DynamicObject getFrozenString(Rope rope) {
assert context.getRopeTable().contains(rope);

DynamicObject string = frozenStrings.get(rope);

if (string == null) {
string = StringOperations.createString(context, rope);
string.set(Layouts.FROZEN_IDENTIFIER, true);
frozenStrings.put(rope, string);
}

return string;
}

}
Original file line number Diff line number Diff line change
@@ -478,6 +478,19 @@ public RubyNode visitCallNode(org.jruby.ast.CallNode node) {
final org.jruby.ast.Node receiver = node.getReceiverNode();
final String methodName = node.getName();

if (receiver instanceof org.jruby.ast.StrNode && methodName.equals("freeze")) {
final org.jruby.ast.StrNode strNode = (org.jruby.ast.StrNode) receiver;
final ByteList byteList = strNode.getValue();
final int codeRange = strNode.getCodeRange();

final Rope rope = context.getRopeTable().getRope(byteList.bytes(), byteList.getEncoding(), CodeRange.fromInt(codeRange));

final DynamicObject frozenString = context.getFrozenStrings().getFrozenString(rope);

return addNewlineIfNeeded(node, new DefinedWrapperNode(context, sourceSection, context.getCoreStrings().METHOD,
new ObjectLiteralNode(context, null, frozenString)));
}

// Rubinius.<method>
if (receiver instanceof org.jruby.ast.ConstNode
&& ((org.jruby.ast.ConstNode) receiver).getName().equals("Rubinius")) {
@@ -2893,10 +2906,23 @@ public RubyNode visitSplatNode(org.jruby.ast.SplatNode node) {

@Override
public RubyNode visitStrNode(org.jruby.ast.StrNode node) {
final SourceSection sourceSection = translate(node.getPosition());

final ByteList byteList = node.getValue();
final int codeRange = node.getCodeRange();
final Rope rope = context.getRopeTable().getRope(byteList.bytes(), byteList.getEncoding(), CodeRange.fromInt(codeRange));
final RubyNode ret = new StringLiteralNode(context, translate(node.getPosition()), rope);

final RubyNode ret;

if (node.isFrozen()) {
final DynamicObject frozenString = context.getFrozenStrings().getFrozenString(rope);

ret = new DefinedWrapperNode(context, sourceSection, context.getCoreStrings().METHOD,
new ObjectLiteralNode(context, null, frozenString));
} else {
ret = new StringLiteralNode(context, sourceSection, rope);
}

return addNewlineIfNeeded(node, ret);
}

Original file line number Diff line number Diff line change
@@ -97,6 +97,11 @@ public RubyRootNode parse(RubyContext context, Source source, Encoding defaultEn
boolean isInlineSource = parserContext == ParserContext.SHELL;
boolean isEvalParse = parserContext == ParserContext.EVAL || parserContext == ParserContext.INLINE || parserContext == ParserContext.MODULE;
final org.jruby.parser.ParserConfiguration parserConfiguration = new org.jruby.parser.ParserConfiguration(context.getJRubyRuntime(), 0, isInlineSource, !isEvalParse, false);

if (context.getJRubyRuntime().getInstanceConfig().isFrozenStringLiteral()) {
parserConfiguration.setFrozenStringLiteral(true);
}

parserConfiguration.setDefaultEncoding(defaultEncoding);

// Parse to the JRuby AST