2010-07-16 3 views
2

Знаете ли вы хорошие конструкции компилятора, когда вывод должен быть расположен в памяти процесса и выполнен сразу после компиляции?Конструкция компилятора для прямого выполнения

Я изучил несколько компиляторов SCHEME и прочитал все, что мог, о V8. Есть интересные методы JIT, такие как встроенное кэширование, которое я хотел бы попробовать в своем собственном компиляторе.

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

ответ

1

Частично релевантно: Principles of Artificial Intelligence Programming в Common Lisp by Peter Norvig.

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

Конечно, работая в Lisps, большая часть работы по «компиляции» уже сделана для вас языком. Я не помню, какой «исполняемый» код он создал, может быть, какой-то CL байт-код?

+0

Это правда? Я думал, что материал, сделанный backend, - настоящая работа, которую должен сделать компилятор. Разделение на промежуточный язык является менее трудной проблемой. Если нет, то я вполне доволен, потому что я знаю гораздо больше о последнем. – Cheery

+1

Я не очень квалифицирован, чтобы ответить на это. Я прочитал книгу Норвига, и он делает все, что он выглядит легко. Но это только потому, что он гений. Поскольку вы напрямую решаете проблему, вам нужно искать самого себя. –

1

Я читал книгу под названием «Лисп в маленьких пьесах», которая, как утверждается, была хорошей и обсуждала реализацию Лиспа. Если память служит, и то, что я читал, было точной, это может быть очень полезно для вас.

0

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

Другой выбор дизайна будет связан с его быстрым! Если это JIT, то вы не хотите долго ждать, я должен подумать. Предположительно это может привести к другим проектным решениям, которые вы вынуждены сделать. Я думаю, вы вряд ли пожалеете о том, что ваш компилятор будет быстрее против других ограничений.

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

+0

Кажется, нет причин? При компиляции в память вы можете быстро использовать ярлык. Элементы, которые вам нужны, могут быть загружены в память и напрямую связаны с ними, и вы можете полностью игнорировать исполняемые форматы файлов и связываться с общими объектами. Хотя, с другой стороны, вы можете добавить программу, которая устанавливает среду для программы перед ее загрузкой. – Cheery

+0

Да, именно это последнее предложение в скобках предназначалось для захвата - «с некоторой дополнительной работой». – Gian

1

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

Но как только вы решили, что такие вещи представлены (а некоторые влияют на эффективность с точки зрения макета памяти, доступности и т. Д.), Генерация кода проста.

Различия между, скажем, компилятором Scheme, который компилируется на C, а затем передает его компилятору C (который может скомпилировать его для сборки и передать его ассемблеру) vs генерирует машинные инструкции непосредственно в ОЗУ вашим компилятором.

Различные этапы дают вам возможность добавлять оптимизацию и предлагают разделение проблем.Генерирование кода C может быть проще, чем сборка или, особенно, машинный код, поскольку компилятор C может сделать для вас тяжелый подъем (например, переносимость архитектуры).

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

Компиляция на промежуточном языке (ala JVM, CLR) также может упростить, а затем вы используете JIT. Компиляция байт-кодов JVM не особенно сложна, так как это простая машина стека. ОПТИМИЗАЦИЯ этого кода - это другая проблема, но преобразование в машинный код довольно просто. CLR отличается тем, что он захватывает больше семантики скомпилированного кода. CLR больше похожа на промежуточную фазу компиляции, в отличие от JVM, которая является фактическим кодом, предназначенным для выполнения как есть.

В конце концов, это все массивы данных в ОЗУ где-нибудь, независимо от того, являются ли эти данные машинным кодом или кодом виртуальной машины. Независимо от того, находится ли этот массив в ОЗУ надлежащим образом или отображен VM из файла, это еще одна деталь. С виртуальной памятью вам, вероятно, небезразлична система.

Так что это сводится к сосредоточению на генерации кода. После того, как вам это нравится, перенаправление его другим компиляторам, оперативной памяти или файлам является небольшим шагом.

 Смежные вопросы

  • Нет связанных вопросов^_^