Я проверял OpenJDK JVM Код оптимизации конкатенации строк когда я столкнулся со следующим:
cnode = recv->isa_CallStaticJava();
if (cnode == NULL) {
alloc = recv->isa_Allocate();
if (alloc == NULL) {
break;
}
// Find the constructor call
Node* result = alloc->result_cast();
if (result == NULL || !result->is_CheckCastPP() || alloc->in(TypeFunc::Memory)->is_top()) {
// strange looking allocation
#ifndef PRODUCT
if (PrintOptimizeStringConcat) {
tty->print("giving up because allocation looks strange ");
alloc->jvms()->dump_spec(tty); tty->cr();
}
#endif
break;
}
Во-первых, я не уверен, что cnode
, я думаю cnode
это некоторый тип представления объекта для вызова со знаком плюс «+» (для конкатенации строк). Сейчас, result
это вызов соответствующего знака плюс StringBuilder
конструктор. Хорошо, еще раз не уверен, но я думаю, что если не создано ни одного узла, или узел не является CheckCastPP, или объектное представление созданного размещения находится сверху стека, оптимизация не будет продолжена.
Что такое CheckCastPP и может ли моя интерпретация быть правильной?
Функция, которую вы смотрите — PhaseStringOpts::build_candidate(CallStaticJavaNode* call)
— начинается с StringBuilder.toString()
вызывать узел и пытается развернуть цепочку использования в поисках типичного шаблона конкатенации:
StringBuilder AllocateNode -> append() CallStaticJavaNode -> ... -> toString()
Показанный вами фрагмент проверяет тип текущего узла в цепочке. Если это CallStaticJavaNode
тогда это должен быть вызов StringBuilder.append()
иначе должно быть AllocateNode
,
На уровне JVM создание нового объекта
<init>
метод (конструктор)Для правильно сгенерированного байт-кода
new java/lang/StringBuilder
dup
invokespecial java/lang/StringBuilder.<init>()V
будет ровно одно использование AllocNode
что бросает результат в StringBuilder
,
Это то что result->is_CheckCastPP()
утверждает.