<p dir="ltr">It's paranoid to me because I know whether I'm using any of that stuff or not :)</p>
<p dir="ltr">@Stable isn't meant for use outside JDK right? So doesn't seem like a general solution.  And even if it were, does compiler take this at full faith? </p>
<p dir="ltr">Sent from my phone</p>
<div class="gmail_quote">On Sep 10, 2014 9:05 AM, "Remi Forax" <<a href="mailto:forax@univ-mlv.fr">forax@univ-mlv.fr</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  
    
  
  <div text="#000000" bgcolor="#FFFFFF">
    <br>
    <div>On 09/10/2014 02:41 PM, Vitaly
      Davidovich wrote:<br>
    </div>
    <blockquote type="cite">
      <p dir="ltr">I think there's a fundamental problem in trying to
        "convey" things to the compiler.  Clearly, it can't be some
        metadata approach since compiler can't just trust user blindly. 
        The only way I know to convey things is through code shape.</p>
      <p dir="ltr">One thing that bothers me is that even fields marked
        final aren't really treated as such by compiler because it's
        paranoid of things like reflection. <br>
      </p>
    </blockquote>
    <br>
    It's not paranoid, most of the dependency injection libraries,
    Hibernate or serialization code allow you to set the value of final
    field at runtime.<br>
    <br>
    <blockquote type="cite">
      <p dir="ltr"> If there was some way to reassure it that final
        fields aren't modified behind its back, then more type info can
        be captured at init time (e.g. array is not null and length is
        captured as a constant).</p>
    </blockquote>
    <br>
    @java.lang.invoke.Stable<br>
    <br>
    Rémi<br>
    <br>
    <blockquote type="cite">
      <p dir="ltr">Sent from my phone</p>
      <div class="gmail_quote">On Sep 10, 2014 6:48 AM, "Paul Sandoz"
        <<a href="mailto:paul.sandoz@oracle.com" target="_blank">paul.sandoz@oracle.com</a>>
        wrote:<br type="attribution">
        <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
          <br>
          This method:<br>
          <br>
              static int aaload(int[] a, int i) {<br>
                  int index = i & (a.length - 1);<br>
          <br>
                  return a[index];<br>
              }<br>
          <br>
          compiles to:<br>
          <br>
            0x000000010466a56c: mov    0xc(%rsi),%r11d    ;*arraylength<br>
                                                          ; implicit
          exception: dispatches to 0x000000010466a5a5<br>
            0x000000010466a570: mov    %r11d,%r10d<br>
            0x000000010466a573: dec    %r10d<br>
            0x000000010466a576: and    %r10d,%edx         ;*iand<br>
          <br>
            0x000000010466a579: cmp    %r11d,%edx<br>
            0x000000010466a57c: jae    0x000000010466a58e<br>
            0x000000010466a57e: mov    0x10(%rsi,%rdx,4),%eax<br>
          <br>
          <br>
          For the bounds check there is only one unsigned comparison
          check since the array length is non-negative (this will also
          catch the case if "i" is -ve and the array length is 0).<br>
          <br>
          If the patch for JDK-8003585 is applied the check gets
          strength reduced to:<br>
          <br>
            0x000000010d9e06ec: mov    0xc(%rsi),%r11d    ;*arraylength<br>
                                                          ; implicit
          exception: dispatches to 0x000000010d9e0725<br>
            0x000000010d9e06f0: mov    %r11d,%r10d<br>
            0x000000010d9e06f3: dec    %r10d<br>
            0x000000010d9e06f6: and    %r10d,%edx         ;*iand<br>
          <br>
            0x000000010d9e06f9: test   %r11d,%r11d<br>
            0x000000010d9e06fc: jbe    0x000000010d9e070e<br>
            0x000000010d9e06fe: mov    0x10(%rsi,%rdx,4),%eax<br>
          <br>
          and if the array is constant or there is a dominating check
          (hoisted out of a loop) then the bounds check will go away.
          More on that later.<br>
          <br>
          <br>
          This method:<br>
          <br>
              int unsafe_aaload(int[] a, int i) {<br>
                  int index = i & (a.length - 1);<br>
          <br>
                  // Emulate return a[index]<br>
                  if (index < 0 || index >= a.length)<br>
                      throw new ArrayIndexOutOfBoundsException();<br>
          <br>
                  long address = (((long) index) << 2) +
          UNSAFE.ARRAY_INT_BASE_OFFSET;<br>
                  return UNSAFE.getInt(a, address);<br>
              }<br>
          <br>
          compiles to:<br>
          <br>
            0x000000010495be8c: mov    0xc(%rdx),%r10d    ;*arraylength<br>
                                                          ; implicit
          exception: dispatches to 0x000000010495bee9<br>
            0x000000010495be90: mov    %r10d,%r8d<br>
            0x000000010495be93: dec    %r8d<br>
            0x000000010495be96: and    %r8d,%ecx          ;*iand<br>
          <br>
            0x000000010495be99: test   %ecx,%ecx<br>
            0x000000010495be9b: jl     0x000000010495beb6  ;*iflt<br>
          <br>
            0x000000010495be9d: cmp    %r10d,%ecx<br>
            0x000000010495bea0: jge    0x000000010495becd  ;*if_icmplt<br>
          <br>
            0x000000010495bea2: movslq %ecx,%r10<br>
            0x000000010495bea5: mov    0x10(%rdx,%r10,4),%eax 
          ;*invokevirtual getInt<br>
          <br>
          <br>
          The patch for JDK-8003585 makes no difference.<br>
          <br>
          (Note: in general we cannot assume that "int index = i &
          (a.length - 1)" always occurs before the bounds checks,
          otherwise i would have explicitly written "if (a.length == 0)
          throw ...")<br>
          <br>
          Ideally similar code as shown for an aaload should be
          generated. Any suggestions/ideas on how to make that happen?<br>
          <br>
          <br>
          --<br>
          <br>
          Regarding removing the bounds checks, as previously referred
          to. If it is known the array length is always > 0 the
          bounds check can be removed. The general context here is code
          in the ForkJoinPool.WorkQueue, such as:<br>
          <br>
                  final ForkJoinTask<?> poll() {<br>
                      ForkJoinTask<?>[] a; int b;
          ForkJoinTask<?> t;<br>
                      while ((b = base) - top < 0 && (a =
          array) != null) {<br>
                          int j = (((a.length - 1) & b) <<
          ASHIFT) + ABASE;<br>
                          t =
          (ForkJoinTask<?>)U.getObjectVolatile(a, j);<br>
                          if (base == b) {<br>
                              if (t != null) {<br>
                                  if (U.compareAndSwapObject(a, j, t,
          null)) {<br>
                                      base = b + 1;<br>
                                      return t;<br>
                                  }<br>
                              }<br>
                              else if (b + 1 == top) // now empty<br>
                                  break;<br>
                          }<br>
                      }<br>
                      return null;<br>
                  }<br>
          <br>
          If "array" is not null it's length is always > 0 (a zero
          length array is never allocated by the code). Is there a way
          to safely convey that knowledge to the runtime/compiler?
          thereby enabling removal of bounds checks for any replacement
          of Unsafe in such code.<br>
          <br>
          Paul.<br>
        </blockquote>
      </div>
    </blockquote>
    <br>
  </div>

</blockquote></div>