2010-12-12 19 views
36

C++ ma wiele dziedziczenia. Wdrożenie dziedziczenia wielokrotnego na poziomie złożenia może być dość skomplikowane, ale w trybie on-line jest dobrze descriptions (vtables, korekty pointer, thunks itp.).W jaki sposób interfejsy Java są implementowane wewnętrznie? (vtables?)

Java nie ma wielokrotnego dziedziczenia implementacji, ale ma wiele dziedziczenia interfejsu, więc nie sądzę, że prosta implementacja z pojedynczym vtable na klasę może to zaimplementować. W jaki sposób java implementuje interfejsy wewnętrznie?

Rozumiem, że w przeciwieństwie do C++, Java jest skompilowana Jit, więc różne fragmenty kodu mogą być zoptymalizowane w różny sposób, a różne maszyny JVM mogą robić różne rzeczy. Czy istnieje ogólna strategia, którą kieruje się wieloma maszynami wirtualnymi lub czy ktoś zna implementację w konkretnej maszynie JVM?

Również maszyny JVM często devirtualizują i inline wywołują metody, w którym to przypadku nie ma żadnych vtabelek lub równoważnych elementów, więc może nie mieć sensu pytanie o rzeczywiste sekwencje zestawów implementujące wywołania metod wirtualnych/interfejsu, ale zakładam, że większość Maszyny JVM nadal posiadają pewną ogólną reprezentację klas do wykorzystania, jeśli nie były w stanie odrzucić wszystkiego. Czy to założenie jest błędne? Czy ta reprezentacja wygląda w jakikolwiek sposób na vtable C++? Jeśli tak, czy interfejsy mają oddzielne vtables i jak są one powiązane z vtables klasy? Jeśli tak, instancje obiektów mogą mieć wiele podpowierzchni vtable (do vtables klasy/interfejsu), takich jak instancje obiektów w C++? Czy odniesienia do typu klasy i typu interfejsu do tego samego obiektu zawsze mają tę samą wartość binarną, czy też mogą różnić się tak, jak w C++, gdzie wymagają korekty wskaźnika?

(dla porównania: this question pyta o coś podobnego CLR, a nie wydaje się być dobrym wyjaśnienie w this msdn article mimo że mogą być nieaktualne już nie byłem w stanie znaleźć coś podobnego dla Javy.).

Edit:

  • znaczy „narzędzi” w sensie „w jaki sposób kompilator GCC realizować całkowite wywołań dodawanie/funkcja/etc”, a nie w sensie „klasy Java ArrayList implementuje interfejs listy ".
  • Jestem świadomy, jak to działa na poziomie kodu bajtowego JVM, co chcę wiedzieć, jaki rodzaj kodu i struktur danych są generowane przez JVM po zakończeniu ładowania plików klasy i kompilacji kodu bajtowego.
+2

Wspomniano o dziedziczeniu interfejsu i dziedziczeniu implementacji. Dziedziczenie implementacji jest trudne, ponieważ musisz mieć zdefiniowaną kolejność wyszukiwania. Dziedziczenie interfejsu jest o wiele prostsze. Po prostu masz mapę z wszystkimi sygnaturami metod, które muszą zostać zaimplementowane. Nie jest wymagana żadna kolejność wyszukiwania (ponieważ nie ma dołączonej implementacji). Tam nie ma porządku. – extraneon

Odpowiedz

25

Kluczową cechą maszyny wirtualnej HotSpot JVM jest inline caching. Nie oznacza to, że metoda docelowa ma charakter inklinacyjny, ale oznacza, że ​​założenie jest umieszczane w kodzie JIT, który każde przyszłe wywołanie metody wirtualnej lub interfejsu będzie skierowane na z tą samą implementacją (tj. Że strona wywoławcza jest monomorficzny). W tym przypadku sprawdzanie jest kompilowane w kodzie maszynowym, niezależnie od tego, czy założenie rzeczywiście istnieje (tj. Czy typ obiektu docelowego jest taki sam jak przed ostatnim razem), a następnie przekazać sterowanie bezpośrednio do metody docelowej - z w ogóle nie ma żadnych wirtualnych tabel. Jeśli asercja się nie powiedzie, można spróbować przekształcić ją w megamorficzną stronę wywołania (tj. Z wieloma możliwymi typami); jeśli to również się nie powiedzie (lub jeśli jest to pierwsze wywołanie), wykonywane jest regularne wyszukiwanie z długimi zwojami, używając vtables (dla metod wirtualnych) i itables (dla interfejsów).

Edit: The Hotspot Wiki ma więcej szczegółów na temat vtable i itable odcinki.W przypadku polimorfizmu nadal umieszcza wbudowaną wersję pamięci podręcznej w witrynie wywołania. Jednak kod faktycznie jest skrótem, który wykonuje odnośnik w vtable lub może być użyteczny. Istnieje jeden skrót vtable dla każdego przesunięcia tabeli (0, 1, 2, ...). Interface calls dodaj liniowe przeszukiwanie tablicy itables przed zaglądaniem do pliku możliwego do znalezienia (jeśli znaleziono) w danym przesunięciu.

+0

Te strony Hotspot Wiki dotyczące VirtualCalls i interfejsów wydają się być tym, czego szukam. Nadal trzeba jednak wszystko przeczytać. – JanKanis

+1

Wiki został przeniesiony na https://wikis.oracle.com/display/HotSpotInternals/Home –

+0

Wiki oracle zostało zamrożone, myślę, że https://wiki.openjdk.java.net/display/HotSpot/Main jest gdzie zostały zaktualizowane informacje. – JanKanis

Powiązane problemy