2015-09-10 31 views
13

java ma argument -XX:MaxInlineLevel (z wartością domyślną 9), który kontroluje maksymalną liczbę połączeń zagnieżdżonych do wbudowanych. Dlaczego istnieje taki limit? Dlaczego nie ma zwykłej heurystyki opartej na częstotliwości i rozmiarze kodu wystarczającym, aby JVM zadecydowała sama o tym, jak głęboko wbudować?Dlaczego JVM ma maksymalną głębokość wiersza?

(jest to poproszony przez JitWatch pokazując mi, że głęboko zagnieżdżone Guava checkArgument rozmowa nie była inlined powodu głębokości)

+0

Nie jest to wcale pewne, ale prawdopodobnie uniknięcie wzajemnych pułapek rekurencyjnych, które mogą być trudne/drogie do obrony w inny sposób. – OldCurmudgeon

+1

@ OldCurmudgeon, ale masz MaxRecursiveInlineLevel – MrSimpleMind

+0

@MrSimpleMind - Interesujące - dlatego jestem wyraźnie w błędzie. To musi być inny powód. – OldCurmudgeon

Odpowiedz

10

Niektóre znaczące poszukiwania odkrywa to ciekawy mały fragment (I rzeczywiście dostał miarę stronie z wyszukiwarki Google):

if (inline_depth() > MaxInlineLevel) { 
     return "inlining too deep"; 
    } 
    if (method() == callee_method 
      && inline_depth() > MaxRecursiveInlineLevel) { 
     return "recursively inlining too deep"; 
    } 

które sugerują, że MaxInlineLevel jest zgodnie z oczekiwaniami sztywny limit na to, jak głęboko idziesz przed zatrzymać inline. Sugeruje także, że numer MaxRecursiveInlineLevel odnosi się tylko do bezpośrednich wywołań rekursywnych, a nie do wywołań rekurencyjnych, takich jak foo(), wywołujących bar(), które wywołują foo().

Więc myślę, że miał rację w Domyślam komentarza - MaxInlineLevel jest ochrona przed wzajemnego rekursji ponieważ do wykrycia, że ​​trzeba zachować odniesień do pełnej głębokości stosu wywołań inline.

MaxInlineResursionLevel Sterowanie foo() wywołań foo().

Należy zauważyć, że kod, do którego występuje odwołanie, może nie być prawdziwą maszyną JVM.

Komentarze od @apangin znajdują bardziej nowoczesną wersję hotspotu z Open JDK 8, sugerują, że obecnie nie jest to już tak proste. Wygląda na to, że cały stos jest poszukiwany dla wywołań rekursywnych, więc wzajemna rekursja może być teraz zablokowana przed przejściem obok MaxRecursiveInlineLevel.

+3

Patrzysz na bardzo stare źródła. Właściwe miejsce znajduje się pod adresem [hg.openjdk.java.net] (http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/). 'MaxRecursiveInlineLevel' zlicza rekursywne wywołania zarówno [bezpośrednie i pośrednie] (http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/c1374141598c/src/share/vm/opto/bytecodeInfo.cpp#l389). – apangin

+0

@apangin - Wydaje się, że to nie robi tego, co mówi komentarz. Również jest to tylko porównanie z 'MaxRecursiveInlineLevel'. Dobre znalezisko. – OldCurmudgeon

+3

Kop głębiej. [Pętla] (http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/c1374141598c/src/share/vm/opto/bytecodeInfo.cpp#l401) przechodzi przez wszystkie ramki sprawdzające, czy metoda wyniesienia prezentuje się w dowolnym miejscu na stosie. [MaxInlineLevel] (http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/c1374141598c/src/share/vm/opto/bytecodeInfo.cpp#l380) jest teraz ustawiony w konstruktorze InlineTree. – apangin