OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Понедельник, 16 Июнь, 2025 21:11

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 332 ]  На страницу Пред.  1 ... 4, 5, 6, 7, 8, 9, 10 ... 17  След.
Автор Сообщение
 Заголовок сообщения: Re: Oberon/Ur
СообщениеДобавлено: Пятница, 09 Август, 2024 23:22 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1556
наверное, все и так поняли, но у меня зуд пояснятельства. «процедурные карты» — это просто карты смещений указателей (и строк) от EBP. точнее, от некоторой другой базы, но неважно. важно то, что эти карты можно построить во время компиляции. а в ядре у нас есть такое:
Код:
  (* this is allocated on the stack for each procedure with pointers or strings *)
  ProcMapItem = POINTER TO RECORD [untagged, align1]
    prev: ProcMapItem;
    base: ADDR; (* EBP *)
    info: ProcInfo;
  END;

  ProcInfo = POINTER TO RECORD [untagged, align1]
    nameptr: ADDR; (* asciiz procedure name *)
    ptrmap: ProcVarItem; (* pointer offset map; could be NIL *)
    strmap: ProcVarItem; (* string offset map; could be NIL *)
  END;

  ProcVarItem = POINTER TO RECORD [untagged, align1]
    ofs: INTEGER; (* offset from base; -1 means "no more" *)
  END;


(* this is for GC; no need to make this writeable, the compiler knows its way around *)
VAR
  currProcMap-: ProcMapItem;

на входе в процедуру кодоген выделяет место на стеке под `ProcMapItem`, и пишет такой код:
Код:
pmi.prev := Kernel.currProcMap;
pmi.base := LocFrameAdr;
pmi.info := procinfoptr;
Kernel.currProcMap := pmi;

и, очевидно, на выходе:
Код:
Kernel.currProcMap := pmi.prev;

это всё очень дёшево: свеженький стек, который только что занулили, и `Kernel.currProcMap`, к которой обращаются всегда. `LocFrameAdr` в регистре, `procinfoptr` вообще константа.

конечно, можно было просто прибить адрес карты по известному смещению от базы и обойтись всего одним push, но тогда возникают проблемы с колбэками, и появляются эвристики для детекта «правильных EBP». а, как известно: тот, кто платит скоростью за безопасность, не получает ни скорости, ни безопасности.

карты, кстати, линейные. массивы делаются плоскими, и карта строится для всего массива. сначала я писал типы переменных, и потом в ядре код по типу всё делал. но потом передумал. рационале: а не делайте многомегабайтных массивов с указателями и строками в процедурах! всё равно компилятор оборвёт полёт мысли где-то в районе попытки выделить на стеке около 128 кб. иба ваистену.

такие же плоские карты строятся и для глобалов. там полёт мысли оборвут где-то на мегабайте. рационале то же самое: юзайте динамические массивы, выделяйте при старте модуля.

decref'ы для строк компилятор пишет прямо в процедуру. но карта всё равно нужна, чтобы раскрутить стек после трапа.

кстати, если линковать карты для всех процедур — получаем более-менее халявный backtrace. без номеров строк, правда. не особо полезно, но в качестве отладочной штуки иногда годится.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Oberon/Ur
СообщениеДобавлено: Суббота, 10 Август, 2024 09:41 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1556
итак, «эксперимент» отработал с GC. стал примерно на две секунды медленней (24 vs 22). всё ещё ощутимо шустрее BBCB (~30). после переделки GC на нерекурсивный ничего особо поменяться не должно, я думаю.

итого: примерно полтора месяца неспешной работы на полноценный компилятор оберона. даже с допфичами (дельфи-строки). если стандартный фултайм — думаю, недели три было бы. окей, на кодоген типа Nanojit с нуля понадобилось бы ещё недели две.

замечу, что если бы я изначально всё дизайнил сразу под полноценный компилятор, то было бы ещё быстрее, а код красивей. сейчас там немножко a kind of a mess. не ужас-ужас, но чуть-чуть пугалка.

да, ещё нет финализаторов. лапы не дошли просто, а так-то место в VMT предусмотрено, и всё такое.

