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: 993395fed194
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 70fdee66d724
Choose a head ref
  • 3 commits
  • 2 files changed
  • 1 contributor

Commits on Dec 30, 2016

  1. Copy the full SHA
    f9b405b View commit details
  2. Copy the full SHA
    1d2f3d8 View commit details
  3. Copy the full SHA
    70fdee6 View commit details
Showing with 24 additions and 10 deletions.
  1. +7 −10 core/src/main/java/org/jruby/RubyArray.java
  2. +17 −0 test/jruby/test_array.rb
17 changes: 7 additions & 10 deletions core/src/main/java/org/jruby/RubyArray.java
Original file line number Diff line number Diff line change
@@ -2457,20 +2457,17 @@ protected RubyArray safeReverse() {
/** rb_ary_collect
*
*/
public IRubyObject collect(ThreadContext context, Block block) {
final Ruby runtime = context.runtime;
public RubyArray collect(ThreadContext context, Block block) {
if (!block.isGiven()) return makeShared();

final Ruby runtime = context.runtime;
IRubyObject[] arr = new IRubyObject[realLength];

return collectFrom(context, arr, 0, block);
}

protected IRubyObject collectFrom(ThreadContext context, IRubyObject[] arr, int i, Block block) {
for (i = 0; i < realLength; i++) {
int i = 0;
for (; i < realLength; i++) {
// Do not coarsen the "safe" check, since it will misinterpret AIOOBE from the yield
// See JRUBY-5434
arr[i] = block.yield(context, eltOk(i));
safeArraySet(runtime, arr, i, block.yield(context, eltOk(i))); // arr[i] = ...
}

// use iteration count as new size in case something was deleted along the way
@@ -2664,7 +2661,7 @@ public IRubyObject delete_at(int pos) {
modify();

IRubyObject nil = getRuntime().getNil();
IRubyObject obj = null; // should never return null below
IRubyObject obj;

try {
obj = values[begin + pos];
@@ -2681,7 +2678,7 @@ public IRubyObject delete_at(int pos) {
}

System.arraycopy(values, begin + pos + 1, values, begin + pos, len - (pos + 1));
values[begin + len - 1] = getRuntime().getNil();
values[begin + len - 1] = nil;
} catch (ArrayIndexOutOfBoundsException e) {
throw concurrentModification(getRuntime(), e);
}
17 changes: 17 additions & 0 deletions test/jruby/test_array.rb
Original file line number Diff line number Diff line change
@@ -45,4 +45,21 @@ def test_range_to_a
str = '2202702806'; assert_equal false, (str..str).member?(str.to_i)
end

def test_collect_concurrency
arr = []

Thread.new do ; times = 0
loop { arr << Time.now.to_f; break if (times += 1) == 1000 }
end

1000.times do
begin
arr.collect { |f| f.to_i }.size
# expected not to raise a Java AIOoBE
rescue ConcurrencyError => e
puts "#{__method__} : #{e}" if $VERBOSE
end
end
end

end