2015-09-10 5 views
13

java hat ein Argument -XX:MaxInlineLevel (mit einem Standardwert von 9), die die maximale Anzahl der geschachtelten Aufrufe von Inline steuert. Warum gibt es eine solche Grenze? Warum reichen die üblichen Heuristiken auf Basis von Häufigkeit und Code-Größe nicht aus, damit die JVM selbst entscheiden kann, wie tief sie inline ist?Warum hat die JVM eine maximale Inline-Tiefe?

(dies wird durch JitWatch aufgefordert wird, zeigt mir, dass ein tief verschachtelt Guava checkArgument Anruf wurde nicht aufgrund Tiefe inlined wird)

+0

Keineswegs sicher, aber wahrscheinlich, um gegenseitige Rekursionsfallen zu vermeiden, die sich auf andere Weise schwierig/teuer abwehren lassen. – OldCurmudgeon

+1

@OldCurmudgeon aber dann hast du die MaxRecursiveInlineLevel – MrSimpleMind

+0

@MrSimpleMind - Interessant - ich bin also eindeutig falsch. Muss ein anderer Grund sein. – OldCurmudgeon

Antwort

10

Einige bedeutende Suche deckt diese interessante kleine fragment (Ich habe tatsächlich so weit Seite die Google-Suche):

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

, die darauf hindeuten, dass die MaxInlineLevel wie erwartet eine harte Grenze, wie tief gehen Sie, bevor Sie inlining stoppen. Es schlägt auch vor, dass die MaxRecursiveInlineLevel bezieht sich nur auf direkte rekursive Aufrufe, nicht umgekehrt rekursive Aufrufe wie foo() Anrufe bar(), die foo() ruft.

Also ich denke, ich in meiner Vermutung Kommentar richtig war - MaxInlineLevel gegen gegenseitige Rekursion zu schützen, ist da zu erkennen, dass Sie Verweise auf die volle Tiefe des inlining Call-Stack halten müßten.

MaxInlineResursionLevel Steuerungen foo() Anrufe foo() Inlining.

Beachten Sie, dass der referenzierte Code möglicherweise keine echte JVM ist.

Kommentare von @apangin findet eine modernere Version von Hotspot von Open JDK 8 vermuten, dass es heutzutage nicht mehr ganz so einfach ist. Es sieht so aus, als ob der vollständige Stapel nach rekursiven Aufrufen durchsucht wird, so dass die gegenseitige Rekursion jetzt auch daran gehindert werden kann, über MaxRecursiveInlineLevel hinauszugehen.

+3

Sie sehen sich die sehr alten Quellen an. Der richtige Ort ist [hg.openjdk.java.net] (http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/). 'MaxRecursiveInlineLevel' zählt sowohl [direkte als auch indirekte] rekursive Aufrufe (http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/c1374141598c/src/share/vm/opto/bytecodeInfo.cpp#l389). – apangin

+0

@apangin - Das scheint nicht zu tun, was der Kommentar sagt. Außerdem wird nur gegen 'MaxRecursiveInlineLevel' verglichen. Gut finden, obwohl. – OldCurmudgeon

+3

Graben tiefer. [Die Schleife] (http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/c1374141598c/src/share/vm/opto/bytecodeInfo.cpp#l401) durchläuft alle Frames, um nach der aufgerufenen Methode zu suchen präsentiert sich überall auf dem Stapel. [MaxInlineLevel] (http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/c1374141598c/src/share/vm/opto/bytecodeInfo.cpp#l380) wird jetzt im InlineTree-Konstruktor festgelegt. – apangin

Verwandte Themen