Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fe6c5b5

Browse files
committed
Merge branch 'master' of [email protected]:jruby~main
2 parents 48c9cc1 + 3d9140f commit fe6c5b5

File tree

7 files changed

+91
-58
lines changed

7 files changed

+91
-58
lines changed

bench/bench_eval.rb

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@
99

1010
bnd = binding
1111

12-
Benchmark.bmbm do |bm|
13-
bm.report("Control") { amount.times { 1 + 1 } }
14-
bm.report("Binding creation") { amount.times { binding } }
15-
bm.report("Implicit binding (short)") { amount.times { eval script } }
16-
bm.report("Explicit binding (short)") { amount.times { eval script, bnd } }
17-
bm.report("Implicit binding (long, * 0.1 loops)") { (amount/10).times { eval long_script } }
18-
bm.report("Explicit binding (long, * 0.1 loops)") { (amount/10).times { eval long_script, bnd } }
12+
(ARGV[0] || 1).to_i.times do
13+
Benchmark.bm(40) do |bm|
14+
bm.report("Control") { amount.times { 1 + 1 } }
15+
bm.report("Binding creation") { amount.times { binding } }
16+
bm.report("Implicit binding (short)") { amount.times { eval script } }
17+
bm.report("Explicit binding (short)") { amount.times { eval script, bnd } }
18+
bm.report("Implicit binding (long, * 0.1 loops)") { (amount/10).times { eval long_script } }
19+
bm.report("Explicit binding (long, * 0.1 loops)") { (amount/10).times { eval long_script, bnd } }
20+
end
1921
end

src/org/jruby/RubyClass.java

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -703,10 +703,11 @@ protected void setModuleSuperClass(RubyClass superClass) {
703703
}
704704

