Нашли или выдавили из себя код, который нельзя назвать нормальным,
на который без улыбки не взглянешь?
Не торопитесь его удалять или рефакторить, — запостите его на
говнокод.ру, посмеёмся вместе!
// https://llvm.org/doxygen/AArch64AddressingModes_8h_source.html#l00051
/// getShiftName - Get the string encoding for the shift type.
static inline const char *getShiftExtendName(AArch64_AM::ShiftExtendType ST) {
switch (ST) {
default: llvm_unreachable("unhandled shift type!");
case AArch64_AM::LSL: return "lsl";
case AArch64_AM::LSR: return "lsr";
case AArch64_AM::ASR: return "asr";
case AArch64_AM::ROR: return "ror";
case AArch64_AM::MSL: return "msl";
case AArch64_AM::UXTB: return "uxtb";
case AArch64_AM::UXTH: return "uxth";
case AArch64_AM::UXTW: return "uxtw";
case AArch64_AM::UXTX: return "uxtx";
case AArch64_AM::SXTB: return "sxtb";
case AArch64_AM::SXTH: return "sxth";
case AArch64_AM::SXTW: return "sxtw";
case AArch64_AM::SXTX: return "sxtx";
}
return nullptr;
}
Хорош ли тот язык, в котором такую херню надо писать?
И да, часто слышу возгласы, что вот в GCC код такой запутанный и непонятный, черт ногу сломит, то ли дело LLVM. Так вот хренушки. Я смотрю код этого LLVM и я б не сказал, что это сильно проше макроговнокода из GCC
/// About Cost Model numbers used below it's necessary to say the following:
/// the numbers correspond to some "generic" X86 CPU instead of usage of
/// concrete CPU model. Usually the numbers correspond to CPU where the feature
/// apeared at the first time. For example, if we do Subtarget.hasSSE42() in
/// the lookups below the cost is based on Nehalem as that was the first CPU
/// to support that feature level and thus has most likely the worst case cost.
Да, это конечно гениальная идея, тупо назначить каким-то инструкциям "стоимость", и оптимизировать так, чтоб стоимость была минимальной под некий "Generic" CPU.
И конечно же хуй знает откуда взятые значения этой самой "стоимости":
которые вряд ли кто пересматривает. Схуя б не сделать некий конфигурационный файл с этими стоимостями, и чтобы кто-то мог легко эти говностоимости в конфиге поменять и пересобрать, померять изменения пирфоманса откомпилированных программ? Хуй там, иди в исходнике ковыряйся, ручками переписывай!
Эти яблоумники не осилили отличную от захардкоженной директорию с компилятором, поэтому если вдруг кто-то захочет просто взять и попробовать «LLVM», то придётся либо ебаться и править исходники, либо ебаться и крутить-вертеть директории.
> которые вряд ли кто пересматривает.
Зачем? Зачем?
ЕМНИП так для каждого поколения штеуда и амуд они пишут свои таблицы и веса.
Причём, по-моему, их комитит производитель cpu, т.к. он больше всего заинтересован в пирформансе.
/// TODO: Develop and implement the target dependent cost model and
/// specialize cost numbers for different Cost Model Targets such as throughput,
/// code size, latency and uop count.
А та хуйня, которую скинул ты - это уже про стоимость при трансформировании этих LLVM в какую-то другую поеботу.
Компиляторы это такая очень заебаная многоуровневая хуита, и вот на одном говнопредставлении там процессор считается как "Generic X86" и никакого учета говноархитектуры там нет. А в более низком абстрактном говнопредставлении - да, там учитывается
А в более низком абстрактном
говнопредставлении - да, там учитывается, говно там гниет и отваливается. А где-нибудь на десятом, десятом уровня - там нет вообще никакой информации. Есть только правила управления, которые нужно запомнить, чтобы управлять гусеничным креслом. При этом можно воспользоваться интуитивно заложенной командой, которая включит этот процессор. Но откуда берется эта интуиция? Похоже, что от спама. Мы много раз слышали на тренингах фразу о том, что нет разницы между Yahoo! и Goodyear. Заебись! Почему? Потому что эти люди поднимают спам-пошлину.
Лямбда "выглядит" как данные, но по сути это обычный код.
Обычно все (кроме скриптушков) про них так и думают: код.
Имхо: чтобы исполнять данные как код, нужно ебаца с защитой страниц, и вероятно еще обманывать спекулятивное выполнение, и префетчер, и вряд-ли бы такую важную фичу запилили бы таким грязным неоптимальным хаком
Технически лямбда -- это как раз данные. Захваченный контекст + указатель на заранее приготовленный конпелятором код.
Если бы она была кодом, то её пришлось бы генерить в rwx страничке. Ну собственно как gcc делает для "лямбд" в няшной, потому что там надо совместимость с обычной функцией.
XSLT -- да, наверное. Данные и код выглядят одинаково хуёво...
А TCL подошёл из-за того, что и код и данные -- просто строки, которые он даже не парсит до запуска команды? Ну хотя там же квадратные скобочки есть, у которых нет аналога в виде данных... Про TCL я сомневаюсь, в общем.
Ну вот [ ] как данные трактовать не получится, походу (они выполнятся). Только самому закавычить в { } и парсить как строку. Так что не чистая гомоиконщина получается.
Гарвардская архитектура никак не мешает компилтайм-гомоиконам. Она только в рантайме может мешать, если ты будешь набрасывать в процессе исполнения некий AST, делать из него инструкции процессора и исполнять его.
А если у тебя интерпретируемая питушня, то и гарвардская архитектура нихрена мешать не будет, если ты конечно не захочешь переписать сам интерпретатор
> Главный враг гомокион это гарвардская архитектура
Емнип, была упоротая либа для эзернета для AVR, которая генерила код для отправки пакета на флешку, а потом исполняла его. При гарвардской архитектуре, да. По-другому этот проц просто не успевал.
Т.е. раздельная память ещё не означает, что в неё вообще нельзя срать. Скорее просто неудобно или нецелесообразно.
Да, там есть инструкции чтоб срать в память для инструкций, только вот эта память является флешевой, и она от частой перезаписи быстро сдохнет. А вот под какие-то неизменяемые глобалки эту память вполне можно юзать, но читать ее тоже надо будет особыми говноинструкциями, а не как обычную оперативную память. Есть еще архитектуры, где память стекфреймов тоже как-то отдельно адресуется через какую-то сраную парашу, в Эльбрусах такую питушню вроде как делали. Там можно даже делать отдельную память для локальных переменных и отдельную память для адресов возврата, чтоб переполнением массива на стеке нельзя было в адрес возврата свою хуйню насрать с целью эксплоита
Ну такое... По идее любой указатель на стеке -- это потенциальный эксплойт при переполнении буфера. Не только адрес возврата.
Да и с другими данными, возможно, что-то могут сделать. Хоть это и будет сложнее.
З.Ы. Лучше какую-то аппаратную поддержку рейнджей прикрутить с двойными регистрами, чтобы буфера вообще не переполнялись. Интел пытался, кстати. Но получилась хуйня и её закопали.
> З.Ы. Лучше какую-то аппаратную поддержку рейнджей прикрутить с двойными регистрами, чтобы буфера вообще не переполнялись. Интел пытался, кстати. Но получилась хуйня и её закопали.
Ну так такую хуйню в Эльбрусах как раз реализовали, можешь посмотреть например тут
> Разница между дескрипторами и обычными указателями заключается в том, что помимо адреса объекта в дескрипторе сохраняется некоторая дополнительная информация, существенная для защиты. Состав этой дополнительной информации зависит от типа объекта, на который ссылается дескриптор
> Дескриптор массива кроме адреса начала массива содержит размер массива, и смещение относительно начала массива, соответствующее текущему значению указателя (рис. 1).
>Разница между дескрипторами и обычными указателями заключается в том, что помимо адреса объекта в дескрипторе сохраняется некоторая дополнительная информация, существенная для защиты. Состав этой дополнительной информации зависит от типа объекта, на который ссылается дескриптор
прямо как у виндовых объектов))
но было бы круто, если бы это было хардварно, и да: с размерами массива
Да, это можно сделать хардварно, и в Эльбрусах так сделали. Но лично я считаю эту идею хуйней т.к. даже хардварно это какие-то дополнительные расходы (дополнительная логика в процессоре, расход электричества и времени на эти говнопроверки).
> Even though Intel MPX is a specially designed hardware-assisted approach with its own added set of hardware registers, it is not faster than any of the software-based approaches. New Intel MPX instructions can cause up to 4× slowdown in the worst case, although compiler optimizations amortize it and lead to runtime overheads of ~50% on average.
> После провала 432-ой машины весь мир бросил заниматься аппаратной поддержкой языков высокого уровня. Об этом забыли в районе 84-го года и до сих пор снова не вспомнили. Все считают, что это красивая идея, однако не практичная. Считают, несмотря на то, что у нас была полная реализация этой идеи, причём реализация эффективная.
> Но к чему в итоге пришли языки высокого уровня? Все нынешние языки высокого уровня на две группы можно поделить: в одну входят языки типа Java, в другую – типа C. Java – это строгий контроль типов, но очень неэффективный. И динамики там нет. Никто даже не думает на Java операционную систему писать. По моим нормам, это не универсальный язык высокого уровня. Другая группа – С-подобные языки. Общее мнение таково, что это не языки высокого уровня. Скорее, вариант ассемблера.
> Получается, что никто в мире, кроме наших ребят-эльбрусовцев не знает действительных преимуществ языков высокого уровня. И это просто ужасно!
> Теперь, что же нужно для того, чтобы получить эти преимущества? Очень немного. Это легко сделать.
> Прежде всего, в языках и аппаратуре вводится два типа дескрипторов – пространственные и временнЫе. Пространственный дескриптор – это, фактически, указатель на данные. Он может, например, содержать размер массива и адрес начала массива. Типичные операции с таким дескриптором – индексирование (доступ к конкретному элементу массива) и взятие подмассива. Всего существует очень небольшое количество операций над указателями на данные.
> И важным моментом здесь является то, что базовый адрес для операций чтения и записи памяти может браться только с таких указателей. С их помощью аппаратура осуществляет контроль выхода за границу массива. О том, что ещё дают пространственные дескрипторы, я скажу позже, когда буду говорить о «контекстной защите».
j123123 # 0
j123123 # 0
Так, что тут у нас?
Да, это конечно гениальная идея, тупо назначить каким-то инструкциям "стоимость", и оптимизировать так, чтоб стоимость была минимальной под некий "Generic" CPU.
И конечно же хуй знает откуда взятые значения этой самой "стоимости":
которые вряд ли кто пересматривает. Схуя б не сделать некий конфигурационный файл с этими стоимостями, и чтобы кто-то мог легко эти говностоимости в конфиге поменять и пересобрать, померять изменения пирфоманса откомпилированных программ? Хуй там, иди в исходнике ковыряйся, ручками переписывай!
gologub # 0 ⇈
JloJle4Ka # 0 ⇈
Эти яблоумники не осилили отличную от захардкоженной директорию с компилятором, поэтому если вдруг кто-то захочет просто взять и попробовать «LLVM», то придётся либо ебаться и править исходники, либо ебаться и крутить-вертеть директории.
3.14159265 # 0 ⇈
Зачем? Зачем?
ЕМНИП так для каждого поколения штеуда и амуд они пишут свои таблицы и веса.
Причём, по-моему, их комитит производитель cpu, т.к. он больше всего заинтересован в пирформансе.
То что передаётся потом в -mtune
j123123 # 0 ⇈
Покажи мне в исходниках эти таблицы для каждого поколения штеуда и амуд.
3.14159265 # 0 ⇈
Файл огромен, весь приводить не буду.
В gcc тоже самое здесь: gcc/config/i386/x86-tune-costs.h
j123123 # 0 ⇈
Смотри исходник по адресу https://llvm.org/doxygen/X86TargetTransformInfo_8cpp_source.html
Обрати внимание на комментарий:
Хуйня в https://llvm.org/doxygen/X86TargetTransformInfo_8cpp_source.html описывает "стоимости" LLVM-опкодов для generic x86 процессора.
А та хуйня, которую скинул ты - это уже про стоимость при трансформировании этих LLVM в какую-то другую поеботу.
Компиляторы это такая очень заебаная многоуровневая хуита, и вот на одном говнопредставлении там процессор считается как "Generic X86" и никакого учета говноархитектуры там нет. А в более низком абстрактном говнопредставлении - да, там учитывается
Hacpy # 0 ⇈
говнопредставлении - да, там учитывается, говно там гниет и отваливается. А где-нибудь на десятом, десятом уровня - там нет вообще никакой информации. Есть только правила управления, которые нужно запомнить, чтобы управлять гусеничным креслом. При этом можно воспользоваться интуитивно заложенной командой, которая включит этот процессор. Но откуда берется эта интуиция? Похоже, что от спама. Мы много раз слышали на тренингах фразу о том, что нет разницы между Yahoo! и Goodyear. Заебись! Почему? Потому что эти люди поднимают спам-пошлину.
3.14159265 # 0 ⇈
Кстати для атома они регулярками загрепали чтобы не копипастить.
nuTepcKuu_nemyx # 0
bormand # 0 ⇈
PolinaAksenova # 0 ⇈
Desktop # 0 ⇈
nuTepcKuu_nemyx # 0 ⇈
gologub # 0 ⇈
PolinaAksenova # 0 ⇈
Desktop # 0 ⇈
booratihno # 0 ⇈
программисты на сишечке так часто делали раньше, и не всегда по собственной воле
gologub # 0 ⇈
YpaHeLI_ # 0 ⇈
PolinaAksenova # 0 ⇈
bormand # 0 ⇈
MAKAKA # 0 ⇈
Обычно все (кроме скриптушков) про них так и думают: код.
Имхо: чтобы исполнять данные как код, нужно ебаца с защитой страниц, и вероятно еще обманывать спекулятивное выполнение, и префетчер, и вряд-ли бы такую важную фичу запилили бы таким грязным неоптимальным хаком
bormand # 0 ⇈
Если бы она была кодом, то её пришлось бы генерить в rwx страничке. Ну собственно как gcc делает для "лямбд" в няшной, потому что там надо совместимость с обычной функцией.
MAKAKA # 0 ⇈
Сама лямбда -- код, а её контекст может и данные
Ну так знаете обычная процедура тоже код, а её стек -- данные
bormand # 0 ⇈
Указатель на код в структурку с данными гораздо проще засунуть )))
MAKAKA # 0 ⇈
MOV RAX, 12345
где 12345 это адрес какого-то говна с контекстом (забудем пока про PIC)
bormand # 0 ⇈
Под каждую генерить такой thunk с mov'ом? Ну gcc'шное расширение так и делает, потому что выхода нет.
MAKAKA # 0 ⇈
Код один, данные разные.
Логично один раз сгенерить код, а потом кортежи
(данные1, указатель-на-код) , (данныеN, указатель-на-код) положить в секцию данных
ну собссно как классы и делаюит, ок
bormand # 0 ⇈
MAKAKA # 0 ⇈
Блин, захваты контекста такая неоднозначная тема, конечно: в большинстве мейнстрима оно происходит неявно (вот как раз хорошо, что в крестах явно)
Обратился к переменной, и сам не заметил.
А потом блуждаешь среди ссылок когда память потекла
bormand # 0 ⇈
В крестах кстати тоже есть автозахват. Пишешь [&] или [=] и конпелятор сам разберётся что в контекст затащить.
MAKAKA # 0 ⇈
Очень часто мне кложить ничего не нужно, мне нужно просто функцию чтобы сортирнуть чото или памнуть
Мало того, что с пустыми скобочками это чище, так теперь вот я узнал, что это еще и дешевле)
bormand # 0 ⇈
Короче почитала спеку, там немного хитрее.
Лямбда это всегда класс, но в captureless случае у нее есть оператор каста в сишную функцию. Поэтому она так интуитивно и работает.
MAKAKA # 0 ⇈
выходит, я могу и свой класс так сделать, не () у него реализовывать, а каст в функцию?
bormand # 0 ⇈
Т.е. можно даже указатель на код туда не ложить если полиморфизм не нужен.
booratihno # 0 ⇈
или XLST
или TCL
Много есть могучих языков
JloJle4Ka # 0 ⇈
bormand # 0 ⇈
А TCL подошёл из-за того, что и код и данные -- просто строки, которые он даже не парсит до запуска команды? Ну хотя там же квадратные скобочки есть, у которых нет аналога в виде данных... Про TCL я сомневаюсь, в общем.
booratihno # 0 ⇈
ой,ну ладно! а где у вас еще прямо в языке есть средства для навигации по дереву типа XQuery и XPath?:)
Вы просто ненавидите XML!
>а больше он ничего и не умеет
ну да, там вроде еще массивы есть, но можно и без них.
bormand # 0 ⇈
А их вроде нет в синтаксисе, это просто команда?
Ну вот [ ] как данные трактовать не получится, походу (они выполнятся). Только самому закавычить в { } и парсить как строку. Так что не чистая гомоиконщина получается.
MAKAKA # 0 ⇈
скобочки же круглые?
>Ну вот [ ] как данные трактовать не получится,
ну да, это как $() или ` `
Тем не менее, везде TCL туда причисляют
bootcamp_dropout # 0 ⇈
MAKAKA # 0 ⇈
Любой код это просто данные
Почти любые данные это код (ну ладно, иногда это инвалид опкод)
Если ты в реальном режиме, то вообще всяческие разделения на код и данные для тебя чисто абстрактные
-----
Главный враг гомокион это гарвардская архитектура: они даже память разделили)
j123123 # 0 ⇈
А если у тебя интерпретируемая питушня, то и гарвардская архитектура нихрена мешать не будет, если ты конечно не захочешь переписать сам интерпретатор
bormand # 0 ⇈
Хотя это к интерпретаторам относится уже.
bormand # 0 ⇈
Емнип, была упоротая либа для эзернета для AVR, которая генерила код для отправки пакета на флешку, а потом исполняла его. При гарвардской архитектуре, да. По-другому этот проц просто не успевал.
Т.е. раздельная память ещё не означает, что в неё вообще нельзя срать. Скорее просто неудобно или нецелесообразно.
j123123 # 0 ⇈
bormand # 0 ⇈
Ну такое... По идее любой указатель на стеке -- это потенциальный эксплойт при переполнении буфера. Не только адрес возврата.
Да и с другими данными, возможно, что-то могут сделать. Хоть это и будет сложнее.
З.Ы. Лучше какую-то аппаратную поддержку рейнджей прикрутить с двойными регистрами, чтобы буфера вообще не переполнялись. Интел пытался, кстати. Но получилась хуйня и её закопали.
j123123 # 0 ⇈
Ну так такую хуйню в Эльбрусах как раз реализовали, можешь посмотреть например тут
> Разница между дескрипторами и обычными указателями заключается в том, что помимо адреса объекта в дескрипторе сохраняется некоторая дополнительная информация, существенная для защиты. Состав этой дополнительной информации зависит от типа объекта, на который ссылается дескриптор
> Дескриптор массива кроме адреса начала массива содержит размер массива, и смещение относительно начала массива, соответствующее текущему значению указателя (рис. 1).
DypHuu_niBEHb # 0 ⇈
прямо как у виндовых объектов))
но было бы круто, если бы это было хардварно, и да: с размерами массива
j123123 # 0 ⇈
А, ну еще есть https://en.wikipedia.org/wiki/Intel_MPX только вот софтварная проверка границ не оказывается более медленной:
> Even though Intel MPX is a specially designed hardware-assisted approach with its own added set of hardware registers, it is not faster than any of the software-based approaches. New Intel MPX instructions can cause up to 4× slowdown in the worst case, although compiler optimizations amortize it and lead to runtime overheads of ~50% on average.
j123123 # 0 ⇈
> После провала 432-ой машины весь мир бросил заниматься аппаратной поддержкой языков высокого уровня. Об этом забыли в районе 84-го года и до сих пор снова не вспомнили. Все считают, что это красивая идея, однако не практичная. Считают, несмотря на то, что у нас была полная реализация этой идеи, причём реализация эффективная.
> Но к чему в итоге пришли языки высокого уровня? Все нынешние языки высокого уровня на две группы можно поделить: в одну входят языки типа Java, в другую – типа C. Java – это строгий контроль типов, но очень неэффективный. И динамики там нет. Никто даже не думает на Java операционную систему писать. По моим нормам, это не универсальный язык высокого уровня. Другая группа – С-подобные языки. Общее мнение таково, что это не языки высокого уровня. Скорее, вариант ассемблера.
> Получается, что никто в мире, кроме наших ребят-эльбрусовцев не знает действительных преимуществ языков высокого уровня. И это просто ужасно!
> Теперь, что же нужно для того, чтобы получить эти преимущества? Очень немного. Это легко сделать.
> Прежде всего, в языках и аппаратуре вводится два типа дескрипторов – пространственные и временнЫе. Пространственный дескриптор – это, фактически, указатель на данные. Он может, например, содержать размер массива и адрес начала массива. Типичные операции с таким дескриптором – индексирование (доступ к конкретному элементу массива) и взятие подмассива. Всего существует очень небольшое количество операций над указателями на данные.
> И важным моментом здесь является то, что базовый адрес для операций чтения и записи памяти может браться только с таких указателей. С их помощью аппаратура осуществляет контроль выхода за границу массива. О том, что ещё дают пространственные дескрипторы, я скажу позже, когда буду говорить о «контекстной защите».
DypHuu_niBEHb # 0 ⇈
>аппаратной поддержкой языков высокого уровня. О
место для шутки про поддержку плавпитуха из JS в арме
gologub # 0 ⇈