формат указателей в итоге сделал не такой, как в BBCB, и весь memory manager с нуля сочинил.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Oberon/Ur
СообщениеДобавлено: Воскресенье, 11 Август, 2024 10:00 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1556
я зделол! теперь `MarkBlock()` нерекурсивная. точнее, рекурсивная, конечно, как иначе — но как и полагается: использует пару полей в блоке чтобы сохранять состояние. надо два поля, потому что у меня все блоки на самом деле массивы, так проще. в наше время можно растранжирить немного памяти, чтобы не писать дубликат кода для массивов и не-массивов. ну, 24 байта на заголовок блока. да фиг с ним. в принципе, можно сократить до 20 байт, но не вижу смысла. код станет запутаней только.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Oberon/Ur
СообщениеДобавлено: Воскресенье, 11 Август, 2024 23:39 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1556
вот я мощный антигаз. зачем, собственно, нам поле `base` в списке карт, если структуру можно класть всегда в начало пула локалов — и тогда её адрес и будет базой?

кстати, вспомнил, что забыл обработать аргументы-указатели. для IN, OUT и VAR это неважно, конечно — то есть, массивы в любом случае в безопасности. а вот одиноким указателям грозит, грозит. буду просто копировать их в пул — благо, этот код (для копирования аргументов) я отключил, но не выкинул.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Oberon/Ur
СообщениеДобавлено: Понедельник, 12 Август, 2024 11:36 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1556
в общем, я немного поправил ошибок в GC, и всё стало плохо аж на 27/28 секунд. всё ещё быстрее, чем в BBCB, правда. с другой стороны — у ящика куча всего в хипе уже лежит, а у O/Ur там почти пусто. так что думаю, что скорость более-менее одинаковая в итоге.

алсо, наконец-то доделал `WITH` и `CASE`. теперь вроде бы все операторы на месте.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Oberon/Ur
СообщениеДобавлено: Вторник, 13 Август, 2024 05:23 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1556
я, кстати, адски заколебался уже давно, поэтому комментарии `/* … */` и `//` тоже поддерживаются. поэтому вложеность комментариев я уберу, наверное. идея вложенности в том, чтобы было удобно комментарить код с комментариями, а когда есть несколько видов — надо просто stick to one style, и второй отлично работает как кодоотключалка. тем более что насколько я помню, вложеность комментариев ни в репортах, ни в синтаксисе не отображена. а потому что невозможно регулярками это нарисовать, хихи.

надо бы и в LC закончить документирование менеджера памяти. я там немного про формат блоков написал в своё время — надо добить логику выделения, да алгоритм пометки. там на самом деле всё очень-очень просто (что и неудивительно), но код традиционно обероновски непроницаем. когда разберёшься — то всё очевидно, но помогать разбираться код не желает.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Oberon/Ur
СообщениеДобавлено: Вторник, 13 Август, 2024 07:01 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1556
кстати, чуть не забыл. авторазыменованые указатели надо того… бережно якорить во временные локалы. иначе есть шанс их потерять.

ну, в смысле, если у нас, например, `glob: RecPtr`, и мы вызываем `SomeProc (VAR r: RecDesc);`, то глобал надо скопировать в локал. в BBCB не надо, потому что он зависнет на стеке, а стек сканируется консервативно. в O/Ur же сканер точный, поэтому незарегистрированый стековый указатель не увидит.

просто якорить в `SomeProc()` нельзя: сканер, опять-таки, точный. и при `glob: RecDesc` он сломается, потому что переданый указатель на `glob` будет ни разу не в куче.

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Oberon/Ur
СообщениеДобавлено: Вторник, 13 Август, 2024 16:19 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1556
поскольку в наножите есть инструкция перехода по таблице, то и сделал `CASE` через таблицу, если она не очень большая получается.

на самом деле для красоты надо бы сделать возможность использовать несколько таблиц — было бы удобно, если есть диапазоны с большими дырками. но пока что мне это не особо нужно: я всё равно `CASE` использую не так часто; в основном для выбора по небольшому диапазону. допилю, если необходимость появится.

вообще, система уже умеет почти всё, что надо, чтобы попытаться на неё BBCB перетащить. нет, собственно, возможности ставить обработчики трапов, да финализаторы всё забываю дописать. но это код чисто в `System:Kernel` — все трапы проходят через интринсик, там просто надо вместо `abort()` сделать раскрутку стека. собственно, это и для финализаторов надо, чтобы они систему не уронили нечаянно.

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

