hotspot/agent/src/share/classes/sun/jvm/hotspot/interpreter/Bytecodes.java
changeset 10251 71b8938a2821
parent 7662 5f31baaff55b
child 13728 882756847a04
equal deleted inserted replaced
10250:0794cd144834 10251:71b8938a2821
   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 }