Java编译器在第一次访问后省略getfield操作码是否合法?
我正在试验的Java端口是,我惊讶地发现JavaC1.8.0_60在每次访问对象字段时都会发出一个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
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");
}
}