собственно, сам проект Oberon/Ur можно считать завершённым. не в том смысле, что я его бросаю, а в том смысле, что он работает. дальше у проекта есть несколько направлений, в которых мне хочется идти.

  • допиливание Nanojit до возможности сохранять скомпилированый код. тут надо добавить создание таблицы фиксапов разного вида. несложно, но скучно.
  • порт Nanojit и компилятора на Oberon/Ur. несложно, но бессмысленно без предыдущего пункта. (как взлетать-то? ;-)
  • порт BBCB на O/Ur. несложно, забавно, но лень. ;-)
  • играть в Doom и ждать, что из предыдущих пунктов захочется сделать. самый реалистичный вариант.

а. ещё можно оживить кодоген для x86_64. но это максимально лень; подожду, пока мне за это кто-нибудь заплатит (то есть, никогда не случится).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Oberon/Ur
СообщениеДобавлено: Вторник, 13 Август, 2024 16:53 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1556
и чуть оптимизировал кодоген для and/or. всё ещё фигово, но чуть лучше. ;-) ускорил «эксперимент» без гц почти на секунду, и с гц на целых две почти.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Oberon/Ur
СообщениеДобавлено: Вторник, 13 Август, 2024 22:45 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1556
на удивление: взял из BBCB `Strings.IntToStringForm()` — заработало. где ж я так налажал-то?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Oberon/Ur
СообщениеДобавлено: Среда, 14 Август, 2024 03:07 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2461
Откуда: Россия, Томск
arisu писал(а):
причины против две. первая: бинарного `~` не существует
Так ведь это же "приблизительное равенство": (PI ~ 3) = TRUE.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Oberon/Ur
СообщениеДобавлено: Среда, 14 Август, 2024 03:11 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1556
Александр Ильин писал(а):
arisu писал(а):
причины против две. первая: бинарного `~` не существует
Так ведь это же "приблизительное равенство": (PI ~ 3) = TRUE.
главное то, что в спеках этого нет.

впрочем, можно реализовать для чисел. возвращать рандомно TRUE или FALSE — кто там знает, какое приближение имелось в виду.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Oberon/Ur
СообщениеДобавлено: Среда, 14 Август, 2024 03:12 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1556
алсо, перетащил из ящика `Strings.RealToStringForm()`. оно даже выводит что-то очень похожее на правильное. только с округлениями непонятки.

ах, да. конечно, все перетащеные вместо писать в массив — возвращают честный STRING.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Oberon/Ur
СообщениеДобавлено: Среда, 14 Август, 2024 20:58 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1556
о. я знаю. надо какого-нибудь маленького видеоигоря на SDL напилить. кстати, Files портировать, гыг.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Oberon/Ur
СообщениеДобавлено: Среда, 14 Август, 2024 23:12 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1556
кстати хочу сказать: как здорово, что бокс на свете есть. который блэк. там за меня умные люди уже красиво сдизайнили все апи, просто бери да вору… творчески заимствуй.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Oberon/Ur
СообщениеДобавлено: Среда, 14 Август, 2024 23:25 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1556
кстати, если вдруг кому любопытно. «сейчасный» `System:Kernel` от Oberon/Ur. в нём можно посмотреть на memory manager, который — возможно — чуть проще для понимания, чем в BBCB.

а вот так в Math мы достаём мантиссу и экспоненту без ассемблера:
Код:
PROCEDURE Exponent* (v: REAL): INTEGER;
VAR e: INTEGER;
BEGIN
  e := SHR(S.GET(INTEGER, S.ADR(v) + 4), 4 + 16) MOD 2%100000000000;
  IF e = 2%100000000000 - 1 THEN e := MAX(INTEGER);
  ELSIF e = 0 THEN e := -1074; (* denormal: minimal exponent minus the number of mantissa bits *)
  ELSE DEC[unchecked](e, 1023);
  END IF
  RETURN e;
END Exponent;


PROCEDURE Mantissa* (v: REAL): REAL;
VAR
  m: SET;
  e: INTEGER;