705705
public Collection subclasses(boolean includeDescendants) {
706-
if (subclasses != null) {
707-
Collection<RubyClass> mine = new ArrayList<RubyClass>(subclasses);
706+
Set<RubyClass> mySubclasses = subclasses;
707+
if (mySubclasses != null) {
708+
Collection<RubyClass> mine = new ArrayList<RubyClass>(mySubclasses);
708709
if (includeDescendants) {
709-
for (RubyClass i: subclasses) {
710+
for (RubyClass i: mySubclasses) {
710711
mine.addAll(i.subclasses(includeDescendants));
711712
}
712713
}
@@ -716,21 +717,63 @@ public Collection subclasses(boolean includeDescendants) {
716717
return Collections.EMPTY_LIST;
717718
}
718719
}
719-
720+
721+
/**
722+
* Add a new subclass to the weak set of subclasses.
723+
*
724+
* This version always constructs a new set to avoid having to synchronize
725+
* against the set when iterating it for invalidation in
726+
* invalidateCacheDescendants.
727+
*
728+
* @param subclass The subclass to add
729+
*/
720730
public synchronized void addSubclass(RubyClass subclass) {
721-
if (subclasses == null) subclasses = new WeakHashSet<RubyClass>();
722-
subclasses.add(subclass);
731+
Set<RubyClass> oldSubclasses = subclasses;
732+
Set<RubyClass> mySubclasses =
733+
new WeakHashSet<RubyClass>(oldSubclasses == null ? 1 : oldSubclasses.size() + 1);
734+
if (oldSubclasses != null) mySubclasses.addAll(oldSubclasses);
735+
mySubclasses.add(subclass);
736+
subclasses = Collections.unmodifiableSet(mySubclasses);
723737
}
724738

739+
/**
740+
* Remove a subclass from the weak set of subclasses.
741+
*
742+
* This version always constructs a new set to avoid having to synchronize
743+
* against the set when iterating it for invalidation in
744+
* invalidateCacheDescendants.
745+
*
746+
* @param subclass The subclass to remove
747+
*/
725748
public synchronized void removeSubclass(RubyClass subclass) {
726-
if (subclasses == null) return;
727-
subclasses.remove(subclass);
749+
Set<RubyClass> oldSubclasses = subclasses;
750+
if (oldSubclasses == null) return;
751+
752+
Set<RubyClass> mySubclasses = new WeakHashSet<RubyClass>(oldSubclasses.size() + 1);
753+
mySubclasses.addAll(oldSubclasses);
754+
mySubclasses.remove(subclass);
755+
756+
subclasses = Collections.unmodifiableSet(mySubclasses);
728757
}
729758

759+
/**
760+
* Invalidate all subclasses of this class by walking the set of all
761+
* subclasses and asking them to invalidate themselves.
762+
*
763+
* Note that this version works against a reference to the current set of
764+
* subclasses, which could be replaced by the time this iteration is
765+
* complete. In theory, there may be a path by which invalidation would
766+
* miss a class added during the invalidation process, but the exposure is
767+
* minimal if it exists at all. The only way to prevent it would be to
768+
* synchronize both invalidation and subclass set modification against a
769+
* global lock, which we would like to avoid.
770+
*/
771+
@Override
730772
protected void invalidateCacheDescendants() {
731773
super.invalidateCacheDescendants();
732774
// update all subclasses
733-
if (subclasses != null) for (RubyClass subclass : subclasses) {
775+
Set<RubyClass> mySubclasses = subclasses;
776+
if (mySubclasses != null) for (RubyClass subclass : mySubclasses) {
734777
subclass.invalidateCacheDescendants();
735778
}
736779
}

src/org/jruby/RubyJRuby.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ public static RubyModule createJRubyExt(Ruby runtime) {
9696
public static void createJRubyCoreExt(Ruby runtime) {
9797
runtime.getClassClass().defineAnnotatedMethods(JRubyClassExtensions.class);
9898
runtime.getThread().defineAnnotatedMethods(JRubyThreadExtensions.class);
99+
runtime.getString().defineAnnotatedMethods(JRubyStringExtensions.class);
99100
}
100101

101102
public static class ExtLibrary implements Library {
@@ -350,6 +351,13 @@ public static IRubyObject times(IRubyObject recv, Block unusedBlock) {
350351
}
351352
}
352353

354+
public static class JRubyStringExtensions {
355+
@JRubyMethod(name = "alloc", meta = true)
356+
public static IRubyObject alloc(ThreadContext context, IRubyObject recv, IRubyObject size) {
357+
return RubyString.newStringLight(context.getRuntime(), (int)size.convertToInteger().getLongValue());
358+
}
359+
}
360+
353361
public static class MethodExtensions {
354362
@JRubyMethod(name = "args")
355363
public static IRubyObject methodArgs(IRubyObject recv) {

src/org/jruby/RubyModule.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,14 @@ public synchronized void update() {
220220
protected Set<RubyClass> includingHierarchies;
221221

222222
public synchronized void addIncludingHierarchy(IncludedModuleWrapper hierarchy) {
223-
if (includingHierarchies == null) includingHierarchies = new WeakHashSet<RubyClass>();
224-
includingHierarchies.add(hierarchy);
223+
Set<RubyClass> oldIncludingHierarchies = includingHierarchies;
224+
Set<RubyClass> myIncludingHierarchies =
225+
new WeakHashSet<RubyClass>(oldIncludingHierarchies == null ? 1 : oldIncludingHierarchies.size() + 1);
226+
if (includingHierarchies != null) {
227+
myIncludingHierarchies.addAll(oldIncludingHierarchies);
228+
}
229+
myIncludingHierarchies.add(hierarchy);
230+
includingHierarchies = Collections.unmodifiableSet(myIncludingHierarchies);
225231
}
226232

227233
// ClassProviders return Java class/module (in #defineOrGetClassUnder and

src/org/jruby/parser/StaticScope.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public abstract class StaticScope implements Serializable {
8484

8585
private boolean isBackrefLastlineScope = false;
8686

87-
private DynamicScope dummyScope = new NoVarsDynamicScope(this);
87+
private DynamicScope dummyScope;
8888

8989
protected StaticScope(StaticScope enclosingScope, String[] names) {
9090
assert names != null : "names is not null";
@@ -365,7 +365,7 @@ public void setArities(int required, int optional, int rest) {
365365
}
366366

367367
public DynamicScope getDummyScope() {
368-
return dummyScope;
368+
return dummyScope == null ? dummyScope = new NoVarsDynamicScope(this) : dummyScope;
369369
}
370370

371371
private void growVariableNames(String name) {

src/org/jruby/util/collections/WeakHashSet.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ public WeakHashSet() {
4040
map = new WeakHashMap<T,T>();
4141
}
4242

43+
public WeakHashSet(int size) {
44+
map = new WeakHashMap<T,T>(size);
45+
}
46+
4347
public boolean add(T o) {
4448
T previousValue = map.put(o, null);
4549
return previousValue == null;

tool/snapshot.rb

Lines changed: 8 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,53 +4,23 @@
44

55
abort "jruby.properties filename location needed" unless ARGV[0]
66

7-
def update_jruby_properties(url, tag, revision)
7+
def update_jruby_properties(revision)
88
properties = File.open(ARGV[0]) {|f| f.read}
9-
# properties.sub!(/^version.jruby=.*$/, "version.jruby=#{tag}-#{revision}")
109
properties.sub!(/Revision: \d+/, "Revision: #{revision}")
11-
properties << "\nurl=#{url}\nrevision=#{revision}\n"
1210
File.open(ARGV[0], "w") {|f| f << properties }
1311
end
1412

15-
MAX_GIT_COMMITS = 100
16-
1713
# look through the last MAX_GIT_COMMITS for a git-svn-id: for jruby
1814
# if a git-svn-id for jruby is found return: [url, tag, revision, git_commits_searched]
1915
# else nil
20-
def find_last_git_svn_rev
21-
re = /git-svn-id: https:\/\/svn.codehaus.org\/jruby\/(.*)\/(.*)@(.*) /
22-
return (0..MAX_GIT_COMMITS).each do |n|
23-
last_commit = `git rev-list HEAD --pretty=raw --no-color --max-count=1 --skip=#{n}`
24-
break nil if last_commit.empty? || n == MAX_GIT_COMMITS
25-
next unless match = re.match(last_commit)
26-
if match[1][/(tags|branches)/]
27-
tag = tag = match[2]
28-
else
29-
tag = "trunk"
30-
end
31-
revision = match[3]
32-
url = last_commit[/git-svn-id: (https:.*)@/, 1]
33-
break [url, tag, revision, n] if url && tag && revision
34-
end
16+
def find_last_git_rev
17+
re = /commit (.......).*/
18+
last_commit = `git rev-list HEAD --pretty=raw --no-color --max-count=1`
19+
return nil unless match = re.match(last_commit)
20+
return match[1]
3521
end
3622

37-
if File.exist? '.svn'
38-
svn_props = YAML::load(`svn info`)
39-
# true if we are working from a svn checkout
40-
url = svn_props["URL"]
41-
revision = svn_props["Revision"].to_s
42-
path = url =~ /#{svn_props["Repository Root"]}\/(.*)/ && $1
43-
tag = case path
44-
when /trunk/
45-
"trunk"
46-
when /(tags|branches)\/(.*)/
47-
"#{$1.sub(/e?s$/, '')}-#{$2}"
48-
else
49-
path.gsub(%r{/}, '-')
50-
end
51-
update_jruby_properties(url, tag, revision)
52-
elsif (url, tag, revision, git_commits_searched = find_last_git_svn_rev)[0]
53-
revision << "+#{git_commits_searched}" if git_commits_searched > 0
54-
update_jruby_properties(url, tag, revision)
23+
if revision = find_last_git_rev
24+
update_jruby_properties(revision)
5525
end
5626

0 commit comments

Comments
 (0)