Стратегия в StringConcatFactory - PullRequest
       10

Стратегия в StringConcatFactory

0 голосов
/ 29 апреля 2018

Я знаю инструкцию invokedynamic

Также я знал базовый процесс, как он реализуется. Но когда я приеду код. Я не могу понять код в StringConcatFactory.

Можете ли вы рассказать мне, как шесть стратегий реализуются в исходном коде. Только стратегия по умолчанию также делается. Как студент университета, я не могу по исходному коду.

private enum Strategy {
    /**
     * Bytecode generator, calling into {@link java.lang.StringBuilder}.
     */
    BC_SB,

    /**
     * Bytecode generator, calling into {@link java.lang.StringBuilder};
     * but trying to estimate the required storage.
     */
    BC_SB_SIZED,

    /**
     * Bytecode generator, calling into {@link java.lang.StringBuilder};
     * but computing the required storage exactly.
     */
    BC_SB_SIZED_EXACT,

    /**
     * MethodHandle-based generator, that in the end calls into {@link java.lang.StringBuilder}.
     * This strategy also tries to estimate the required storage.
     */
    MH_SB_SIZED,

    /**
     * MethodHandle-based generator, that in the end calls into {@link java.lang.StringBuilder}.
     * This strategy also estimate the required storage exactly.
     */
    MH_SB_SIZED_EXACT,

    /**
     * MethodHandle-based generator, that constructs its own byte[] array from
     * the arguments. It computes the required storage exactly.
     */
    MH_INLINE_SIZED_EXACT
}

1 Ответ

0 голосов
/ 30 апреля 2018

makeConcat() и makeConcatWithConstants(), которые являются StringConcatFactory точками входа API, обе используют doStringConcat(), что дает CallSite, используемое invokedynamic.

doStringConcat() звонки generate(Lookup, String, MethodType, Recipe), которые содержат следующий переключатель на перечисление, о котором вы спрашиваете:

switch (STRATEGY) {
    case BC_SB:
        return StringConcatFactory.BytecodeStringBuilderStrategy.generate(lookup, className, mt, recipe, StringConcatFactory.Mode.DEFAULT);
    case BC_SB_SIZED:
        return StringConcatFactory.BytecodeStringBuilderStrategy.generate(lookup, className, mt, recipe, StringConcatFactory.Mode.SIZED);
    case BC_SB_SIZED_EXACT:
        return StringConcatFactory.BytecodeStringBuilderStrategy.generate(lookup, className, mt, recipe, StringConcatFactory.Mode.SIZED_EXACT);
    case MH_SB_SIZED:
        return StringConcatFactory.MethodHandleStringBuilderStrategy.generate(mt, recipe, StringConcatFactory.Mode.SIZED);
    case MH_SB_SIZED_EXACT:
        return StringConcatFactory.MethodHandleStringBuilderStrategy.generate(mt, recipe, StringConcatFactory.Mode.SIZED_EXACT);
    case MH_INLINE_SIZED_EXACT:
        return StringConcatFactory.MethodHandleInlineCopyStrategy.generate(mt, recipe);
    default:
        throw new StringConcatException("Concatenation strategy " + STRATEGY + " is not implemented");
}
  1. BytecodeStringBuilderStrategy ручки BC_SB, BC_SB_SIZED и BC_SB_SIZED_EXACT. Он генерирует тот же StringBuilder -используемый байт-код, который javac сгенерировал бы, если бы вы просто написали конкатенацию в своем Java-коде. Основное отличие состоит в том, что этот байт-код генерируется во время выполнения (а не во время компиляции) и загружается с использованием Unsafe.defineAnonymousClass().
  2. MethodHandleStringBuilderStrategy ручки MH_SB_SIZED и MH_SB_SIZED_EXACT. Он использует механизм MethodHandle (включая композицию MethodHandle) для построения той же цепочки конкатенации поверх вызовов StringBuilder. Он не использует частные API (например, Unsafe), поэтому это, вероятно, наименее непереносимая стратегия.
  3. MethodHandleInlineCopyStrategy ручки MH_INLINE_SIZED_EXACT. Он также использует механизм MethodHandle для построения цепочки конкатенации с композицией MethodHandle, но вместо StringBuffer он работает напрямую с байтовым массивом, избегая копирования, где это возможно. Для этого он использует некоторые внутренние API и некоторые знания о деталях реализации JDK (например, конструктор String, который избегает копирования строковых байтов). Таким образом, эта реализация более хрупкая (для изменений JDK), но она также обеспечивает большую скорость.

Небольшое резюме

Мы можем видеть, что три отличаются в двух аспектах: a) что используется в качестве буфера для построения строки и b) как создается цепочка конкатенации.

  1. BytecodeStringBuilderStrategy (BC_SB_xxx) использует StringBuilder и генерацию кода времени выполнения.
  2. MethodHandleStringBuilderStrategy (MH_SB_xxx) использует StringBuilder и MethodHandle s
  3. MethodHandleInlineCopyStrategy (MH_INLINE_SIZED_EXACT) использует байтовый массив и MethodHandle с.
...