BEGIN
  e := Exponent(v);
  IF e # MAX(INTEGER) THEN
    m := S.GET(SET, S.ADR(v) + 4);
    (* convert exponent to adjusted zero *)
    m := m - {20..30};
    m := m + {20..29};
    S.PUT(m, S.ADR(v) + 4);
  END IF
  RETURN v;
END Mantissa;


p.s.: если вдруг кто удивляется, почему либсишные апи импортируются из либм… это баг. не в компиляторе, в `dlsym()`. по какой-то загадочной причине такой импорт работал, и я вот только что этот баг заметил, гыг. полагаю, что либц можно так откуда угодно насквозь получить — просто потому, что она загружена вместе с бинарём.


Вложения:
Комментарий к файлу: current Oberon/Ur Kernel
our_kernel.7z [11.22 КБ]
Скачиваний: 109
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Oberon/Ur
СообщениеДобавлено: Четверг, 15 Август, 2024 04:31 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1556
категорически надоело, что вызовы к ещё не скомпиленым процедурам роутятся индиректом через переменную. таки пропатчил Nanojit чтобы можно было получать адреса и патчить их потом через официальный API.

тащемта, проблема изначально в том, что это только на x86 всё так просто. а на других архитектурах может случиться ёк, потому что адрес может быть слишком далеко. исходя из этого я долго не хотел так патчить, а потом подумал: да ладно! хватит себя обманывать, не будет никаких других архитектур всё равно. так что подпиливаем всё под x86, а остальные пусть раскорячатся и эмулируют её квирки, если вдруг появятся. один фиг кодоген, например, ожидает, что все входные аргументы в стеке сидят, и можно получить адрес любого из них. что очевидно не так на x86_64, и даже на арме, вроде бы.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Oberon/Ur
СообщениеДобавлено: Пятница, 16 Август, 2024 14:40 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1556
ффух. пришлось выгнуть Nanojit в интересную позу, но:
Код:
TYPE
  TryProc* = PROCEDURE (a, b, c: ADDR);

PROCEDURE Try* [no_nil_checks] (proc: TryProc; a, b, c: ADDR): INTEGER;
VAR err: INTEGER;
BEGIN
  IF proc = NIL THEN RETURN 0; END IF
  TRY ^err DO
    proc(a, b, c);
  END TRY
  RETURN err;
END Try;

соответственно, трапы в финализаторах (которые — финализаторы — я наконец сделал) теперь не фатальны. `System:Kernel.IntrinsicTrap()` делает раскрутку стека (освобождает строки), и правильно восстанавливает ESP и EBP. код, конечно, страшненький — но и неважно: это системная конструкция, для использования в нормальном коде не предназначена. на самом деле попытка использовать это вне `Try` скорее всего всё развалит нафиг. как-нибудь потом проверю, сейчас лень.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Oberon/Ur
СообщениеДобавлено: Суббота, 17 Август, 2024 08:58 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1556
надо теперь пилить вызов компилятора на лету, для эмуляции `LoadMod()`. не то чтобы сложно, но есть небольшой нюанс: я память от нод и прочего не освобождаю. в смысле, я использую bump allocator, а потом выкидываю всё вместе. а мне нужны скопы, типы, ноды-декларации, такое вот.

с другой стороны: а и фиг с ним. просто не буду аллокатор убивать пока. мне откровенно лень пилить деконструктор нужной инфы (из тайпидов и прочего). пусть болтается в памяти, не жалко. ну, пусть мегабайт оберон-кода съест десять-пятнадцать мегов на ast и прочее — who cares? как начнёт парить — переделаю.

это я подхожу к реализации `System:Files`. которой очевидно нужен системно-зависимый модуль, загружаемый из оберон-кода уже. нет, это можно захачить, конечно. но одна из прелестей оберона для меня — как раз динамическая загрузка модулей и вызов команд из них. без этого оберон довольно скучный язык с маленьким шворцем.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Oberon/Ur
СообщениеДобавлено: Суббота, 17 Август, 2024 20:26 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2461
Откуда: Россия, Томск
arisu писал(а):
Код:
[no_nil_checks]
Подчерки детектед!


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 332 ]  На страницу Пред.  1 ... 4, 5, 6, 7, 8, 9, 10 ... 17  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2025, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB