Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6806227

Quit coders xBufferLoop by exception on xflow

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Won't Fix
    • Icon: P5 P5
    • None
    • 6u10
    • core-libs

      A DESCRIPTION OF THE REQUEST :
      Current xBufferLoop checks the bounds of the buffers by querying Buffer by its remaining() method.
      After, the bounds are checked 2nd time internally by Buffer's get()/put() methods.


      JUSTIFICATION :
      If the first of this redundunt checks would be saved, xBufferLoop would become faster.
      See my example from UTF_8$Encoder below ...


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
              private CoderResult encodeBufferLoop(CharBuffer src, ByteBuffer dst) {

                  int mark = src.position(); // TODO: maybe instead use src.mark(); evaluate by microbenchmark!
                  while (true) try {
                      dst.mark();
                      int c = src.get();
                      if (c < 0x80) {
                          // Have at most seven bits
                          dst.put((byte)c);
                      } else if (c < 0x800) {
                          // 2 bytes, 11 bits
                          dst.put((byte)(0xc0 | ((c >> 06))));
                          dst.put((byte)(0x80 | (c & 0x3f)));
                      } else if (Surrogate.is(c)) {
                          // Have a surrogate pair
                          if (sgp == null)
                              sgp = new Surrogate.Parser();
                          int uc = sgp.parse((char)c, src); // TODO: throw exception there, if src is empty
                          if (uc < 0) {
                              src.position(mark);
                              return sgp.error();
                          }
                          dst.put((byte)(0xf0 | ((uc >> 18))));
                          dst.put((byte)(0x80 | ((uc >> 12) & 0x3f)));
                          dst.put((byte)(0x80 | ((uc >> 06) & 0x3f)));
                          dst.put((byte)(0x80 | (uc & 0x3f)));
                          mark++; //2 chars
                      } else {
                          // 3 bytes, 16 bits
                          dst.put((byte)(0xe0 | ((c >> 12))));
                          dst.put((byte)(0x80 | ((c >> 06) & 0x3f)));
                          dst.put((byte)(0x80 | (c & 0x3f)));
                      }
                      mark++;
                  } catch (BufferUnderflowException bue) {
                      return underflow(src, mark);
                  } catch (BufferOverflowException boe) {
                      dst.reset();
                      return overflow(src, mark);
                  }
              }

      ACTUAL -
              private CoderResult encodeBufferLoop(CharBuffer src, ByteBuffer dst) {

                  int mark = src.position();
                  while (src.hasRemaining()) {
                      int c = src.get();
                      if (c < 0x80) {
                          // Have at most seven bits
                          if (!dst.hasRemaining())
                              return overflow(src, mark);
                          dst.put((byte)c);
                      } else if (c < 0x800) {
                          // 2 bytes, 11 bits
                          if (dst.remaining() < 2)
                              return overflow(src, mark);
                          dst.put((byte)(0xc0 | ((c >> 06))));
                          dst.put((byte)(0x80 | (c & 0x3f)));
                      } else if (Surrogate.is(c)) {
                          // Have a surrogate pair
                          if (sgp == null)
                              sgp = new Surrogate.Parser();
                          int uc = sgp.parse((char)c, src);
                          if (uc < 0) {
                              src.position(mark);
                              return sgp.error();
                          }
                          if (dst.remaining() < 4)
                              return overflow(src, mark);
                          dst.put((byte)(0xf0 | ((uc >> 18))));
                          dst.put((byte)(0x80 | ((uc >> 12) & 0x3f)));
                          dst.put((byte)(0x80 | ((uc >> 06) & 0x3f)));
                          dst.put((byte)(0x80 | (uc & 0x3f)));
                          mark++; //2 chars
                      } else {
                          // 3 bytes, 16 bits
                          if (dst.remaining() < 3)
                              return overflow(src, mark);
                          dst.put((byte)(0xe0 | ((c >> 12))));
                          dst.put((byte)(0x80 | ((c >> 06) & 0x3f)));
                          dst.put((byte)(0x80 | (c & 0x3f)));
                      }
                      mark++;
                  }
                  src.position(mark);
                  return CoderResult.UNDERFLOW;
              }

            sherman Xueming Shen
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: