2012-05-12 20 views
18

Czy ktoś mógłby wymienić główne zadania, które musi wykonać weryfikator kodu bajtowego, aby zagwarantować poprawność programu? Czy istnieje standardowy, minimalny zestaw obowiązków zdefiniowany w specyfikacji JVM? Zastanawiam się również, czy weryfikacje obejmują inne fazy, takie jak ładowanie i inicjowanie.Obowiązki weryfikatora kodu JVM

Odpowiedz

15

Jest to określone w JVM Specification: Chapter 4.10. Verification of class Files.

Większość strony opisuje różne aspekty bezpieczeństwa typu. Aby sprawdzić, czy program jest bezpieczny pod względem typu, weryfikator musi ustalić, jakie typy operandów znajdują się w stosie argumentów w każdym punkcie programu i upewnić się, że pasują one do typu oczekiwanego przez odpowiednią instrukcję.

Inne rzeczy weryfikuje obejmują, ale nie ograniczają się do następujących:

  • Oddziały muszą mieścić się w granicach tablicy kodem metody.

  • Cele wszystkich instrukcji sterowania przepływem są każdorazowo początkiem instrukcji. W przypadku szerokiej instrukcji, szeroki kod operacji jest uważany za początek instrukcji, a kod operacyjny dający operację zmodyfikowaną przez tę szeroką instrukcję nie jest uważany za rozpoczynający instrukcję. Oddziały w środku instrukcji są niedozwolone.

  • Żadna instrukcja nie może uzyskać dostępu do lokalnej zmiennej ani jej zmodyfikować w indeksie większym lub równym liczbie zmiennych lokalnych, które wskazuje metoda przypisana.

  • Wszystkie odniesienia do puli stałej muszą być wpisami odpowiedniego typu. (Na przykład pole get get musi odnosić się do pola.)

  • Kod nie kończy się w środku instrukcji.

  • Wykonanie nie może spaść z końca kodu.

  • Dla każdej procedury obsługi wyjątku punkt początkowy i końcowy kodu chronionego przez program obsługi musi znajdować się na początku instrukcji lub, w przypadku punktu końcowego, tuż za końcem kodu. Punkt początkowy musi znajdować się przed punktem końcowym. Kod obsługi wyjątku musi rozpoczynać się od prawidłowej instrukcji i nie może rozpoczynać się od modyfikacji kodu operacyjnego przez szeroką instrukcję.

W końcowym etapie weryfikator przeprowadza również analizę przepływu danych, który zapewnia, że ​​brak odniesienia instrukcja żadnych niezainicjowane zmiennych lokalnych.

+0

Czy weryfikator Java jest włączony podczas ładowania klas z lokalnego systemu plików? Na przykład, gdy Eclipse lub Apache ładuje klasę, czy kod bajtowy jest zweryfikowany? –

7

Możesz również rzucić okiem na białą księgę Java Language Environment Jamesa Goslinga.

enter image description here

Kod bajtowy weryfikator przemierza bytecodes, konstruuje informacji o stanie typ i weryfikuje rodzaje parametrów do wszystkich instrukcji kodu bajtowego .

Ilustracja pokazuje przepływ danych i sterowania z języka kodu źródłowego Javy przez kompilator Javy do ładowarki klasy i kodu bajtowego weryfikatora i stąd na maszynie wirtualnej Javy, która zawiera system interpretera i wykonania. Ważną kwestią jest to, że program ładujący klasy Java i weryfikator kodu bajtowego nie przyjmują żadnych założeń o pierwotnym źródle strumienia kodu bajtowego - kod mógł pochodzić z lokalnego systemu lub mógł przebyć w połowie drogi wokół planety. Weryfikator kodu bajtowego działa jako rodzaj strażnika: zapewnia, że ​​kod przekazywany do interpretera Java jest w stanie dopasowania do wykonania i może działać bez obawy o złamanie interpretatora Java . Zaimportowany kod nie może być wykonywany w żaden sposób, dopóki nie przejdzie testów weryfikatora. Gdy weryfikator zrobić szereg ważnych właściwości są znane:

  • Brak przepełnienia operand stos lub cieków są znane
  • Rodzaje parametrów wszystkich instrukcji kodu bajtowego, aby zawsze być prawidłowe
  • dostępy pól obiektu znane są prawne - prywatne, publiczne lub chronione

Mimo wszystko to wydaje się piekielnie szczegółowe sprawdzanie, do czasu weryfikator kodu bajtowego wykonał swoją pracę, int Java erpreter może kontynuować, wiedząc, że kod będzie działał bezpiecznie. Znajomość właściwości powoduje, że interpreter Javy jest znacznie szybszy, ponieważ nie musi niczego sprawdzać. Nie ma sprawdzania typu operacji i sprawdzeń przepełnienia stosu. W ten sposób interpreter może działać z pełną prędkością, bez utraty niezawodności.