Статьи

Оптимизатор JikesRVM (JIT) – I

Jikes RVM включает в себя два компилятора. Одним из них является базовый компилятор, а другим — оптимизирующий компилятор, который обычно называют JIT-компилятором. Сборки BaseBase запускают JikesRVM только с базовым компилятором, где другие сборки, такие как производственная (FastAdaptive), разработка (FullAdaptive) и сборки ExtremeAssertion, имеют как базовые, так и оптимизирующие компиляторы.
Здесь мы рассмотрим оптимизирующий компилятор в Jikes RVM. Пакет org.jikesrvm.compilers содержит исходный код компиляторов, где пакет org.jikesrvm.compilers.opt содержит код оптимизирующего компилятора.

SharedBooleanOptions.dat, находящийся в каталоге / rvm / src-generate / options, определяет логические параметры для оптимизирующего компилятора. Точно так же SharedValueOptions.dat в том же каталоге определяет не булевы параметры.

1. Преобразования методов

Jikes RVM принимает методы как основную единицу оптимизации и оптимизирует их путем преобразования промежуточного представления, как показано ниже.

 Byte Code → [Optimizing Compiler] → Machine Code + Mapping Information
Информация отображения состоит из карт сбора мусора, карт исходного кода и таблиц выполнения. Оптимизирующий компилятор имеет следующие промежуточные фазовые переходы, для промежуточного представления.

High-level Intermediate Representation (HIR) → Low-level Intermediate Representation → Machine Intermediate Representation.
Общая структура генерального плана состоит из элементов,

  1. Преобразование байтовых кодов → HIR , HIR → LIR , LIR → MIR и MIR → Машинный код .
  2. Выполнение оптимизационных преобразований в HIR, LIR и MIR.
  3. Выполнение оптимизации.

2. CompilationPlan

CompilationPlan является основным классом, который инструктирует оптимизирующий компилятор, как оптимизировать данный метод. Его конструктор создает план компиляции, как видно из названия. Это включает в себя экземпляр NormalMethod, метод для оптимизации. Массив TypeReference используется вместо тех, которые определены в методе.

Он также содержит объект InstrumentationPlan, определяющий, как использовать метод для сбора информации об измерениях во время выполнения. Методы initInstrumentation () и finalizeInstrumentation () вызываются в начале компиляции и после компиляции непосредственно перед выполнением метода, соответственно.

План компиляции выполняется путем выполнения каждого элемента в плане оптимизации с помощью вызова метода execute () . Компилятор запрашивает интерфейс InlineOracle, чтобы решить, следует ли встроить сайт вызова. Если есть какие-то инструменты, которые необходимо выполнить, происходит инициализация. После контрольно-измерительных приборов происходит окончательная очистка. Однако финализация не будет выполнена, если это не удастся, за исключением. 
 

3. ОптимизацияПланЭлемент
Диаграмма классов OptimizationPlanElement

Массив OptimizationPlanElement определяет шаги компиляции. Таким образом, OptimizationPlanElement представляет элемент в плане оптимизации. Экземпляры подклассов абстрактного класса OptimizationPlanElement содержатся в OptimizationPlanner.masterPlan , и, следовательно, они представляют глобальное состояние. Неправильно хранить любое состояние для каждой компиляции в поле экземпляра этих объектов. OptimizationPlanner указывает порядок выполнения на этапах HIR и LIR для метода. Метод reportStats () генерирует отчет о времени, потраченном на выполнение элемента.

Метод shouldPerform () определяет, должен ли план оптимизации выполняться и быть частью плана компиляции, обращаясь к переданному объекту OptOptions. Когда элемент включен, включаются также все агрегатные элементы, компонентом которых является этот элемент. Работа, представленная элементом, выполняется в плане оптимизации с помощью execute (). Предполагается, что проделанная работа каким-то образом модифицирует Промежуточное Представление ( IR ). Execute () элемента агрегата вызовет все элементы execute ().

Клиент — это драйвер компилятора, который создает конкретный план оптимизации, включая все OptimizationPlanElement из мастер-плана, которые подходят для этого экземпляра компиляции.


4. ОптимизацияPlanAtomicElement

Финальный класс OptimizationPlanAtomicElement расширяет OptimizationPlanElement. Этот объект состоит из одной фазы компилятора в плане компилятора. Основная работа класса выполняется его фазой, которая является экземпляром класса CompilerPhase . Каждая фаза перекрывает этот абстрактный класс, и , в частности абстрактных методов выполнения (), который делает фактическую работу, и GetName (), который получает название фазы. Новый экземпляр фазы создается при вызове shouldPerform () и удаляется по завершении метода. Следовательно, состояние каждой компиляции содержится в экземплярах подклассов CompilerPhase, так как это состояние не сохраняется в элементе.


5. OptimizationPlanCompositeElement

Аналогично, OptimizationPlanCompositeElement является базовым классом всех элементов в плане компилятора, который объединяет вместе другие элементы OptimizationPlan, как показано на рисунке . Здесь хранится массив OptimizationPlanElement для хранения элементов, составляющих этот составной элемент. Конструктор объединяет элементы, переданные в качестве параметра метода, в составной элемент. Если фаза хочет, чтобы IR сбрасывался до или после выполнения, его можно включить с помощью printingEnabled (). По умолчанию это отключено, когда подклассы могут переопределить этот метод и сделать его истинным.