Java编译器在第一次访问后省略getfield操作码是否合法?

Java编译器在第一次访问后省略getfield操作码是否合法?,java,jvm,javac,jls,happens-before,Java,Jvm,Javac,Jls,Happens Before,我正在试验的Java端口是,我惊讶地发现JavaC1.8.0_60在每次访问对象字段时都会发出一个getfield操作码 以下是Java代码: public class BigInteger { private int[] bits; private int sign; //... public byte[] ToByteArray() { if (sign == 0) { return new

我正在试验的Java端口是,我惊讶地发现JavaC1.8.0_60在每次访问对象字段时都会发出一个
getfield
操作码

以下是Java代码:

public class BigInteger
{
    private int[] bits;
    private int sign;

    //...

    public byte[] ToByteArray()
    {
        if (sign == 0)
        {
            return new byte[] { 0 };
        }

        byte highByte;
        int nonZeroDwordIndex = 0;
        int highDword;
        if (bits == null)
        {
            highByte = (byte)((sign < 0) ? 0xff : 0x00);
            highDword = sign;
        }
        else if (sign == -1)
        {
            highByte = (byte)0xff;
            assert bits.length > 0;
            assert bits[bits.length - 1] != 0;
            while (bits[nonZeroDwordIndex] == 0)
            {
                nonZeroDwordIndex++;
            }

            highDword = ~bits[bits.length - 1];
            if (bits.length - 1 == nonZeroDwordIndex)
            {
                highDword += 1;
            }
        }
        else
        {
            assert sign == 1;
            highByte = 0x00;
            highDword = bits[bits.length - 1];
        }

        byte msb;
        int msbIndex;
        if ((msb = (byte)(highDword >>> 24)) != highByte)
        {
            msbIndex = 3;
        }
        else if ((msb = (byte)(highDword >>> 16)) != highByte)
        {
            msbIndex = 2;
        }
        else if ((msb = (byte)(highDword >>> 8)) != highByte)
        {
            msbIndex = 1;
        }
        else
        {
            msb = (byte)highDword;
            msbIndex = 0;
        }

        boolean needExtraByte = (msb & 0x80) != (highByte & 0x80);
        byte[] bytes;
        int curByte = 0;
        if (bits == null)
        {
            bytes = new byte[msbIndex + 1 + (needExtraByte ? 1 : 0)];
            assert bytes.length <= 4;
        }
        else
        {
            bytes = new byte[4 * (bits.length - 1) + msbIndex + 1 + (needExtraByte ? 1 : 0)];

            for (int i = 0; i < bits.length - 1; i++)
            {
                int dword = bits[i];
                if (sign == -1)
                {
                    dword = ~dword;
                    if (i <= nonZeroDwordIndex)
                    {
                        dword = dword + 1;
                    }
                }
                for (int j = 0; j < 4; j++)
                {
                    bytes[curByte++] = (byte)dword;
                    dword >>>= 8;
                }
            }
        }
        for (int j = 0; j <= msbIndex; j++)
        {
            bytes[curByte++] = (byte)highDword;
            highDword >>>= 8;
        }
        if (needExtraByte)
        {
            bytes[bytes.length - 1] = highByte;
        }
        return bytes;
    }
}
公共类BigInteger
{
私有int[]位;
私人int标志;
//...
公共字节[]ToByteArray()
{
如果(符号==0)
{
返回新字节[]{0};
}
字节高字节;
int non-zerodwordIndex=0;
int highDword;
如果(位==null)
{
高字节=(字节)((符号<0)?0xff:0x00);
highDword=符号;
}
else if(符号==-1)
{
高字节=(字节)0xff;
断言位长度>0;
断言位[bits.length-1]!=0;
while(位[non-zerodordindex]==0)
{
非ZerodWordIndex++;
}
highDword=~位[bits.length-1];
if(bits.length-1==non-zerodwordIndex)
{
highDword+=1;
}
}
其他的
{
断言符号==1;
高字节=0x00;
highDword=位[bits.length-1];
}
字节msb;
int-msb索引;
如果((msb=(字节)(highDword>>>24))!=highByte)
{
msbIndex=3;
}
else if((msb=(字节)(highDword>>>16))!=highByte)
{
msbIndex=2;
}
else if((msb=(字节)(highDword>>>8))!=highByte)
{
msbIndex=1;
}
其他的
{
msb=(字节)高位字;
msbIndex=0;
}
布尔值needExtraByte=(msb&0x80)!=(高字节&0x80);
字节[]字节;
int=0;
如果(位==null)
{
字节=新字节[msbIndex+1+(需要额外字节?1:0)];
断言字节数。长度>=8;
}
}
}
对于(int j=0;j>>=8;
}
如果(需要额外字节)
{
字节[bytes.length-1]=高字节;
}
返回字节;
}
}
正如javap所报告的,JavaC1.8.0_60生成以下字节码:

public byte[] ToByteArray(); Code: 0: aload_0 1: getfield #3 // Field sign:I 4: ifne 15 7: iconst_1 8: newarray byte 10: dup 11: iconst_0 12: iconst_0 13: bastore 14: areturn 15: iconst_0 16: istore_2 17: aload_0 18: getfield #2 // Field bits:[I 21: ifnonnull 48 24: aload_0 25: getfield #3 // Field sign:I 28: ifge 37 31: sipush 255 34: goto 38 37: iconst_0 38: i2b 39: istore_1 40: aload_0 41: getfield #3 // Field sign:I 44: istore_3 45: goto 193 48: aload_0 49: getfield #3 // Field sign:I 52: iconst_m1 53: if_icmpne 156 56: iconst_m1 57: istore_1 58: getstatic #11 // Field $assertionsDisabled:Z 61: ifne 80 64: aload_0 65: getfield #2 // Field bits:[I 68: arraylength 69: ifgt 80 72: new #12 // class java/lang/AssertionError 75: dup 76: invokespecial #13 // Method java/lang/AssertionError."":()V 79: athrow 80: getstatic #11 // Field $assertionsDisabled:Z 83: ifne 109 86: aload_0 87: getfield #2 // Field bits:[I 90: aload_0 91: getfield #2 // Field bits:[I 94: arraylength 95: iconst_1 96: isub 97: iaload 98: ifne 109 101: new #12 // class java/lang/AssertionError 104: dup 105: invokespecial #13 // Method java/lang/AssertionError."":()V 108: athrow 109: aload_0 110: getfield #2 // Field bits:[I 113: iload_2 114: iaload 115: ifne 124 118: iinc 2, 1 121: goto 109 124: aload_0 125: getfield #2 // Field bits:[I 128: aload_0 129: getfield #2 // Field bits:[I 132: arraylength 133: iconst_1 134: isub 135: iaload 136: iconst_m1 137: ixor 138: istore_3 139: aload_0 140: getfield #2 // Field bits:[I 143: arraylength 144: iconst_1 145: isub 146: iload_2 147: if_icmpne 193 150: iinc 3, 1 153: goto 193 156: getstatic #11 // Field $assertionsDisabled:Z 159: ifne 178 162: aload_0 163: getfield #3 // Field sign:I 166: iconst_1 167: if_icmpeq 178 170: new #12 // class java/lang/AssertionError 173: dup 174: invokespecial #13 // Method java/lang/AssertionError."":()V 177: athrow 178: iconst_0 179: istore_1 180: aload_0 181: getfield #2 // Field bits:[I 184: aload_0 185: getfield #2 // Field bits:[I 188: arraylength 189: iconst_1 190: isub 191: iaload 192: istore_3 193: iload_3 194: bipush 24 196: iushr 197: i2b 198: dup 199: istore 4 201: iload_1 202: if_icmpeq 211 205: iconst_3 206: istore 5 208: goto 254 211: iload_3 212: bipush 16 214: iushr 215: i2b 216: dup 217: istore 4 219: iload_1 220: if_icmpeq 229 223: iconst_2 224: istore 5 226: goto 254 229: iload_3 230: bipush 8 232: iushr 233: i2b 234: dup 235: istore 4 237: iload_1 238: if_icmpeq 247 241: iconst_1 242: istore 5 244: goto 254 247: iload_3 248: i2b 249: istore 4 251: iconst_0 252: istore 5 254: iload 4 256: sipush 128 259: iand 260: iload_1 261: sipush 128 264: iand 265: if_icmpeq 272 268: iconst_1 269: goto 273 272: iconst_0 273: istore 6 275: iconst_0 276: istore 8 278: aload_0 279: getfield #2 // Field bits:[I 282: ifnonnull 325 285: iload 5 287: iconst_1 288: iadd 289: iload 6 291: ifeq 298 294: iconst_1 295: goto 299 298: iconst_0 299: iadd 300: newarray byte 302: astore 7 304: getstatic #11 // Field $assertionsDisabled:Z 307: ifne 443 310: aload 7 312: arraylength 313: iconst_4 314: if_icmple 443 317: new #12 // class java/lang/AssertionError 320: dup 321: invokespecial #13 // Method java/lang/AssertionError."":()V 324: athrow 325: iconst_4 326: aload_0 327: getfield #2 // Field bits:[I 330: arraylength 331: iconst_1 332: isub 333: imul 334: iload 5 336: iadd 337: iconst_1 338: iadd 339: iload 6 341: ifeq 348 344: iconst_1 345: goto 349 348: iconst_0 349: iadd 350: newarray byte 352: astore 7 354: iconst_0 355: istore 9 357: iload 9 359: aload_0 360: getfield #2 // Field bits:[I 363: arraylength 364: iconst_1 365: isub 366: if_icmpge 443 369: aload_0 370: getfield #2 // Field bits:[I 373: iload 9 375: iaload 376: istore 10 378: aload_0 379: getfield #3 // Field sign:I 382: iconst_m1 383: if_icmpne 404 386: iload 10 388: iconst_m1 389: ixor 390: istore 10 392: iload 9 394: iload_2 395: if_icmpgt 404 398: iload 10 400: iconst_1 401: iadd 402: istore 10 404: iconst_0 405: istore 11 407: iload 11 409: iconst_4 410: if_icmpge 437 413: aload 7 415: iload 8 417: iinc 8, 1 420: iload 10 422: i2b 423: bastore 424: iload 10 426: bipush 8 428: iushr 429: istore 10 431: iinc 11, 1 434: goto 407 437: iinc 9, 1 440: goto 357 443: iconst_0 444: istore 9 446: iload 9 448: iload 5 450: if_icmpgt 474 453: aload 7 455: iload 8 457: iinc 8, 1 460: iload_3 461: i2b 462: bastore 463: iload_3 464: bipush 8 466: iushr 467: istore_3 468: iinc 9, 1 471: goto 446 474: iload 6 476: ifeq 488 479: aload 7 481: aload 7 483: arraylength 484: iconst_1 485: isub 486: iload_1 487: bastore 488: aload 7 490: areturn 公共字节[]ToByteArray(); 代码: 0:aload_0 1:getfield#3//字段符号:I 4:ifne 15 7:iconst_1 8:newarray字节 10:dup 11:iconst_0 12:iconst_0 13:巴斯托 14:轮到你了 15:iconst_0 16:istore_2 17:aload_0 18:getfield#2//字段位:[I] 21:ifnonnull 48 24:aload_0 25:getfield#3//字段符号:I 28:ifge 37 31:255 34:转到38 37:iconst_0 38:i2b 39:istore_1 40:aload_0 41:getfield#3//字段符号:I 44:istore_3 45:转到193 48:aload_0 49:getfield#3//字段符号:I 52:iconst_m1 53:if_icmpne 156 56:iconst_m1 57:istore_1 58:getstatic#11//字段$assertionsDisabled:Z 61:ifne 80 64:aload_0 65:getfield#2//字段位:[I] 68:排列长度 69:ifgt 80 72:new#12//class java/lang/AssertionError 75:dup 76:invokespecial#13//方法java/lang/AssertionError。”“:()V 79:athrow 80:getstatic#11//字段$assertionsDisabled:Z 83:ifne 109 86:aload_0 87:getfield#2//字段位:[I] 90:aload_0 91:getfield#2//字段位:[I 94:排列长度 95:iconst_1 96:isub 97:I负载 98:ifne 109 101:new#12//class java/lang/AssertionError 104:dup 105:invokespecial#13//方法java/lang/AssertionError。”“:()V 108:athrow 109:aload_0 110:getfield#2//字段位:[I 113:iload_2 114:I负载 115:ifne 124 118:iinc 2,1 121:转到109 124:aload_0 125:getfield#2//字段位:[I 128:aload_0 129:getfield#2//字段位:[I 132:排列长度 133:iconst_1 134:isub 135:I负载 136:iconst_m1 137:ixor 138:istore_3 139:aload_0 140:getfield#2//字段位:[I] 143:排列长度 144:iconst_1 145:isub 146:iload_2 147:if_icmpne 193 150:iinc 3,1 153:转到193 156:getstatic#11//字段$assertionsDisabled:Z 159:ifne 178 162:aload_0 163:getfield#3//字段符号:I 166:iconst_1 167:if_icmpeq 178 170:new#12//class java/lang/AssertionError 173:dup 174:invokespecial#13//方法java/lang/AssertionError。”“:()V 177:athrow 178:iconst_0 179:历史1 180:aload_0 181:getfield#2//字段位:[I 184:aload_0 185:getfield#2//字段位:[I 188:排列长度 189:iconst_1 190:isub 191:I负载 192:istore_3 193:iload_3 194:bipush 24 196:iushr 197:i2b 198:dup 199:历史记录4 201:iload_1 202:if_icmpeq 211 205:iconst_3 206:istore 5 208:转到254 211:iload_3 212:bipush 16 214:iushr 215:i2b 216:dup 217:历史记录
public class Test {
  private boolean stop;

  public static void main(String[] args) throws InterruptedException {
    Test t = new Test();
    new Thread(t::m).start();
//    Thread.sleep(1000);
    System.out.println("stop is now true");
    t.stop = true;
  }

  private void m() {
    while (!stop);
    System.out.println("Finished");
  }

}