Выбрать главу

Идея, лежащая в основе Singularity, не нова. Разработчики программного обеспечения давно осознали невозможность полного контроля со стороны операционной системы за так называемым неуправляемым кодом. Кодом, созданным разнообразными компиляторами, способными допускать ошибки, неточности и двоякости трактования исходного текста программ. Кодом, которому операционная система передаёт управление в момент переключения задач и который за отведённый ему квант времени способен натворить много бед. Только потому, что система не знает, как он работает и с какими объектами взаимодействует.

Вообще-то для обуздания неуправляемого кода существует аппаратная архитектура, основанная на изоляции адресных пространств памяти каждого процесса, кольцах безопасности и продуманном механизме переключении задач. Но прямое её использование существенно снижает производительность системы, в которой трудится множество программ (аппаратное переключение контекста процесса требует сотни циклов работы процессора). Кроме того, все преимущества аппаратной поддержки защиты памяти сводятся на нет лояльностью к вопросам работы с разделяемыми объектами и данными - основой коммуникаций процессов в нынешних системах.

В системах, подобных Singularity, предполагается тщательная верификация кода программы, которая будет в данный момент выполняться. Результат такой верификации - строгое математическое доказательство того, что этот код, именуемый проверенно безопасным (verifiably safe code), в ходе своего выполнения будет работать только с положенными ему объектами и не станет вносить никаких изменений в код и данные других процессов.

То есть, запуская любую программу, система предварительно удостоверяется в полной легитимности работы и, следовательно, полностью контролирует процесс её выполнения. Это и есть идея управляемого выполнения кода.

В такой модели работы процессов для них не требуется аппаратно выделять изолированные адресные пространства памяти и следить за тем, чтобы их границы не были нарушены. Поскольку все будущие действия процесса верифицированы и строго доказана их безопасность для системы и других процессов, то можно сказать, что работа процессов изолирована друг от друга программным способом. Даже располагаясь в едином адресном пространстве памяти, процессы не смогут помешать работе друг друга.

Но разве предварительная верификация кода не снижает производительность системы? Ведь такая проверка не менее затратна по времени и ресурсам, чем переключение процессов.

Ответ на этот вопрос кроется в прогрессе программных платформ управляемого выполнения кода. Основанные на типобезопасных языках, таких, например, как Java или C#, и высокопроизводительных runtime компиляторах, способных "на лету" генерировать оптимальный и дотошно проверенный код, на системах сборки мусора, корректно очищающих память после завершения работы программы, подобные платформы в последнее время сделали гигантский скачок в плане производительности. Теперь она соизмерима с выполнением обычного неуправляемого кода.

Процесс управляемого выполнения кода - основа архитектуры системы Singularity. Базируется он на спецификации Microsoft CLS (Common Language Specification), поддержка которой открыта для многих из имеющихся и вновь разрабатываемых языков программирования и компиляторов для них. Согласно CLS, эти компиляторы не генерируют неуправляемый код, а создают некий промежуточный код на языке MSIL (Microsoft Intermediate Language). Дополнительно с генерацией кода MISL они создают манифест - метаданные программы, в которых чётко описаны её типы, сведения о необходимых программе внешних объектах и правила взаимодействия с ними. Код MISL и манифест упаковываются в исполняемый PE (portable executable) файл.

Спецификация Microsoft CLS лежит в основе не только системы Singularity, но и среды разработки для традиционных систем .NET Framework

Дальше происходит компиляция MISL-кода в машинный код, специфичный для системы команд процессора, на котором запущена Singularity. Занимаются этим процессом или JIT-компилятор (just-in-time), генерирующий машинные команды для процессора "на лету", или же программа-генератор NGen (Native Image Generator), создающая традиционный исполняемый образ. Важным является то, что в ходе работы и JIT-компилятора, и программы NGen создаваемый машинный код проверяется на типобезопасность. В случае доказательства того, что полученный код типобезопасен, он исполняется, в противном случае генерируется исключение. Программа не прошла проверку и требует внесения изменений в свой исходный текст.