Отключение JIT и управление потоком кода в MSIL (собственная виртуальная машина) - PullRequest
1 голос
/ 06 марта 2009

Я пишу свой собственный язык сценариев на C # с некоторыми функциями, которые мне нравятся, и я решил использовать MSIL в качестве выходного байт-кода (Reflection.Emit весьма полезен, и мне не нужно придумывать другой байт-код). Он работает, испускает исполняемый файл, который можно запустить (даже декомпилировать с помощью Reflector :)) и работает довольно быстро.

Но - я хочу запустить несколько «процессов» в одном процессе + один поток и вручную контролировать назначенное им время ЦП (также реализовать гораздо более надежный IPC, предлагаемый .NET Framework). Есть ли способ полностью отключить JIT? и создать собственную виртуальную машину, шаг за шагом следуя инструкциям с помощью .NET Framework (и управляя использованием памяти и т. д.), без необходимости писать что-либо самостоятельно, или для достижения этого я должен написать всю интерпретацию MSIL?

РЕДАКТИРОВАТЬ 1): я знаю, что интерпретация IL не самая быстрая вещь во вселенной:)

РЕДАКТИРОВАТЬ 2): Чтобы уточнить - я хочу, чтобы моя виртуальная машина была своего рода «операционной системой» - она ​​получает некоторое время ЦП и распределяет его между процессами, управляет распределением памяти для них и так далее. Это не должно быть быстро, ни эффективно, но только доказательство концепции для некоторых из моих экспериментов. Мне не нужно реализовывать это на уровне обработки каждой инструкции - если это должно быть сделано в .NET, я не возражаю, я просто хочу сказать: инструкция первого шага и подождать, пока я скажу вам перейти на следующий шаг.

РЕДАКТИРОВАТЬ 3): Я понял, что ICorDebug, возможно, может удовлетворить мои потребности, теперь глядя на реализацию среды выполнения Mono.

Ответы [ 4 ]

5 голосов
/ 06 марта 2009

Вы можете использовать Mono - я полагаю, что это позволяет опции интерпретировать IL вместо JITting. Тот факт, что это открытый исходный код, означает (при условии лицензирования), что вы также сможете изменить его в соответствии со своими потребностями.

Mono не обладает всеми функциями .NET, правда, но может делать все, что вам нужно.

1 голос
/ 15 мая 2012

Одна вещь, которую вы могли бы рассмотреть, - это генерировать код в стиле конечного автомата. Позвольте мне объяснить, что я имею в виду под этим.

Когда вы пишете методы-генераторы на C # с yield return, метод компилируется во внутренний класс IEnumerator, который реализует конечный автомат. Код метода компилируется в логические блоки, которые завершаются оператором yield return или yield break, и каждый блок соответствует нумерованному состоянию. Поскольку каждый возвращаемый результат должен содержать значение, каждый блок заканчивается сохранением значения в локальном поле. Объект перечислителя, чтобы сгенерировать его следующее значение, вызывает метод, который состоит из гигантского оператора switch для номера текущего состояния, чтобы запустить текущий блок, затем перемещает состояние и возвращает значение локального поля.

Ваш язык сценариев может генерировать свои методы в аналогичном стиле, где метод соответствует объекту конечного автомата, а виртуальная машина выделяет время, перемещая конечный автомат в течение выделенного времени. Несколько хитростей в этом методе: реализовать такие вещи, как вызовы методов и блоки try / finally, сложнее, чем генерировать прямой MSIL.

1 голос
/ 06 марта 2009

Реализация Microsoft Common Language Runtime имеет только одну исполнительную систему, JIT. Mono, с другой стороны, поставляется как с JIT, так и с переводчиком.

Я, однако, не до конца понимаю, что именно вы хотите сделать сами и что вы хотели бы оставить для реализации Microsoft:

Есть ли способ полностью отключить JIT и создать собственную виртуальную машину?

и

... без необходимости что-либо писать самостоятельно, или для достижения этого я должен написать весь MSIL-интерпретацию?

является своего рода противоречием.

Если вы думаете, что вы можете написать лучшую систему исполнения, чем Microsoft JIT, вам придется писать ее с нуля. Имейте в виду, однако, что как microsofts, так и monos JIT являются высоко оптимизированными компиляторами. (стрельба по языку программирования)

Возможность точно рассчитать время ЦП для процессов операционной системы в пользовательском режиме невозможна. Это задача операционной системы.

Может быть, некоторые реализации зеленых потоков являются идеей, но это определенно тема для неуправляемого кода. Если это то, что вам нужно, взгляните на API хостинга CLR.

Я бы предложил, вы пытаетесь реализовать свой язык в CIL. В конце концов, он скомпилирован в сырой x86. Если вам не нужна проверяемость, вы можете использовать указатели там, где это необходимо.

1 голос
/ 06 марта 2009

Остерегайтесь того, что MSIL был разработан для анализа JIT-компилятором. Это не очень подходит для переводчика. Хорошим примером может быть инструкция ADD. Он используется для добавления широкого спектра значений типов значений: byte, short, int32, int64, ushort, uint32, uint64. Ваш компилятор знает, какой тип добавления требуется, но вы потеряете эту информацию о типе при генерации MSIL.

Теперь вам нужно найти его обратно во время выполнения, и для этого требуется проверить типы значений в стеке оценки. Очень медленно.

Легко интерпретируемый IL имеет специальные инструкции ADD, такие как ADD8, ADD16 и т. Д.

...