Mercurial > hg > truffle
comparison agent/src/share/classes/sun/jvm/hotspot/interpreter/Bytecodes.java @ 3838:6a991dcb52bb
7012081: JSR 292: SA-JDI can't read MH/MT/Indy ConstantPool entries
Reviewed-by: kvn, twisti, jrose
author | never |
---|---|
date | Thu, 21 Jul 2011 08:38:25 -0700 |
parents | 0a8e0d4345b3 |
children | da91efe96a93 |
comparison
equal
deleted
inserted
replaced
3837:43f9d800f276 | 3838:6a991dcb52bb |
---|---|
274 public static final int _return_register_finalizer = 231; | 274 public static final int _return_register_finalizer = 231; |
275 public static final int _shouldnotreachhere = 232; // For debugging | 275 public static final int _shouldnotreachhere = 232; // For debugging |
276 | 276 |
277 public static final int number_of_codes = 233; | 277 public static final int number_of_codes = 233; |
278 | 278 |
279 // Flag bits derived from format strings, can_trap, can_rewrite, etc.: | |
280 // semantic flags: | |
281 static final int _bc_can_trap = 1<<0; // bytecode execution can trap or block | |
282 static final int _bc_can_rewrite = 1<<1; // bytecode execution has an alternate form | |
283 | |
284 // format bits (determined only by the format string): | |
285 static final int _fmt_has_c = 1<<2; // constant, such as sipush "bcc" | |
286 static final int _fmt_has_j = 1<<3; // constant pool cache index, such as getfield "bjj" | |
287 static final int _fmt_has_k = 1<<4; // constant pool index, such as ldc "bk" | |
288 static final int _fmt_has_i = 1<<5; // local index, such as iload | |
289 static final int _fmt_has_o = 1<<6; // offset, such as ifeq | |
290 static final int _fmt_has_nbo = 1<<7; // contains native-order field(s) | |
291 static final int _fmt_has_u2 = 1<<8; // contains double-byte field(s) | |
292 static final int _fmt_has_u4 = 1<<9; // contains quad-byte field | |
293 static final int _fmt_not_variable = 1<<10; // not of variable length (simple or wide) | |
294 static final int _fmt_not_simple = 1<<11; // either wide or variable length | |
295 static final int _all_fmt_bits = (_fmt_not_simple*2 - _fmt_has_c); | |
296 | |
297 // Example derived format syndromes: | |
298 static final int _fmt_b = _fmt_not_variable; | |
299 static final int _fmt_bc = _fmt_b | _fmt_has_c; | |
300 static final int _fmt_bi = _fmt_b | _fmt_has_i; | |
301 static final int _fmt_bkk = _fmt_b | _fmt_has_k | _fmt_has_u2; | |
302 static final int _fmt_bJJ = _fmt_b | _fmt_has_j | _fmt_has_u2 | _fmt_has_nbo; | |
303 static final int _fmt_bo2 = _fmt_b | _fmt_has_o | _fmt_has_u2; | |
304 static final int _fmt_bo4 = _fmt_b | _fmt_has_o | _fmt_has_u4; | |
305 | |
306 | |
279 public static int specialLengthAt(Method method, int bci) { | 307 public static int specialLengthAt(Method method, int bci) { |
280 int code = codeAt(method, bci); | 308 int code = codeAt(method, bci); |
281 switch (code) { | 309 switch (code) { |
282 case _wide: | 310 case _wide: |
283 return wideLengthFor(method.getBytecodeOrBPAt(bci + 1)); | 311 return wideLengthFor(method.getBytecodeOrBPAt(bci + 1)); |
335 // find a bytecode, behind a breakpoint if necessary: | 363 // find a bytecode, behind a breakpoint if necessary: |
336 // FIXME: not yet implementable | 364 // FIXME: not yet implementable |
337 // static Code non_breakpoint_code_at(address bcp, methodOop method = null); | 365 // static Code non_breakpoint_code_at(address bcp, methodOop method = null); |
338 | 366 |
339 // Bytecode attributes | 367 // Bytecode attributes |
340 public static boolean isDefined (int code) { return 0 <= code && code < number_of_codes && _format[code] != null; } | 368 public static boolean isDefined (int code) { return 0 <= code && code < number_of_codes && flags(code, false) != 0; } |
341 public static boolean wideIsDefined(int code) { return isDefined(code) && _wide_format[code] != null; } | 369 public static boolean wideIsDefined(int code) { return isDefined(code) && flags(code, true) != 0; } |
342 public static String name (int code) { check(code); return _name [code]; } | 370 public static String name (int code) { check(code); return _name [code]; } |
343 public static String format (int code) { check(code); return _format [code]; } | 371 public static String format (int code) { check(code); return _format [code]; } |
344 public static String wideFormat (int code) { wideCheck(code); return _wide_format [code]; } | 372 public static String wideFormat (int code) { wideCheck(code); return _wide_format [code]; } |
345 public static int resultType (int code) { check(code); return _result_type [code]; } | 373 public static int resultType (int code) { check(code); return _result_type [code]; } |
346 public static int depth (int code) { check(code); return _depth [code]; } | 374 public static int depth (int code) { check(code); return _depth [code]; } |
347 public static int lengthFor (int code) { check(code); return _length [code]; } | 375 public static int lengthFor (int code) { check(code); return _lengths [code] & 0xF; } |
348 public static boolean canTrap (int code) { check(code); return _can_trap [code]; } | 376 public static int wideLengthFor(int code) { check(code); return _lengths [code] >> 4; } |
377 public static boolean canTrap (int code) { check(code); return has_all_flags(code, _bc_can_trap, false); } | |
349 public static int javaCode (int code) { check(code); return _java_code [code]; } | 378 public static int javaCode (int code) { check(code); return _java_code [code]; } |
350 public static boolean canRewrite (int code) { check(code); return _can_rewrite [code]; } | 379 public static boolean canRewrite (int code) { check(code); return has_all_flags(code, _bc_can_rewrite, false); } |
351 public static int wideLengthFor(int code) { wideCheck(code); return wideFormat(code).length(); } | 380 public static boolean native_byte_order(int code) { check(code); return has_all_flags(code, _fmt_has_nbo, false); } |
381 public static boolean uses_cp_cache (int code) { check(code); return has_all_flags(code, _fmt_has_j, false); } | |
352 public static int lengthAt (Method method, int bci) { int l = lengthFor(codeAt(method, bci)); return l > 0 ? l : specialLengthAt(method, bci); } | 382 public static int lengthAt (Method method, int bci) { int l = lengthFor(codeAt(method, bci)); return l > 0 ? l : specialLengthAt(method, bci); } |
353 public static int javaLengthAt (Method method, int bci) { int l = lengthFor(javaCode(codeAt(method, bci))); return l > 0 ? l : specialLengthAt(method, bci); } | 383 public static int javaLengthAt (Method method, int bci) { int l = lengthFor(javaCode(codeAt(method, bci))); return l > 0 ? l : specialLengthAt(method, bci); } |
354 public static boolean isJavaCode (int code) { return 0 <= code && code < number_of_java_codes; } | 384 public static boolean isJavaCode (int code) { return 0 <= code && code < number_of_java_codes; } |
355 public static boolean isFastCode (int code) { return number_of_java_codes <= code && code < number_of_codes; } | 385 public static boolean isFastCode (int code) { return number_of_java_codes <= code && code < number_of_codes; } |
356 | 386 |
359 public static boolean isAstore (int code) { return (code == _astore || code == _astore_0 || code == _astore_1 | 389 public static boolean isAstore (int code) { return (code == _astore || code == _astore_0 || code == _astore_1 |
360 || code == _astore_2 || code == _astore_3); } | 390 || code == _astore_2 || code == _astore_3); } |
361 | 391 |
362 public static boolean isZeroConst (int code) { return (code == _aconst_null || code == _iconst_0 | 392 public static boolean isZeroConst (int code) { return (code == _aconst_null || code == _iconst_0 |
363 || code == _fconst_0 || code == _dconst_0); } | 393 || code == _fconst_0 || code == _dconst_0); } |
394 | |
395 static int flags (int code, boolean is_wide) { | |
396 assert code == (code & 0xff) : "must be a byte"; | |
397 return _flags[code + (is_wide ? 256 : 0)]; | |
398 } | |
399 static int format_bits (int code, boolean is_wide) { return flags(code, is_wide) & _all_fmt_bits; } | |
400 static boolean has_all_flags (int code, int test_flags, boolean is_wide) { | |
401 return (flags(code, is_wide) & test_flags) == test_flags; | |
402 } | |
403 | |
404 static char compute_flags(String format) { | |
405 return compute_flags(format, 0); | |
406 } | |
407 static char compute_flags(String format, int more_flags) { | |
408 if (format == null) return 0; // not even more_flags | |
409 int flags = more_flags; | |
410 int fp = 0; | |
411 if (format.length() == 0) { | |
412 flags |= _fmt_not_simple; // but variable | |
413 } else { | |
414 switch (format.charAt(fp)) { | |
415 case 'b': | |
416 flags |= _fmt_not_variable; // but simple | |
417 ++fp; // skip 'b' | |
418 break; | |
419 case 'w': | |
420 flags |= _fmt_not_variable | _fmt_not_simple; | |
421 ++fp; // skip 'w' | |
422 assert(format.charAt(fp) == 'b') : "wide format must start with 'wb'"; | |
423 ++fp; // skip 'b' | |
424 break; | |
425 } | |
426 } | |
427 | |
428 boolean has_nbo = false, has_jbo = false; | |
429 int has_size = 0; | |
430 while (fp < format.length()) { | |
431 int this_flag = 0; | |
432 char fc = format.charAt(fp++); | |
433 switch (fc) { | |
434 case '_': continue; // ignore these | |
435 | |
436 case 'j': this_flag = _fmt_has_j; has_jbo = true; break; | |
437 case 'k': this_flag = _fmt_has_k; has_jbo = true; break; | |
438 case 'i': this_flag = _fmt_has_i; has_jbo = true; break; | |
439 case 'c': this_flag = _fmt_has_c; has_jbo = true; break; | |
440 case 'o': this_flag = _fmt_has_o; has_jbo = true; break; | |
441 | |
442 // uppercase versions mark native byte order (from Rewriter) | |
443 // actually, only the 'J' case happens currently | |
444 case 'J': this_flag = _fmt_has_j; has_nbo = true; break; | |
445 case 'K': this_flag = _fmt_has_k; has_nbo = true; break; | |
446 case 'I': this_flag = _fmt_has_i; has_nbo = true; break; | |
447 case 'C': this_flag = _fmt_has_c; has_nbo = true; break; | |
448 case 'O': this_flag = _fmt_has_o; has_nbo = true; break; | |
449 default: assert false : "bad char in format"; | |
450 } | |
451 | |
452 flags |= this_flag; | |
453 | |
454 assert !(has_jbo && has_nbo) : "mixed byte orders in format"; | |
455 if (has_nbo) | |
456 flags |= _fmt_has_nbo; | |
457 | |
458 int this_size = 1; | |
459 if (fp < format.length() && format.charAt(fp) == fc) { | |
460 // advance beyond run of the same characters | |
461 this_size = 2; | |
462 while (fp + 1 < format.length() && format.charAt(++fp) == fc) this_size++; | |
463 switch (this_size) { | |
464 case 2: flags |= _fmt_has_u2; break; | |
465 case 4: flags |= _fmt_has_u4; break; | |
466 default: assert false : "bad rep count in format"; | |
467 } | |
468 } | |
469 assert has_size == 0 || // no field yet | |
470 this_size == has_size || // same size | |
471 this_size < has_size && fp == format.length() : // last field can be short | |
472 "mixed field sizes in format"; | |
473 has_size = this_size; | |
474 } | |
475 | |
476 assert flags == (char)flags : "change _format_flags"; | |
477 return (char)flags; | |
478 } | |
479 | |
364 | 480 |
365 //---------------------------------------------------------------------- | 481 //---------------------------------------------------------------------- |
366 // Internals only below this point | 482 // Internals only below this point |
367 // | 483 // |
368 | 484 |
369 private static String[] _name; | 485 private static String[] _name; |
370 private static String[] _format; | 486 private static String[] _format; |
371 private static String[] _wide_format; | 487 private static String[] _wide_format; |
372 private static int[] _result_type; | 488 private static int[] _result_type; |
373 private static byte[] _depth; | 489 private static byte[] _depth; |
374 private static byte[] _length; | 490 private static byte[] _lengths; |
375 private static boolean[] _can_trap; | |
376 private static int[] _java_code; | 491 private static int[] _java_code; |
377 private static boolean[] _can_rewrite; | 492 private static char[] _flags; |
378 | 493 |
379 static { | 494 static { |
380 _name = new String [number_of_codes]; | 495 _name = new String [number_of_codes]; |
381 _format = new String [number_of_codes]; | 496 _format = new String [number_of_codes]; |
382 _wide_format = new String [number_of_codes]; | 497 _wide_format = new String [number_of_codes]; |
383 _result_type = new int [number_of_codes]; // See BasicType.java | 498 _result_type = new int [number_of_codes]; // See BasicType.java |
384 _depth = new byte [number_of_codes]; | 499 _depth = new byte [number_of_codes]; |
385 _length = new byte [number_of_codes]; | 500 _lengths = new byte [number_of_codes]; |
386 _can_trap = new boolean[number_of_codes]; | |
387 _java_code = new int [number_of_codes]; | 501 _java_code = new int [number_of_codes]; |
388 _can_rewrite = new boolean[number_of_codes]; | 502 _flags = new char[256 * 2]; // all second page for wide formats |
389 | 503 |
390 // In case we want to fetch this information from the VM in the | 504 // In case we want to fetch this information from the VM in the |
391 // future | 505 // future |
392 VM.registerVMInitializedObserver(new Observer() { | 506 VM.registerVMInitializedObserver(new Observer() { |
393 public void update(Observable o, Object data) { | 507 public void update(Observable o, Object data) { |
710 | 824 |
711 private static void def(int code, String name, String format, String wide_format, int result_type, int depth, boolean can_trap, int java_code) { | 825 private static void def(int code, String name, String format, String wide_format, int result_type, int depth, boolean can_trap, int java_code) { |
712 if (Assert.ASSERTS_ENABLED) { | 826 if (Assert.ASSERTS_ENABLED) { |
713 Assert.that(wide_format == null || format != null, "short form must exist if there's a wide form"); | 827 Assert.that(wide_format == null || format != null, "short form must exist if there's a wide form"); |
714 } | 828 } |
829 int len = (format != null ? format.length() : 0); | |
830 int wlen = (wide_format != null ? wide_format.length() : 0); | |
715 _name [code] = name; | 831 _name [code] = name; |
832 _result_type [code] = result_type; | |
833 _depth [code] = (byte) depth; | |
834 _lengths [code] = (byte)((wlen << 4) | (len & 0xF)); | |
835 _java_code [code] = java_code; | |
716 _format [code] = format; | 836 _format [code] = format; |
717 _wide_format [code] = wide_format; | 837 _wide_format [code] = wide_format; |
718 _result_type [code] = result_type; | 838 int bc_flags = 0; |
719 _depth [code] = (byte) depth; | 839 if (can_trap) bc_flags |= _bc_can_trap; |
720 _can_trap [code] = can_trap; | 840 if (java_code != code) bc_flags |= _bc_can_rewrite; |
721 _length [code] = (byte) (format != null ? format.length() : 0); | 841 _flags[code+0*256] = compute_flags(format, bc_flags); |
722 _java_code [code] = java_code; | 842 _flags[code+1*256] = compute_flags(wide_format, bc_flags); |
723 if (java_code != code) { | |
724 _can_rewrite[java_code] = true; | |
725 } else { | |
726 _can_rewrite[java_code] = false; | |
727 } | |
728 } | 843 } |
729 } | 844 } |