Языку Java присущ встроенный динамизм.
Reflection, динамическая загрузка — это то, без чего современные Java приложения просто не могут существовать, поэтому существует мнение, что AOT (статическая) компиляция вряд ли применима к Java в общем случае, а там где применима не может составить конкуренцию JIT (динамической) компиляции в плане прозводительности.
В этом докладе показывается почему это не (совсем) так, при этом рассматриваются случаи,
где у статических компиляторов действительно есть определенные сложности в обработке динамической семантики Java.
Также упоминается, где статическая компиляции для Java может быть полезна.
47. A a;
… è
a.foo();
if (RT_Type(a) in CHA) {
inlined body of foo()
} else {
a.foo();
}
Идея: метод не перегружается – невиртуальный
Анализ иерархии классов (CHA)
47
48. Формальный vs фактический тип
A a; //A – формальный тип
Если A – формальный тип переменой a,
то во время исполнения в a могут находится значения типа
наследника A. Такие типы называются фактическими.
A a = new B(); //B – фактический тип
Источником фактических типов для статического анализа являются
операторы new.
48
50. Типовый анализ
A a = b? new B() : new C();
a.foo();
Если foo() в B и С один и тоже, то
a.foo() невиртуальный вызов
(можно инлайнить)
50
51. Типовый анализ
A a = b? bar() : baz();
…
a.foo();
Если bar() возвращает только new B,
а baz() экземпляры new С, то
a.foo() - опять невиртуальный вызов
(можно инлайнить)
51
58. Пример
ArrayList list = getCollection();
ArrayList.ListItr iter = new ListItr(list);
while (iter.hasNext()) {
Object o = iter.next();
doSomething(o);
}
58
59. Пример
ArrayList list = getCollection();
ArrayList.ListItr iter = onStack ListItr();
iter.this$0 = list;
iter.cursor = 0;
iter.size = list.elemData.length;
while (iter.hasNext()) {
Object o = iter.next();
doSomething(o);
}
59
60. Пример
ArrayList list = getCollection();
ArrayList.ListItr iter = onStack ListItr(list);
iter.this$0 = list;
iter.cursor = 0;
iter.size = list.elemData.length;
while (iter.cursor < iter.size) {
int index = iter.cursor++;
Object o = iter.this$0.elemData[index];
doSomething(o);
}
60
61. Пример
ArrayList list = getCollection();
int cursor = 0;
int size = list.elemData.length;
while (cursor < size) {
Object o = list.elemData[cursor++];
doSomething(o);
}
61
62. Пример
ArrayList list = getCollection();
int size = list.elemData.length;
for (int i = 0; i < size; i++) {
doSomething(list.elemData[i]);
}
62