Top


定義場所(file name)

hotspot/src/share/vm/interpreter/bytecodes.cpp

説明(description)

// Format strings interpretation:
//
// b: bytecode
// c: signed constant, Java byte-ordering
// i: unsigned local index, Java byte-ordering (I = native byte ordering)
// j: unsigned CP cache index, Java byte-ordering (J = native byte ordering)
// k: unsigned CP index, Java byte-ordering
// o: branch offset, Java byte-ordering
// _: unused/ignored
// w: wide bytecode
//
// Note: The format strings are used for 2 purposes:
//       1. to specify the length of the bytecode
//          (= number of characters in format string)
//       2. to derive bytecode format flags (_fmt_has_k, etc.)
//
// Note: For bytecodes with variable length, the format string is the empty string.

名前(function name)

int Bytecodes::compute_flags(const char* format, int more_flags) {

本体部(body)

  {- -------------------------------------------
  (1) 
      ---------------------------------------- -}

      if (format == NULL)  return 0;  // not even more_flags
      int flags = more_flags;
      const char* fp = format;
      switch (*fp) {
      case '\0':
        flags |= _fmt_not_simple; // but variable
        break;
      case 'b':
        flags |= _fmt_not_variable;  // but simple
        ++fp;  // skip 'b'
        break;
      case 'w':
        flags |= _fmt_not_variable | _fmt_not_simple;
        ++fp;  // skip 'w'
        guarantee(*fp == 'b', "wide format must start with 'wb'");
        ++fp;  // skip 'b'
        break;
      }

      int has_nbo = 0, has_jbo = 0, has_size = 0;
      for (;;) {
        int this_flag = 0;
        char fc = *fp++;
        switch (fc) {
        case '\0':  // end of string
          assert(flags == (jchar)flags, "change _format_flags");
          return flags;

        case '_': continue;         // ignore these

        case 'j': this_flag = _fmt_has_j; has_jbo = 1; break;
        case 'k': this_flag = _fmt_has_k; has_jbo = 1; break;
        case 'i': this_flag = _fmt_has_i; has_jbo = 1; break;
        case 'c': this_flag = _fmt_has_c; has_jbo = 1; break;
        case 'o': this_flag = _fmt_has_o; has_jbo = 1; break;

        // uppercase versions mark native byte order (from Rewriter)
        // actually, only the 'J' case happens currently
        case 'J': this_flag = _fmt_has_j; has_nbo = 1; break;
        case 'K': this_flag = _fmt_has_k; has_nbo = 1; break;
        case 'I': this_flag = _fmt_has_i; has_nbo = 1; break;
        case 'C': this_flag = _fmt_has_c; has_nbo = 1; break;
        case 'O': this_flag = _fmt_has_o; has_nbo = 1; break;
        default:  guarantee(false, "bad char in format");
        }

        flags |= this_flag;

        guarantee(!(has_jbo && has_nbo), "mixed byte orders in format");
        if (has_nbo)
          flags |= _fmt_has_nbo;

        int this_size = 1;
        if (*fp == fc) {
          // advance beyond run of the same characters
          this_size = 2;
          while (*++fp == fc)  this_size++;
          switch (this_size) {
          case 2: flags |= _fmt_has_u2; break;
          case 4: flags |= _fmt_has_u4; break;
          default: guarantee(false, "bad rep count in format");
          }
        }
        guarantee(has_size == 0 ||                     // no field yet
                  this_size == has_size ||             // same size
                  this_size < has_size && *fp == '\0', // last field can be short
                  "mixed field sizes in format");
        has_size = this_size;
      }
    }

This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.