Wszystkie programy mają środowisko wykonawcze. Mamy tendencję do zapominania o tym, ale tam jest. Standardowa biblioteka lib dla C, która otacza wywołania systemowe do systemu operacyjnego. Objective-C ma środowisko wykonawcze, które otacza wszystkie przekazywane wiadomości.
W Javie środowiskiem wykonawczym jest JVM. Większość implementacji Java, które znają ludzie, jest podobna do HotSpot JVM, która jest interpretatorem kodu bajtowego i kompilatorem JIT.
To nie musi być jedyna implementacja. Nie ma absolutnie nic, co mówi, że nie można zbudować standardowego środowiska wykonawczego lib dla języka Java i skompilować kodu do natywnego kodu maszynowego i uruchomić go w środowisku wykonawczym, które obsługuje wywołania nowych obiektów w mallocach i dostęp do plików do wywołań systemowych na komputerze. I to właśnie robi kompilator Ahead Of Time (AOT zamiast JIT). Zadzwoń, że czas pracy, co będzie ... można nazwać to wdrożenie JVM (i to nie przestrzegać specyfikacji JVM) lub środowiska wykonawczego lub standardowego lib dla Javy. Jest tam i robi zasadniczo to samo.
Można to zrobić albo przez ponowną implementację, javac
aby celować w maszynę natywną (tak właśnie zrobił GCJ ). Lub można to zrobić z tłumaczeniem generowanego przez bajt kodu na kod javac
maszynowy (lub bajtowy) dla innej maszyny - to właśnie robi Android. Na podstawie Wikipedii to właśnie robi Excelsior JET („Kompilator przekształca przenośny bajtowy kod Java w zoptymalizowane pliki wykonywalne dla pożądanego sprzętu i systemu operacyjnego (OS)”), i to samo dotyczy RoboVM .
Istnieją dodatkowe komplikacje związane z Javą, co oznacza, że jest to bardzo trudne do wykonania jako ekskluzywne podejście. Dynamiczne ładowanie klas ( class.forName()
) lub obiektów proxy wymaga dynamiki, której kompilatory AOT nie zapewniają łatwo, dlatego ich odpowiednie maszyny JVM muszą również zawierać kompilator JIT (Excelsior JET) lub interpreter (GCJ) do obsługi klas, których nie można wstępnie skompilować ojczysty.
Pamiętaj, że JVM jest specyfikacją , z wielu implementacjach . Biblioteka standardowa C jest także specyfikacją z wieloma różnymi implementacjami.
W Javie 8 wykonano sporo pracy przy kompilacji AOT. W najlepszym razie podsumowanie AOT można podsumować tylko w ramach pola tekstowego. Jednak na JVM Language Summit w 2015 r. (Sierpień 2015 r.) Odbyła się prezentacja: Java Goes AOT (wideo z YouTube). Ten film ma 40 minut i opisuje wiele głębszych aspektów technicznych i testów wydajności.
gcj
minimalny możliwy do uruchomienia przykładMożesz także zaobserwować implementację typu open source, taką jak
gcj
(teraz przestarzała). Np. Plik Java:Następnie skompiluj i uruchom z:
Teraz możesz go zdekompilować i zobaczyć, jak to działa.
file Main.o
mówi, że to plik elfa.readelf -d Main | grep NEEDED
mówi, że zależy to od bibliotek dynamicznych:Więc libgcj.so musi być tam, gdzie implementowana jest funkcjonalność Java.
Następnie możesz go zdekompilować za pomocą:
i zobacz dokładnie, jak to jest realizowane.
Wygląda bardzo podobnie do C ++, wielu zmian nazw i pośrednich wywołań funkcji polimorficznych.
Zastanawiam się, jak zaczyna się śmieciarstwo. Warto przyjrzeć się: /programming/7100776/garbage-collection-implementation-in-compiled- languages i innych skompilowanych językach z GC jak Go.
Testowane na Ubuntu 14.04, GCC 4.8.4.
Spójrz również na https://en.wikipedia.org/wiki/Android_Runtime , szkielet systemu Android 5 i nowszych, który robi pełne AOT w celu optymalizacji aplikacji na Androida.
źródło