Новости
Ця стаття - переклад статті
Віртуальна машина (VM) це абстракція над рівнем операційної системи, яка дозволяє емулювати фізичну машину. Віртуальна машина дозволяє запускати одну і ту ж платформу під різними операційними системами і апаратними архітектурами. Інтерпретатори Java і Python можна розглядати як приклади, в яких код компілюється в специфічний для їх віртуальних машин байт код. Теж можна спостерігати і в архітектурі Microsoft .Net, де код компілюється в проміжний мова для CLR (Common Language Runtime).
Що повинно входити в реалізацію віртуальної машини? Вона повинна емулювати операції фізичного процесора, а так само в ідеалі містити наступні концепції:
- компіляція вихідного коду в специфічний для даної віртуальної машини байткод
- структури даних для зберігання інструкцій і операндів (дані і процес їх обробки)
- стек викликів для виконання операцій в функції
- "Покажчик інструкції" (IP) вказує на следующии виконувану інструкцію
- віртуальний ЦП - обробного інструкції
- доставляються покажчиком інструкції
- декодування операндів
- виконання інструкції
Існує два основних способи реалізації віртуальної машини: стековий і реєстровий. Приклад стековой віртуальної машини - віртуальна машина Java, .Net CLR, це широко використовуваний метод реалізації віртуальної машини. Як реєстрової віртуальної машини можна назвати Lua VM і Dalvik VM (яку ми коротко розглянемо). Різниця між цими двома підходами в механізмі використовується для запису та отримання операндів і результатів виконання команд.
Стекова віртуальна машина
Стекова віртуальна машина реалізує основні, вище описані властивості віртуальної машини, але в якості структури даних, куди поміщаються операнди, використовується стек. Операції отримують дані з стека, обробляють їх і заносять в стек результат за правилом LIFO (останній прийшов, перший пішов). У стековой віртуальній машині, операція додавання двох чисел повинна виконуватися таким способом (де 20, 7, і "результат" - операнди):
POP 20 POP 7 ADD 20, 7, result PUSH result
Через операцій PUSH і POP для операції додавання потрібно 4 інструкції. Перевага стековой моделі в тому, що операнди задаються неявно покажчиком стека (на малюнку - SP). Це означає, що віртуальній машині не потрібно явно вказувати адреси операндів, покажчик стека вказує на наступний операнд. У стекових віртуальних машинах все арифметичні і логічні операції виконуються за допомогою отримання операндів і повернення результатів в стек.
Реєстрові віртуальні машини
У реєстрової реалізації віртуальної машини структура даних, в яку поміщаються операнди, заснована на регістрах процесора. При цьому не потрібні операції PUSH або POP, але інструкції повинні явно містити адреси (регістри) в яких містяться операнди. Тобто, операнди для інструкцій, на відміну від стековой моделі, вказуються явно. Наприклад, операція додавання в реєстрової віртуальній машині виглядає приблизно так:
ADD R1, R2, R3; # Складає вміст R1 і R2, результат заносить в R3
За рахунок відсутності операцій POP і PUSH команди в реєстрової віртуальній машині виконуються швидше аналогічних команд стековой віртуальної машини.
Інша перевага реєстрової моделі в тому що вона дозволяє провести оптимізацію, яка не може бути виконана при стекового підході. Наприклад кілька разів зустрічається вираз при регістровому підході може бути обчислено лиш одного разу і збережено в регістрі для подальшого використання, що економить час, необхідний для перерахунку вираження.
Але з іншого боку в середньому інструкція реєстрової машини довше ніж в стековой машині, так як в ній тред явне вказівку операндів.
цікава стаття , В якій міститься проста реалізація на С реєстрової віртуальної машини. Якщо ви цікавитеся реалізацією віртуальних машин і інтерпретаторів то вас може зацікавити книга автора ANTLR Теренса Парра "Language Implementation Pattern: Create your own domain-specific and general programming languages".
Віртуальна машина DALVIK
DALVIK - реалізована google віртуальна машина для Android і виконує функцію інтерпретатора java коду на пристроях під керуванням цієї ОС. Для виконання процесу Android створює окремий екземпляр віртуальної машини. Це знижує ймовірність краху системи при падінні одного з додатків. Dalvik реалізує реєстрову модель і в відрізняються від стандартного java байткода, який виконує 8 бітні інструкції на стековой JVM, використовує 16 бітні інструкції. Регістри реалізовані в Dalvik у вигляді 4 бітових полів.
Якщо ми хочемо отримати більш детальну інформацію про те як процес отримує екземпляр віртуальної машини, ми повинні почати розгляд з моменту завантаження ядра Linux в Android:
При завантаженні системи, завантажувач операційної системи завантажує ядро в пам'ять і ініціалізує системні параметри. Незабаром після цього,
- ядро запускає Ініціалізується програму, яка є батьківським процесом по ставлення до всіх інших процесів.
- инициализирующая програма запускає системні демони і дуже важливий сервіс "зигота".
- процес зиготи створює екземпляр Dalvik, що є прабатьком всіх примірників Dalvik в системі.
- процес зиготи так само запускає BSD сокет, який прослуховує вхідні запити.
- при отриманні чергового запиту на створення нового екземпляра Dalvik VM, процес зиготи розгалужує батьківський Dalvik VM процес і передає дочірній процес запитувачу з додатком.
Це короткий опис того, як створюється і використовується віртуальна машина Dalvik в ОС Android.
Повертаючись до теми віртуальних машин, Dalvik відрізняється від звичайної віртуальної машини Java тим, що вона виконує байткод Dalvik, відмінний від звичайного java байткода. Проміжний крок між Java компілятором і Dalvik VM, на якому відбувається перетворення Java байткода в байткод Dalvik бере на себе DEX компілятор. Ралічіе між JVM і Dalvik проілюстріровано на наступній діаграмі (запозиченої з книги - Learning Android ).
DEX компілятор перетворює .class файли java в .dex файли, які мають менший розмір і оптимізовані для Dalvik VM.
На закінчення …
Не можна однозначно сказати, що стековая віртуальна машина краще ніж реєстрова або навпаки. Це питання залишається дискусійним і цікавою областю для досліджень. ось цікава стаття в якій автор реалізує традиційну JVM як реєстрову VM, і описує деякі отримані цікаві результати.
Що повинно входити в реалізацію віртуальної машини?