Составители:
Рубрика:
Давайте сформулируем эти ограничения:
1. Ограничение на структуру стека вычислений.
Структура стека вычислений определяется количеством и типа-
ми значений, лежащих на стеке.
Для любой инструкции, входящей в поток инструкций, структу-
ра стека должна быть постоянной вне зависимости от того, из
какого места программы на нее передается управление.
2. Ограничение на размер стека вычислений.
В заголовке метода должна быть указана максимальная глубина
стека вычислений. Другими словами, максимальное количество
значений, которое может размещаться на стеке вычислений в
процессе выполнения метода, должно быть заранее известно
еще до JIT-компиляции этого метода.
Это ограничение, на первый взгляд, может показаться несколь-
ко странным, если принять во внимание, что благодаря ограни-
чению 1 JIT-компилятор может легко вычислить максимальную
глубину стека в процессе компиляции. Цель введения подобно-
го ограничения состоит в том, чтобы JIT-компилятор, присту-
пая к компиляции метода, мог сразу выделить нужное количест-
во памяти под свои внутренние структуры данных.
3. Ограничение на обратные переходы.
Если при последовательном переборе инструкций, формирую-
щих тело метода, JIT-компилятор встречает инструкцию, рас-
положенную сразу за инструкцией безусловного перехода, и ес-
ли на эту инструкцию еще не было перехода, то JIT-компилятор
не может вычислить структуру стека вычислений для этой инст-
рукции. В этом случае он предполагает, что стек для этой инст-
рукции должен быть пуст.
Чтобы лучше понять данную ситуацию, рассмотрим пример:
...
br L2
L1: ldc.0 ; здесь стек считается пустым
...
L2: br L1 ; обратный переход на L1
...
Когда JIT-компилятор доходит до инструкции ldc.0, расположен-
ной непосредственно после инструкции безусловного перехода br
L2, он не может определить для нее структуру стека вычислений,
так как еще не дошел до того места программы, откуда на нее пе-
редается управление. В принципе, просканировав дальше про-
грамму, это место можно обнаружить (это инструкция br L1), но
тогда алгоритм JIT-компилятора должен быть многопроходным.
Common Intermediate Language
87
3.1.1.2. Адреса переходов
В состав набора инструкций CIL входят инструкции для организации
условных и безусловных переходов. Встроенные операнды этих инструк-
ций содержат адреса переходов. При этом допустимы только такие адреса,
которые указывают на первые байты инструкций в теле данного метода.
Мы будем называть абсолютным адресом инструкции смещение пер-
вого байта инструкции относительно начала потока инструкций. Инст-
рукцию, на которую передается управление в результате выполнения ин-
струкции перехода, назовем целью перехода.
В качестве адресов перехода используются не абсолютные адреса це-
лей перехода, а так называемые относительные адреса. Относительный ад-
рес является разностью абсолютного адреса цели перехода и абсолютного
адреса инструкции, непосредственно следующей за инструкцией перехо-
да. Для того чтобы лучше понять принцип вычисления адресов перехода,
обратимся к следующему примеру:
...
target_addr: add ; цель перехода
...
br rel_addr ; инструкция перехода
next_addr: ...
Здесь используется инструкция безусловного перехода br. При этом в
качестве цели перехода выступает инструкция add, расположенная по аб-
солютному адресу target_addr. Если инструкция, следующая за инструк-
цией br, имеет абсолютный адрес next_addr, то адрес перехода rel_addr
вычисляется следующим образом:
reladdr := target_addr – next_addr
Адреса переходов кодируются во встроенных операндах инструкций
перехода в виде 8-битных или 32-битных целых чисел со знаком. При этом
8-битные адреса используются в сокращенных вариантах инструкций пе-
рехода.
3.1.1.3. Ограничения на последовательности инструкций
В спецификации языка CIL в описании каждой инструкции указаны
условия, при которых допустимо ее использование. Кроме того, на форми-
рование последовательности инструкций наложен ряд ограничений, поз-
воляющих упростить создание JIT-компилятора. Наличие этих ограниче-
ний означает, что в программах допускаются не любые сочетания инструк-
ций, а только те сочетания, которые удовлетворяют некоторым условиям.
Упрощение JIT-компилятора благодаря введению ограничений на
последовательности инструкций достигается, главным образом, за счет
того, что эти ограничения позволяют использовать в JIT-компиляторе од-
нопроходный алгоритм перевода CIL-кода в код процессора.
86
CIL и системное программирование в Microsoft .NET
86 CIL и системное программирование в Microsoft .NET Common Intermediate Language 87 3.1.1.2. Адреса переходов Давайте сформулируем эти ограничения: В состав набора инструкций CIL входят инструкции для организации 1. Ограничение на структуру стека вычислений. условных и безусловных переходов. Встроенные операнды этих инструк- Структура стека вычислений определяется количеством и типа- ций содержат адреса переходов. При этом допустимы только такие адреса, ми значений, лежащих на стеке. которые указывают на первые байты инструкций в теле данного метода. Для любой инструкции, входящей в поток инструкций, структу- Мы будем называть абсолютным адресом инструкции смещение пер- ра стека должна быть постоянной вне зависимости от того, из вого байта инструкции относительно начала потока инструкций. Инст- какого места программы на нее передается управление. рукцию, на которую передается управление в результате выполнения ин- 2. Ограничение на размер стека вычислений. струкции перехода, назовем целью перехода. В заголовке метода должна быть указана максимальная глубина В качестве адресов перехода используются не абсолютные адреса це- стека вычислений. Другими словами, максимальное количество лей перехода, а так называемые относительные адреса. Относительный ад- значений, которое может размещаться на стеке вычислений в рес является разностью абсолютного адреса цели перехода и абсолютного процессе выполнения метода, должно быть заранее известно адреса инструкции, непосредственно следующей за инструкцией перехо- еще до JIT-компиляции этого метода. да. Для того чтобы лучше понять принцип вычисления адресов перехода, Это ограничение, на первый взгляд, может показаться несколь- обратимся к следующему примеру: ко странным, если принять во внимание, что благодаря ограни- ... чению 1 JIT-компилятор может легко вычислить максимальную target_addr: add ; цель перехода глубину стека в процессе компиляции. Цель введения подобно- ... го ограничения состоит в том, чтобы JIT-компилятор, присту- br rel_addr ; инструкция перехода пая к компиляции метода, мог сразу выделить нужное количест- next_addr: ... во памяти под свои внутренние структуры данных. Здесь используется инструкция безусловного перехода br. При этом в 3. Ограничение на обратные переходы. качестве цели перехода выступает инструкция add, расположенная по аб- Если при последовательном переборе инструкций, формирую- солютному адресу target_addr. Если инструкция, следующая за инструк- щих тело метода, JIT-компилятор встречает инструкцию, рас- цией br, имеет абсолютный адрес next_addr, то адрес перехода rel_addr положенную сразу за инструкцией безусловного перехода, и ес- вычисляется следующим образом: ли на эту инструкцию еще не было перехода, то JIT-компилятор reladdr := target_addr – next_addr не может вычислить структуру стека вычислений для этой инст- Адреса переходов кодируются во встроенных операндах инструкций рукции. В этом случае он предполагает, что стек для этой инст- перехода в виде 8-битных или 32-битных целых чисел со знаком. При этом рукции должен быть пуст. 8-битные адреса используются в сокращенных вариантах инструкций пе- Чтобы лучше понять данную ситуацию, рассмотрим пример: рехода. ... br L2 3.1.1.3. Ограничения на последовательности инструкций L1: ldc.0 ; здесь стек считается пустым В спецификации языка CIL в описании каждой инструкции указаны ... условия, при которых допустимо ее использование. Кроме того, на форми- L2: br L1 ; обратный переход на L1 рование последовательности инструкций наложен ряд ограничений, поз- ... воляющих упростить создание JIT-компилятора. Наличие этих ограниче- Когда JIT-компилятор доходит до инструкции ldc.0, расположен- ний означает, что в программах допускаются не любые сочетания инструк- ной непосредственно после инструкции безусловного перехода br ций, а только те сочетания, которые удовлетворяют некоторым условиям. L2, он не может определить для нее структуру стека вычислений, Упрощение JIT-компилятора благодаря введению ограничений на так как еще не дошел до того места программы, откуда на нее пе- последовательности инструкций достигается, главным образом, за счет редается управление. В принципе, просканировав дальше про- того, что эти ограничения позволяют использовать в JIT-компиляторе од- грамму, это место можно обнаружить (это инструкция br L1), но нопроходный алгоритм перевода CIL-кода в код процессора. тогда алгоритм JIT-компилятора должен быть многопроходным.
Страницы
- « первая
- ‹ предыдущая
- …
- 48
- 49
- 50
- 51
- 52
- …
- следующая ›
- последняя »