2012-11-07 9 views
11

Istnieje kilka języków, które obsługują wystarczająco wydajny system typów, które mogą udowodnić podczas kompilacji, że kod nie adresuje tablicy poza jej granicami. Moje pytanie brzmi, czy gdybyśmy mieli skompilować taki język do JVM, czy jest jakiś sposób, abyśmy mogli skorzystać z tego dla wydajności i usunąć kontrole granic tablicy, które występują przy każdym dostępie do tablicy?Zhakuj maszynę JVM, aby uniknąć niepotrzebnych sprawdzeń i rzutowania na granice.

1) Wiem, że ostatnie JDK obsługuje pewną eliminację czeków związanych z tablicą, ale ponieważ wiem, że podczas kompilacji niektóre połączenia są bezpieczne, mogę bezpiecznie usunąć więcej.

2) Niektórzy mogą sądzić, że nie ma to wpływu na wydajność, ale z całą pewnością ma na to wpływ, szczególnie w ciężkich zastosowaniach macierzowych/obliczeniowych, takich jak obliczenia naukowe.

To samo pytanie dotyczące odlewania. Wiem, że coś jest pewnego rodzaju, ale Java nie robi tego z powodu swojego ograniczonego systemu typów. Czy jest jakiś sposób, aby po prostu powiedzieć JVM, aby "zaufaj mi" i pomiń wszelkie kontrole?

Zdaję sobie sprawę, że prawdopodobnie nie ma sposobu, aby to zrobić, ponieważ JVM jest ogólnie rozpowszechniany, czy rozsądnie byłoby zmodyfikować maszynę JVM za pomocą tej funkcji? Czy to jest coś, co zostało zrobione?

Jest to jedna z frustracji w kompilacji JVM do języka JVM, który wciąż jest ograniczony przez ograniczenia Javy.

+0

Zgadzam się, że kontrole graniczne mogą być czasochłonne. Jak często rzucasz? (i/lub podać więcej szczegółów) Wydaje się mało prawdopodobne, aby był znaczącym osiągnięciem wydajności w większości kodów. – user949300

+1

Nie jestem pewien, ale to jest ogólna zasada: ponieważ dowiedziałem się pewnych rzeczy na temat kodu, chcę, aby ograniczenia maszyny JVM ustąpiły, ponieważ są w tym przypadku niepotrzebne. – mentics

+0

Zajrzałeś do sun.misc.Unsafe? http://stackoverflow.com/questions/5574241/interesting-uses-of-sun-misc-unsafe Możesz uzyskać dostęp do pamięci bezpośrednio, bez sprawdzania granic, pod warunkiem, że aplikacja ma poprawne ustawienia. Nie zdziwiłbym się, gdyby w sposób bezpośredni lub pośredni dostarczył również niektóre funkcje odlewania. – Philip

Odpowiedz

3

Zasadniczo nie można tego zrobić w bezpieczny sposób bez infrastruktury proof-carrying code (PCC). PCC pozwoliłoby ci osadzić twoje rozumowanie bezpieczeństwa w pliku class. Twój zagnieżdżony dowód jest sprawdzany w czasie ładowania klasy. Klasa nie jest ładowana, jeśli w proofie jest błąd.

Jeśli JVM kiedykolwiek pozwolił ci zrzucić kontrole w czasie wykonywania bez wymogu formalnego dowodu, to, jak to określił SecurityMatt, pokona oryginalną filozofię Javy jako bezpiecznej platformy.

JVM używa specjalnej formy PCC do sprawdzania lokalnych zmiennych w metodzie. Wszystkie informacje o typowaniu lokalnie zmiennym są używane przez mechanizm ładujący klasy do sprawdzania poprawności, ale później są odrzucane.Ale to jedyny przykład pojęć PCC używanych w JVM. O ile mi wiadomo, nie ma ogólnej infrastruktury PCC dla JVM.

Kiedyś słyszałem, że istniała platforma JavaCard obsługująca mały podzestaw Java. Nie jestem pewien, czy to może być pomocne w twoim problemie.

+0

Świetne informacje! Wydaje się, że innym rozwiązaniem może być mechanizm zaufanego kodu. Niektóre wyszukiwania pokazują, że niektóre osoby pracują na PCC z Javą. Może któregoś dnia dostaniemy. – mentics

2

Jedną z kluczowych funkcji Java jest to, że nie musi "ufać" programistom, aby sprawdzać granice. Eliminuje to luki w zabezpieczeniach "przepełnienie bufora", które mogą prowadzić do tego, że napastnik może wykonać dowolny kod w aplikacji.

Pozwalając programistom na wyłączenie sprawdzania ograniczeń, Java straciłaby jedną z kluczowych funkcji - bez względu na to, jak niewłaściwy jest programista Java, w jego kodzie nie wystąpią przepełnienia bufora.

Jeśli chcesz używać języka, w którym programista jest zaufany, aby zarządzać własnymi sprawdzaniami granic, mógłbym zaproponować C++. Daje to możliwość przydzielania tablic bez automatycznego sprawdzania ograniczeń (new int []) i alokowania tablic z wbudowanym sprawdzaniem granic (std :: vector). Dodatkowo, zdecydowanie sugeruję, że zanim obwinimy granice, sprawdzając utratę prędkości w aplikacji, wykonuje się BENCHMARKING, aby ustalić, czy w kodzie jest jeszcze coś, co może powodować wąskie gardło.

Może się okazać, że dla celu kompilatora, język kodu bajtowego, taki jak MSIL, będzie lepiej pasował do potrzeb użytkownika niż kod bajtowy Java. MSIL jest silnie typowany i nie ma wielu nieefektywności, które można znaleźć w Javie.

Powiązane problemy