Skip to content

Commit 34aae7c

Browse files
committedDec 22, 2017
Allow aliasing to update the frame reads/writes for a name.
Also cleaned up concurrent access to these structures.
1 parent a4b81bc commit 34aae7c

File tree

2 files changed

+49
-20
lines changed

2 files changed

+49
-20
lines changed
 

‎core/src/main/java/org/jruby/RubyModule.java

+17-11
Original file line numberDiff line numberDiff line change
@@ -1662,19 +1662,25 @@ private DynamicMethod searchForAliasMethod(Ruby runtime, String name) {
16621662
if (anno == null) return method;
16631663

16641664
if (anno.reads().length > 0 || anno.writes().length > 0) {
1665-
String baseName = getBaseName();
1666-
char refChar = '#';
1667-
String simpleName = getSimpleName();
1668-
1669-
if (baseName == null && this instanceof MetaClass) {
1670-
IRubyObject attached = ((MetaClass)this).getAttached();
1671-
if (attached instanceof RubyModule) {
1672-
simpleName = ((RubyModule)attached).getSimpleName();
1673-
refChar = '.';
1665+
1666+
MethodIndex.addMethodReadFields(name, anno.reads());
1667+
MethodIndex.addMethodWriteFields(name, anno.writes());
1668+
1669+
if (runtime.isVerbose()) {
1670+
String baseName = getBaseName();
1671+
char refChar = '#';
1672+
String simpleName = getSimpleName();
1673+
1674+
if (baseName == null && this instanceof MetaClass) {
1675+
IRubyObject attached = ((MetaClass) this).getAttached();
1676+
if (attached instanceof RubyModule) {
1677+
simpleName = ((RubyModule) attached).getSimpleName();
1678+
refChar = '.';
1679+
}
16741680
}
1675-
}
16761681

1677-
runtime.getWarnings().warning(simpleName + refChar + name + " accesses caller method's state and should not be aliased");
1682+
runtime.getWarnings().warning(simpleName + refChar + name + " accesses caller method's state and should not be aliased");
1683+
}
16781684
}
16791685
}
16801686

‎core/src/main/java/org/jruby/runtime/MethodIndex.java

+32-9
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.util.Collections;
3434
import java.util.HashMap;
3535
import java.util.HashSet;
36+
import java.util.List;
3637
import java.util.Map;
3738
import java.util.Set;
3839
import java.util.concurrent.ConcurrentHashMap;
@@ -224,14 +225,21 @@ public static CallSite getSuperCallSite() {
224225
}
225226

226227
public static void addMethodReadFieldsPacked(int readBits, String methodsPacked) {
227-
Set<FrameField> reads = FrameField.unpack(readBits);
228+
Set<FrameField> reads = Collections.synchronizedSet(FrameField.unpack(readBits));
228229

229230
if (DEBUG) LOG.debug("Adding method field reads: {} for {}", reads, methodsPacked);
230231

231-
for (String name : Helpers.SEMICOLON_PATTERN.split(methodsPacked)) {
232-
if (FrameField.needsFrame(readBits)) FRAME_AWARE_METHODS.add(name);
233-
if (FrameField.needsScope(readBits)) SCOPE_AWARE_METHODS.add(name);
234-
METHOD_FRAME_READS.put(name, reads);
232+
String[] names = Helpers.SEMICOLON_PATTERN.split(methodsPacked);
233+
234+
if (FrameField.needsFrame(readBits)) FRAME_AWARE_METHODS.addAll(Arrays.asList(names));
235+
if (FrameField.needsScope(readBits)) SCOPE_AWARE_METHODS.addAll(Arrays.asList(names));
236+
237+
for (String name : names) {
238+
Set<FrameField> current = METHOD_FRAME_READS.putIfAbsent(name, reads);
239+
240+
if (current != null) {
241+
current.addAll(reads);
242+
}
235243
}
236244
}
237245

@@ -240,13 +248,28 @@ public static void addMethodWriteFieldsPacked(int writeBits, String methodsPacke
240248

241249
if (DEBUG) LOG.debug("Adding scope-aware method names: {} for {}", writes, methodsPacked);
242250

243-
for (String name : Helpers.SEMICOLON_PATTERN.split(methodsPacked)) {
244-
if (FrameField.needsFrame(writeBits)) FRAME_AWARE_METHODS.add(name);
245-
if (FrameField.needsScope(writeBits)) SCOPE_AWARE_METHODS.add(name);
246-
METHOD_FRAME_WRITES.put(name, writes);
251+
String[] names = Helpers.SEMICOLON_PATTERN.split(methodsPacked);
252+
253+
if (FrameField.needsFrame(writeBits)) FRAME_AWARE_METHODS.addAll(Arrays.asList(names));
254+
if (FrameField.needsScope(writeBits)) SCOPE_AWARE_METHODS.addAll(Arrays.asList(names));
255+
256+
for (String name : names) {
257+
Set<FrameField> current = METHOD_FRAME_WRITES.putIfAbsent(name, writes);
258+
259+
if (current != null) {
260+
current.addAll(writes);
261+
}
247262
}
248263
}
249264

265+
public static void addMethodReadFields(String name, FrameField[] reads) {
266+
addMethodReadFieldsPacked(FrameField.pack(reads), name);
267+
}
268+
269+
public static void addMethodWriteFields(String name, FrameField[] write) {
270+
addMethodWriteFieldsPacked(FrameField.pack(write), name);
271+
}
272+
250273
@Deprecated
251274
public static void addFrameAwareMethods(String... methods) {
252275
if (DEBUG) LOG.debug("Adding frame-aware method names: {}", Arrays.toString(methods));

0 commit comments

Comments
 (0)
Please sign in to comment.