https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112012-12-13T20:23:21ZRuby Issue Tracking SystemRuby master - Bug #7556: test error on refinementhttps://bugs.ruby-lang.org/issues/7556?journal_id=347002012-12-13T20:23:21Zduerst (Martin Dürst)duerst@it.aoyama.ac.jp
<ul></ul><p>On 2012/12/13 20:13, usa (Usaku NAKAMURA) wrote:</p>
<blockquote>
<p>Issue <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: test error on refinement (Closed)" href="https://bugs.ruby-lang.org/issues/7556">#7556</a> has been reported by usa (Usaku NAKAMURA).</p>
</blockquote>
<blockquote>
<a name="Once-I-wrote-the-detail-of-my-debuggin-but-it-is-lost-by-accidenal-reboot"></a>
<h1 >Once I wrote the detail of my debuggin, but it is lost by accidenal reboot<a href="#Once-I-wrote-the-detail-of-my-debuggin-but-it-is-lost-by-accidenal-reboot" class="wiki-anchor">¶</a></h1>
<a name="of-my-PC"></a>
<h1 >of my PC.<a href="#of-my-PC" class="wiki-anchor">¶</a></h1>
<a name="I-have-no-energy-to-rewrite-it-because-writing-long-English-sentences"></a>
<h1 >I have no energy to rewrite it, because writing long English sentences<a href="#I-have-no-energy-to-rewrite-it-because-writing-long-English-sentences" class="wiki-anchor">¶</a></h1>
<a name="irritates-me-especially-after-seeing-mails-which-reproach-our-native"></a>
<h1 >irritates me, especially after seeing mails which reproach our native<a href="#irritates-me-especially-after-seeing-mails-which-reproach-our-native" class="wiki-anchor">¶</a></h1>
<a name="language"></a>
<h1 >language.<a href="#language" class="wiki-anchor">¶</a></h1>
</blockquote>
<p>Two solutions:</p>
<ol>
<li>Write short English sentences.</li>
<li>Write in Japanese. (If somebody thinks they really need to know what<br>
you wrote, they can ask on the list.)</li>
</ol>
<p>But I know that for creative people, it is much harder to do the same<br>
work again than to do it the first time. I once worked on Devanagari<br>
rendering, but lost that work in a reboot. I didn't want to redo it, so<br>
I worked on Tamil instead. (I just wanted to see whether my architecture<br>
was able to handle Indic rendering issues.)</p>
<p>Regards, Martin.</p> Ruby master - Bug #7556: test error on refinementhttps://bugs.ruby-lang.org/issues/7556?journal_id=347022012-12-13T22:32:01Zshugo (Shugo Maeda)
<ul><li><strong>Assignee</strong> changed from <i>shugo (Shugo Maeda)</i> to <i>ko1 (Koichi Sasada)</i></li></ul><p>usa (Usaku NAKAMURA) wrote:</p>
<blockquote>
<ol>
<li>Error:<br>
test_refine_recursion(TestRefinement):<br>
NoMethodError: undefined method <code>recursive_length' for "oo":String C:/Users/usa/ruby/test/ruby/test_refinement.rb:567:in </code>recursive_length'
:in `'
C:/Users/usa/ruby/test/ruby/test_refinement.rb:806:in `eval'
C:/Users/usa/ruby/test/ruby/test_refinement.rb:806:in `eval_using'
C:/Users/usa/ruby/test/ruby/test_refinement.rb:574:in `test_refine_recursion'
</li>
</ol>
</blockquote>
<p>To avoid an infinite loop by super in a refinement, ci->call is used to distinguish super calls from normal calls,<br>
and if it's a super call, skip the same method.<br>
However, VC++ optimizes vm_call_general and vm_call_super_method into the same method because they have the same definition, so ci->call cannot be used to distinguish super calls from normal calls. How intelligent VC++ is!</p>
<p>I've found that the following hack fixes the problem:</p>
<p>static VALUE<br>
vm_call_super_method(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_info_t <em>ci)<br>
{<br>
#ifdef _WIN32<br>
volatile int x = 0; /</em> to avoid VC++ optimization which makes<br>
vm_call_super_method as an alias of<br>
vm_call_general! */<br>
#endif<br>
return vm_call_method(th, reg_cfp, ci);<br>
}</p>
<p>Sasada-san, do you accept this ugly hack, or do you come up with a neat solution?</p> Ruby master - Bug #7556: test error on refinementhttps://bugs.ruby-lang.org/issues/7556?journal_id=347042012-12-13T23:23:17Zko1 (Koichi Sasada)
<ul></ul><p>(2012/12/13 22:32), shugo (Shugo Maeda) wrote:</p>
<blockquote>
<p>Sasada-san, do you accept this ugly hack, or do you come up with a neat solution?</p>
</blockquote>
<p>To answer your question, I need to learn how refinement is implemented.<br>
Please wait a moment.<br>
(or please commit it ahead and left this ticket open)</p>
<p>--<br>
// SASADA Koichi at atdot dot net</p> Ruby master - Bug #7556: test error on refinementhttps://bugs.ruby-lang.org/issues/7556?journal_id=347052012-12-13T23:23:17Zshugo (Shugo Maeda)
<ul></ul><p>Hi,</p>
<p>2012/12/13 SASADA Koichi <a href="mailto:ko1@atdot.net" class="email">ko1@atdot.net</a>:</p>
<blockquote>
<blockquote>
<p>Sasada-san, do you accept this ugly hack, or do you come up with a neat solution?</p>
</blockquote>
<p>To answer your question, I need to learn how refinement is implemented.<br>
Please wait a moment.<br>
(or please commit it ahead and left this ticket open)</p>
</blockquote>
<p>Thanks for your quick response.<br>
I've commited the workaround, and have left the ticket open.</p>
<p>--<br>
Shugo Maeda</p> Ruby master - Bug #7556: test error on refinementhttps://bugs.ruby-lang.org/issues/7556?journal_id=347102012-12-14T00:44:51Zphasis68 (Heesob Park)phasis@gmail.com
<ul></ul><p>Here is another workaround:</p>
<p>#ifdef _MSC_VER<br>
#pragma optimize( "", off )<br>
#endif<br>
static VALUE<br>
vm_call_super_method(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_info_t *ci)<br>
{<br>
return vm_call_method(th, reg_cfp, ci);<br>
}<br>
#ifdef _MSC_VER<br>
#pragma optimize( "", on )<br>
#endif</p> Ruby master - Bug #7556: test error on refinementhttps://bugs.ruby-lang.org/issues/7556?journal_id=347282012-12-14T13:47:34Zshugo (Shugo Maeda)
<ul></ul><p>Hello,</p>
<p>phasis68 (Heesob Park) wrote:</p>
<blockquote>
<p>Here is another workaround:</p>
<p>#ifdef _MSC_VER<br>
#pragma optimize( "", off )<br>
#endif</p>
</blockquote>
<p>Thanks for your suggestion.</p>
<p>But it seems that the #pragma optimize( "", off ) version is slightly slower than the volatile int x = 0 version.</p>
<p>with volatile int x = 0:</p>
<p>C:\Users\shugo\Documents\Source\ruby>\ruby\bin\ruby bm_vm2_super.rb<br>
Rehearsal -----------------------------------------<br>
super 1.778000 0.000000 1.778000 ( 1.783227)<br>
-------------------------------- total: 1.778000sec</p>
<pre><code> user system total real
</code></pre>
<p>super 1.810000 0.000000 1.810000 ( 1.806230)</p>
<p>C:\Users\shugo\Documents\Source\ruby>\ruby\bin\ruby bm_vm2_super.rb<br>
Rehearsal -----------------------------------------<br>
super 1.747000 0.000000 1.747000 ( 1.789727)<br>
-------------------------------- total: 1.747000sec</p>
<pre><code> user system total real
</code></pre>
<p>super 1.763000 0.000000 1.763000 ( 1.760224)</p>
<p>C:\Users\shugo\Documents\Source\ruby>\ruby\bin\ruby bm_vm2_super.rb<br>
Rehearsal -----------------------------------------<br>
super 1.763000 0.000000 1.763000 ( 1.804229)<br>
-------------------------------- total: 1.763000sec</p>
<pre><code> user system total real
</code></pre>
<p>super 1.809000 0.000000 1.809000 ( 1.841734)</p>
<p>with #pragma optimize( "", off ):</p>
<p>C:\Users\shugo\Documents\Source\ruby>\ruby\bin\ruby bm_vm2_super.rb<br>
Rehearsal -----------------------------------------<br>
super 1.825000 0.000000 1.825000 ( 1.859236)<br>
-------------------------------- total: 1.825000sec</p>
<pre><code> user system total real
</code></pre>
<p>super 1.872000 0.000000 1.872000 ( 1.864237)</p>
<p>C:\Users\shugo\Documents\Source\ruby>\ruby\bin\ruby bm_vm2_super.rb<br>
Rehearsal -----------------------------------------<br>
super 1.919000 0.000000 1.919000 ( 1.920744)<br>
-------------------------------- total: 1.919000sec</p>
<pre><code> user system total real
</code></pre>
<p>super 1.794000 0.000000 1.794000 ( 1.820232)</p>
<p>C:\Users\shugo\Documents\Source\ruby>\ruby\bin\ruby bm_vm2_super.rb<br>
Rehearsal -----------------------------------------<br>
super 1.872000 0.000000 1.872000 ( 1.913243)<br>
-------------------------------- total: 1.872000sec</p>
<pre><code> user system total real
</code></pre>
<p>super 1.810000 0.000000 1.810000 ( 1.817231)</p>
<p>I guess #pragma optimize( "", off ) disables function inlining of vm_call_method.</p> Ruby master - Bug #7556: test error on refinementhttps://bugs.ruby-lang.org/issues/7556?journal_id=347292012-12-14T14:51:26Zphasis68 (Heesob Park)phasis@gmail.com
<ul></ul><p>Here is a modified version which does not disable function inline expansion.</p>
<p>#ifdef _MSC_VER<br>
#pragma optimize("g",off)<br>
#endif<br>
static VALUE<br>
vm_call_super_method(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_info_t *ci)<br>
{<br>
return vm_call_method(th, reg_cfp, ci);<br>
}<br>
#ifdef _MSC_VER<br>
#pragma optimize("g",on)<br>
#endif</p> Ruby master - Bug #7556: test error on refinementhttps://bugs.ruby-lang.org/issues/7556?journal_id=347302012-12-14T15:13:30Zshugo (Shugo Maeda)
<ul></ul><p>phasis68 (Heesob Park) wrote:</p>
<blockquote>
<p>Here is a modified version which does not disable function inline expansion.</p>
<p>#ifdef _MSC_VER<br>
#pragma optimize("g",off)<br>
#endif</p>
</blockquote>
<p>I also tried it, but couldn't see improvement:</p>
<p>C:\Users\shugo\Documents\Source\ruby>\ruby\bin\ruby bm_vm2_super.rb<br>
Rehearsal -----------------------------------------<br>
super 1.856000 0.000000 1.856000 ( 1.868237)<br>
-------------------------------- total: 1.856000sec</p>
<pre><code> user system total real
</code></pre>
<p>super 1.872000 0.000000 1.872000 ( 1.910743)</p>
<p>C:\Users\shugo\Documents\Source\ruby>\ruby\bin\ruby bm_vm2_super.rb<br>
Rehearsal -----------------------------------------<br>
super 1.841000 0.000000 1.841000 ( 1.860736)<br>
-------------------------------- total: 1.841000sec</p>
<pre><code> user system total real
</code></pre>
<p>super 1.903000 0.016000 1.919000 ( 1.956249)</p>
<p>C:\Users\shugo\Documents\Source\ruby>\ruby\bin\ruby bm_vm2_super.rb<br>
Rehearsal -----------------------------------------<br>
super 1.872000 0.000000 1.872000 ( 1.927244)<br>
-------------------------------- total: 1.872000sec</p>
<pre><code> user system total real
</code></pre>
<p>super 1.841000 0.000000 1.841000 ( 1.868237)</p>
<p>And, other options of the optimize pragma such as "p" don't fix the problem.</p> Ruby master - Bug #7556: test error on refinementhttps://bugs.ruby-lang.org/issues/7556?journal_id=347312012-12-14T15:59:13Zphasis68 (Heesob Park)phasis@gmail.com
<ul></ul><p>Here is a different workaround using __forceinline on vm_call_method function.</p>
<p>static<br>
#ifdef _MSC_VER<br>
__forceinline<br>
#else<br>
inline<br>
#endif<br>
VALUE<br>
vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci)<br>
{<br>
...<br>
}</p> Ruby master - Bug #7556: test error on refinementhttps://bugs.ruby-lang.org/issues/7556?journal_id=347332012-12-14T16:55:02Zshugo (Shugo Maeda)
<ul></ul><p>phasis68 (Heesob Park) wrote:</p>
<blockquote>
<p>Here is a different workaround using __forceinline on vm_call_method function.</p>
<p>static<br>
#ifdef _MSC_VER<br>
__forceinline<br>
#else<br>
inline<br>
#endif<br>
VALUE<br>
vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci)</p>
</blockquote>
<p>Thanks, it solves the problem without the optimize progma for rb_call_super_method, and performance decrease hasn't been observed.</p>
<p>Could you tell me why __forceinline for vm_call_method prevent VC++ to make vm_call_general and vm_call_super_method as the same function?<br>
I couldn't find the reason at <a href="URL:http://msdn.microsoft.com/library/vstudio/z8y1yy88" class="external">URL:http://msdn.microsoft.com/library/vstudio/z8y1yy88</a>.</p> Ruby master - Bug #7556: test error on refinementhttps://bugs.ruby-lang.org/issues/7556?journal_id=347342012-12-14T17:04:58Zshugo (Shugo Maeda)
<ul><li><strong>Status</strong> changed from <i>Assigned</i> to <i>Closed</i></li><li><strong>% Done</strong> changed from <i>0</i> to <i>100</i></li></ul><p>This issue was solved with changeset r38377.<br>
Usaku, thank you for reporting this issue.<br>
Your contribution to Ruby is greatly appreciated.<br>
May Ruby be with you.</p>
<hr>
<ul>
<li>
<p>vm_insnhelper.c (vm_call_super_method): remove volatile introduced<br>
in r38365.</p>
</li>
<li>
<p>vm_insnhelper.c (vm_call_method): use __forceinline to prevent<br>
VC to make vm_call_general and vm_call_super_method as the same<br>
method. Thanks, Heesob Park. [Bug <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: test error on refinement (Closed)" href="https://bugs.ruby-lang.org/issues/7556">#7556</a>] <a href="/issues/7556">[ruby-core:50867]</a></p>
</li>
</ul> Ruby master - Bug #7556: test error on refinementhttps://bugs.ruby-lang.org/issues/7556?journal_id=347392012-12-14T17:41:00Zphasis68 (Heesob Park)phasis@gmail.com
<ul></ul><p>It seems that inline or __inline is not respected by the compiler (ignored by compiler cost/benefit analyzer)</p>
<p>Refer to <a href="http://en.wikipedia.org/wiki/Inline_function" class="external">http://en.wikipedia.org/wiki/Inline_function</a></p> Ruby master - Bug #7556: test error on refinementhttps://bugs.ruby-lang.org/issues/7556?journal_id=347412012-12-14T17:57:55Zshugo (Shugo Maeda)
<ul></ul><p>phasis68 (Heesob Park) wrote:</p>
<blockquote>
<p>It seems that inline or __inline is not respected by the compiler (ignored by compiler cost/benefit analyzer)</p>
<p>Refer to <a href="http://en.wikipedia.org/wiki/Inline_function" class="external">http://en.wikipedia.org/wiki/Inline_function</a></p>
</blockquote>
<p>I know it, but I don't know why __forceinline prevent user functions (in this case, vm_call_general and vm_call_super_method) to be optimized into a single function.</p> Ruby master - Bug #7556: test error on refinementhttps://bugs.ruby-lang.org/issues/7556?journal_id=347422012-12-14T18:29:09Zphasis68 (Heesob Park)phasis@gmail.com
<ul></ul><p>2012/12/14 shugo (Shugo Maeda) <a href="mailto:redmine@ruby-lang.org" class="email">redmine@ruby-lang.org</a></p>
<blockquote>
<p>Issue <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: test error on refinement (Closed)" href="https://bugs.ruby-lang.org/issues/7556">#7556</a> has been updated by shugo (Shugo Maeda).</p>
<p>phasis68 (Heesob Park) wrote:</p>
<blockquote>
<p>It seems that inline or __inline is not respected by the compiler<br>
(ignored by compiler cost/benefit analyzer)</p>
<p>Refer to <a href="http://en.wikipedia.org/wiki/Inline_function" class="external">http://en.wikipedia.org/wiki/Inline_function</a></p>
</blockquote>
<p>I know it, but I don't know why __forceinline prevent user functions (in<br>
this case, vm_call_general and vm_call_super_method) to be optimized into a<br>
single function.</p>
</blockquote>
<p>The __forceinline keyword overrides the cost/benefit analysis and<br>
relies on the judgment of the programmer instead.<br>
Using __forceinline insures that all functions which call<br>
vm_call_method function have the inline expanded code instead of<br>
vm_call_method function call.<br>
Thus, vm_call_general and vm_call_super_method are separated function.</p>