[macruby-changes] [3056] MacRuby/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Fri Nov 27 16:57:41 PST 2009
Revision: 3056
http://trac.macosforge.org/projects/ruby/changeset/3056
Author: lsansonetti at apple.com
Date: 2009-11-27 16:57:38 -0800 (Fri, 27 Nov 2009)
Log Message:
-----------
fixing a bunch of GCD bugs
Modified Paths:
--------------
MacRuby/trunk/dispatcher.cpp
MacRuby/trunk/gcd.c
MacRuby/trunk/test_vm/gcd.rb
MacRuby/trunk/vm.cpp
MacRuby/trunk/vm.h
Modified: MacRuby/trunk/dispatcher.cpp
===================================================================
--- MacRuby/trunk/dispatcher.cpp 2009-11-26 00:52:54 UTC (rev 3055)
+++ MacRuby/trunk/dispatcher.cpp 2009-11-28 00:57:38 UTC (rev 3056)
@@ -71,8 +71,7 @@
static force_inline VALUE
__rb_vm_bcall(VALUE self, SEL sel, VALUE dvars, rb_vm_block_t *b,
- IMP pimp, const rb_vm_arity_t &arity, int argc,
- const VALUE *argv)
+ IMP pimp, const rb_vm_arity_t &arity, int argc, const VALUE *argv)
{
if ((arity.real != argc) || (arity.max == -1)) {
VALUE *new_argv = (VALUE *)alloca(sizeof(VALUE) * arity.real);
@@ -113,7 +112,7 @@
static force_inline VALUE
__rb_vm_rcall(VALUE self, SEL sel, IMP pimp, const rb_vm_arity_t &arity,
- int argc, const VALUE *argv)
+ int argc, const VALUE *argv)
{
if ((arity.real != argc) || (arity.max == -1)) {
VALUE *new_argv = (VALUE *)alloca(sizeof(VALUE) * arity.real);
@@ -1373,10 +1372,8 @@
}
static rb_vm_block_t *
-rb_vm_dup_active_block(rb_vm_block_t *src_b)
+dup_block(rb_vm_block_t *src_b)
{
- assert(src_b->flags & VM_BLOCK_ACTIVE);
-
const size_t block_size = sizeof(rb_vm_block_t)
+ (sizeof(VALUE *) * src_b->dvars_size);
@@ -1403,6 +1400,36 @@
return new_b;
}
+extern "C"
+rb_vm_block_t *
+rb_vm_uncache_or_dup_block(rb_vm_block_t *b)
+{
+ return GET_VM()->uncache_or_dup_block(b);
+}
+
+extern "C"
+rb_vm_block_t *
+rb_vm_dup_block(rb_vm_block_t *b)
+{
+ return dup_block(b);
+}
+
+rb_vm_block_t *
+RoxorVM::uncache_or_dup_block(rb_vm_block_t *b)
+{
+ void *key = (void *)b->imp;
+ std::map<void *, rb_vm_block_t *>::iterator iter = blocks.find(key);
+ if (iter == blocks.end()) {
+ b = dup_block(b);
+ GC_RETAIN(b);
+ blocks[key] = b;
+ }
+ else {
+ b = iter->second;
+ }
+ return b;
+}
+
static force_inline VALUE
rb_vm_block_eval0(rb_vm_block_t *b, SEL sel, VALUE self, int argc,
const VALUE *argv)
@@ -1467,7 +1494,7 @@
block_call:
if (b->flags & VM_BLOCK_ACTIVE) {
- b = rb_vm_dup_active_block(b);
+ b = dup_block(b);
}
b->flags |= VM_BLOCK_ACTIVE;
@@ -1611,16 +1638,15 @@
const bool is_ifunc = (iter != blocks.end())
&& ((iter->second->flags & VM_BLOCK_IFUNC) == VM_BLOCK_IFUNC);
- if (!is_ifunc && iter != blocks.end()) {
- rb_objc_release(iter->second);
- }
b = (rb_vm_block_t *)xmalloc(sizeof(rb_vm_block_t)
+ (sizeof(VALUE *) * dvars_size));
if (!is_ifunc) {
- rb_objc_retain(b);
+ if (iter != blocks.end()) {
+ GC_RELEASE(iter->second);
+ }
+ GC_RETAIN(b);
blocks[key] = b;
}
-
*cached = false;
}
else {
Modified: MacRuby/trunk/gcd.c
===================================================================
--- MacRuby/trunk/gcd.c 2009-11-26 00:52:54 UTC (rev 3055)
+++ MacRuby/trunk/gcd.c 2009-11-28 00:57:38 UTC (rev 3056)
@@ -129,7 +129,7 @@
{
VALUE q = rb_queue_alloc(cQueue, 0);
if (should_retain) {
- rb_objc_retain((void*)q);
+ GC_RETAIN(q);
}
RQueue(q)->queue = dq;
return q;
@@ -284,20 +284,31 @@
}
static VALUE
-rb_queue_dispatch_body(VALUE val)
+rb_queue_dispatch_body(VALUE data)
{
- rb_vm_block_t *the_block = (rb_vm_block_t *)val;
- return rb_vm_block_eval(the_block, 0, NULL);
+ GC_RELEASE(data);
+ //rb_vm_block_t *b = rb_vm_uncache_or_dup_block((rb_vm_block_t *)data);
+ rb_vm_block_t *b = (rb_vm_block_t *)data;
+ return rb_vm_block_eval(b, 0, NULL);
}
static void
-rb_queue_dispatcher(void* block)
+rb_queue_dispatcher(void *data)
{
- assert(block != NULL);
- rb_rescue2(rb_queue_dispatch_body, (VALUE)block, NULL, 0,
+ assert(data != NULL);
+ rb_rescue2(rb_queue_dispatch_body, (VALUE)data, NULL, 0,
rb_eStandardError);
}
+static rb_vm_block_t *
+rb_queue_dispatcher_prepare_block(rb_vm_block_t *block)
+{
+ rb_vm_set_multithreaded(true);
+ rb_vm_block_make_detachable_proc(block);
+ GC_RETAIN(block);
+ return block;
+}
+
/*
* call-seq:
* gcdq.dispatch(synchronicity) { i = 42 }
@@ -332,8 +343,7 @@
VALUE synchronous;
rb_scan_args(argc, argv, "01", &synchronous);
- rb_vm_block_make_detachable_proc(block);
- rb_vm_set_multithreaded(true);
+ block = rb_queue_dispatcher_prepare_block(block);
if (RTEST(synchronous)){
dispatch_sync_f(RQueue(self)->queue, (void *)block,
@@ -369,8 +379,7 @@
rb_raise(rb_eArgError, "dispatch_after() requires a block argument");
}
- rb_vm_block_make_detachable_proc(block);
- rb_vm_set_multithreaded(true);
+ block = rb_queue_dispatcher_prepare_block(block);
dispatch_after_f(offset, RQueue(self)->queue, (void *)block,
rb_queue_dispatcher);
@@ -378,15 +387,6 @@
return Qnil;
}
-static void
-rb_queue_applier(void* block, size_t ii)
-{
- assert(block != NULL);
- rb_vm_block_t *the_block = (rb_vm_block_t*)block;
- VALUE num = SIZET2NUM(ii);
- rb_vm_block_eval(the_block, 1, &num);
-}
-
/*
* call-seq:
* gcdq.apply(amount_size) { block }
@@ -400,6 +400,16 @@
*
*/
+static void
+rb_queue_applier(void *data, size_t ii)
+{
+ assert(data != NULL);
+ rb_vm_block_t *block = rb_vm_uncache_or_dup_block((rb_vm_block_t *)data);
+ rb_vm_block_make_detachable_proc(block);
+ VALUE num = SIZET2NUM(ii);
+ rb_vm_block_eval(block, 1, &num);
+}
+
static VALUE
rb_queue_apply(VALUE self, SEL sel, VALUE n)
{
@@ -408,7 +418,6 @@
rb_raise(rb_eArgError, "apply() requires a block argument");
}
- rb_vm_block_make_detachable_proc(block);
rb_vm_set_multithreaded(true);
dispatch_apply_f(NUM2SIZET(n), RQueue(self)->queue, (void *)block,
@@ -565,9 +574,13 @@
rb_raise(rb_eArgError, "dispatch() requires a block argument");
}
- rb_vm_block_make_detachable_proc(block);
- rb_vm_set_multithreaded(true);
+ if (CLASS_OF(target) != cQueue) {
+ rb_raise(rb_eArgError, "expected Queue object, but got %s",
+ rb_class2name(CLASS_OF(target)));
+ }
+ block = rb_queue_dispatcher_prepare_block(block);
+
dispatch_group_async_f(RGroup(self)->group, RQueue(target)->queue,
(void *)block, rb_queue_dispatcher);
@@ -597,8 +610,7 @@
rb_raise(rb_eArgError, "notify() requires a block argument");
}
- rb_vm_block_make_detachable_proc(block);
- rb_vm_set_multithreaded(true);
+ block = rb_queue_dispatcher_prepare_block(block);
dispatch_group_notify_f(RGroup(self)->group, RQueue(target)->queue,
(void *)block, rb_queue_dispatcher);
Modified: MacRuby/trunk/test_vm/gcd.rb
===================================================================
--- MacRuby/trunk/test_vm/gcd.rb 2009-11-26 00:52:54 UTC (rev 3055)
+++ MacRuby/trunk/test_vm/gcd.rb 2009-11-28 00:57:38 UTC (rev 3056)
@@ -1,34 +1,44 @@
-n = (0..999).to_a.inject(0) { |b, i| b + i }.to_s
+n = (0..9999).to_a.inject(0) { |b, i| b + i }.to_s
+# sequential + synchronous
assert n, %{
n = 0
q = Dispatch::Queue.new('foo')
- g = Dispatch::Group.new
- 1000.times do |i|
- g.dispatch(q) { n += i }
+ 10000.times do |i|
+ q.dispatch(true) { n += i }
end
- g.wait
p n
}
+# sequential + asynchronous
assert n, %{
n = 0
q = Dispatch::Queue.new('foo')
+ 10000.times do |i|
+ q.dispatch { n += i }
+ end
+ q.dispatch(true) {}
+ p n
+}
+
+# group + sequential
+assert n, %{
+ n = 0
+ q = Dispatch::Queue.new('foo')
g = Dispatch::Group.new
- 1000.times do |i|
- g.dispatch(Dispatch::Queue.concurrent) do
- g.dispatch(q) { n += i }
- end
+ 10000.times do |i|
+ g.dispatch(q) { n += i }
end
g.wait
p n
}
+# group + concurrent
assert n, %{
n = 0
q = Dispatch::Queue.new('foo')
g = Dispatch::Group.new
- 1000.times do |i|
+ 10000.times do |i|
g.dispatch(Dispatch::Queue.concurrent) do
q.dispatch(true) { n += i }
end
@@ -37,25 +47,28 @@
p n
}
+# apply + sequential
assert n, %{
n = 0
q = Dispatch::Queue.new('foo')
- q.apply(1000) do |i|
+ q.apply(10000) do |i|
n += i
end
p n
}
+# apply + concurrent
assert n, %{
n = 0
q = Dispatch::Queue.new('foo')
- Dispatch::Queue.concurrent.apply(1000) do |i|
+ Dispatch::Queue.concurrent.apply(10000) do |i|
q.dispatch { n += i }
end
q.dispatch(true) {}
p n
}
+# exceptions should be ignored
assert ':ok', %{
g = Dispatch::Group.new
g.dispatch(Dispatch::Queue.concurrent) { raise('hey') }
@@ -66,15 +79,15 @@
# Stress tests
assert ':ok', %{
- Dispatch::Queue.concurrent.apply(10000000) {}
+ Dispatch::Queue.concurrent.apply(10000000) { |i| i+2*3/4-5}
p :ok
}
assert ':ok', %{
i = 0
g = Dispatch::Group.new
- while i < 10000000
- g.dispatch(Dispatch::Queue.concurrent) { 1+2*3/4-5 }
+ while i < 100000
+ g.dispatch(Dispatch::Queue.concurrent) { i+2*3/4-5 }
i += 1
end
g.wait
Modified: MacRuby/trunk/vm.cpp
===================================================================
--- MacRuby/trunk/vm.cpp 2009-11-26 00:52:54 UTC (rev 3055)
+++ MacRuby/trunk/vm.cpp 2009-11-28 00:57:38 UTC (rev 3056)
@@ -2686,7 +2686,8 @@
};
static void
-rb_vm_add_lvar_use(rb_vm_var_uses **var_uses, void *use, unsigned char use_type)
+rb_vm_add_lvar_use(rb_vm_var_uses **var_uses, void *use,
+ unsigned char use_type)
{
if (var_uses == NULL) {
return;
@@ -2701,7 +2702,8 @@
new_uses->uses_count = 0;
*var_uses = new_uses;
}
- int current_index = (*var_uses)->uses_count;
+
+ const int current_index = (*var_uses)->uses_count;
rb_gc_assign_weak_ref(use, &(*var_uses)->uses[current_index]);
(*var_uses)->use_types[current_index] = use_type;
++(*var_uses)->uses_count;
Modified: MacRuby/trunk/vm.h
===================================================================
--- MacRuby/trunk/vm.h 2009-11-26 00:52:54 UTC (rev 3055)
+++ MacRuby/trunk/vm.h 2009-11-28 00:57:38 UTC (rev 3056)
@@ -371,6 +371,9 @@
bool rb_vm_block_saved(void);
VALUE rb_vm_block_eval(rb_vm_block_t *block, int argc, const VALUE *argv);
+rb_vm_block_t *rb_vm_uncache_or_dup_block(rb_vm_block_t *b);
+rb_vm_block_t *rb_vm_dup_block(rb_vm_block_t *b);
+
static inline void
rb_vm_block_make_detachable_proc(rb_vm_block_t *b)
{
@@ -942,6 +945,7 @@
rb_vm_block_t *uncache_or_create_block(void *key, bool *cached,
int dvars_size);
+ rb_vm_block_t *uncache_or_dup_block(rb_vm_block_t *b);
rb_vm_binding_t *current_binding(void) {
return bindings.empty()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20091127/31681783/attachment-0001.html>
More information about the macruby-changes
mailing list