Java9のStringABuilder.appndの処理

Java9の変更点を調べていたら、ソースコードが見たくなってきたので、openjdkのソースコードを見てみた。
Stringに関しては以下のブログで紹介されています。

d.hatena.ne.jp

今回調べて見たのでは、StringBuilder.appendの処理。
LATIN1からUTF-16を追加するときの処理です。

ソースコード

StringBuilder

    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }

AbstractStringBuilder

    public AbstractStringBuilder append(String str) {
        if (str == null) {
            return appendNull();
        }
        int len = str.length();
        ensureCapacityInternal(count + len);
        putStringAt(count, str);
        count += len;
        return this;
    }

ensureCapacityInternalで領域を確保して、putStringAtで結合しているようです。
ensureCapacityInternalに関しては、どのようなオーバーフローを気にしているのか?newCapacityにはどのようなサイズを取得しようとしているのかが、正直良くわからなかったです。

    private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        int oldCapacity = value.length >> coder;
        if (minimumCapacity - oldCapacity > 0) {
            value = Arrays.copyOf(value,
                    newCapacity(minimumCapacity) << coder);
        }
    }
    private int newCapacity(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = value.length >> coder;
        int newCapacity = (oldCapacity << 1) + 2;
        if (newCapacity - minCapacity < 0) {
            newCapacity = minCapacity;
        }
        int SAFE_BOUND = MAX_ARRAY_SIZE >> coder;
        return (newCapacity <= 0 || SAFE_BOUND - newCapacity < 0)
            ? hugeCapacity(minCapacity)
            : newCapacity;
    }

そして本題はputStringAtです。
この中でcoderを比較して違っていたら拡張しています。

    private final void putStringAt(int index, String str) {
        if (getCoder() != str.coder()) {
            inflate();
        }
        str.getBytes(value, index, coder);
    }

ここで一文字ずつコピーしているのがわかります。

   public static void inflate(byte[] src, int srcOff, byte[] dst, int dstOff, int len) {
        // We need a range check here because 'putChar' has no checks
        checkBoundsOffCount(dstOff, len, dst);
        for (int i = 0; i < len; i++) {
            putChar(dst, dstOff++, src[srcOff++] & 0xff);
        }
    }
    static void putChar(byte[] val, int index, int c) {
        assert index >= 0 && index < length(val) : "Trusted caller missed bounds check";
        index <<= 1;
        val[index++] = (byte)(c >> HI_BYTE_SHIFT);
        val[index]   = (byte)(c >> LO_BYTE_SHIFT);
    }

感想

綺麗なソースコードが読めて、学びはたくさんあるが、読むのは結構難しい。