commit -m "better"
3.21K subscribers
1.01K photos
147 videos
3 files
2.35K links
just random thoughts
Download Telegram
Forwarded from Блог*
#prog

Для #java есть JEP 401: Value Classes and Objects (Preview). Value-объекты в данном случае — это объекты, у которых отсутствует идентичность. Это полезно, поскольку для многих классов, которые просто объединяют несколько полей вместе для удобства (например, LocalDateTime, или условной Point в графическом движке), наличие идентичности, отличной от совокупности значений, не имеет большого смысла.

На практике идентичность у объектов Java существует из-за того, что под них выделяется память в куче и, соответственно, у них есть уникальный адрес. Отсутствие такой идентичности позволяет генерировать более разумную реализацию оператора ==, а также делать то, что в JEP называется "heap flattening": изменение представление объекта, ссылки на который вместо хранения адреса выделенной памяти хранят значения полей объекта.

Всё это звучит хорошо, но, к сожалению, данная идея страдает от существующих элементов дизайна Java.

Первая — это повальная нуллабельность. Даже value-классы должны иметь возможность быть null, и это означает, что даже для сжатого представления один бит в ссылке должен отводиться под null-флаг. Как пишут сами авторы, массив из Integer, например, может хранить значения прямо в ссылках, но так как численные значения Integer занимают 32 бита и ещё один бит должен отводиться под null-флаг, на практике значения элементов массива будут занимать минимум по 64 бита. Это всё ещё выигрыш по сравнению с тем, что есть сейчас, поскольку это позволяет избежать индирекции на указателях и выделения 64 бита на заголовок каждого объекта в куче, но это всё ещё расточительно. Авторы явно признают эту проблему, и в разделе про дальнейшую работу есть ссылка на Null-restricted value class types JEP, но это пока лишь черновик.

Вторая проблема (которая, справедливости ради, была неочевидна индустрии на момент создания Java) — это отсутствие отслеживания алиасинга/перекрытия ссылок. В JEP авторы пишут:

Heap flattening must maintain the integrity of data. A flattened reference must always be read and written atomically, or it could become corrupted. On common platforms, this limits the size of most flattened references to no more than 64 bits.


Иными словами, выгоды от избегания аллокаций коснуться только очень маленьких объектов — особенно с учётом обязательного null-флага и паддинга под него. Но тут вообще стоит задать вопрос: зачем в принципе стоит требование атомарности обновлений ссылок? Атомарность нужна для того, чтобы избежать разрыва значений при одновременных обновлениях. Соответственно, если одновременных доступов нет, атомарность не требуется! Если бы в Java был механизм, который позволяет удостоверять, что доступ к значению уникален и остаётся уникальным в течение всего времени, пока значение остаётся достижимым (по крайней мере, для записи — многопоточное чтение безопасно и без атомарных операций), можно было бы использовать неатомарные операции для обновлений и избежать таким образом ограничений на размеры value-объектов. Можно считать это ещё одним примером к Fixing the next 10000 aliasing bugs, где инвариантом выступает целостность данных, и плюсом в копилку преимуществ отслеживания алиасинга для различных языков программирования.
🤔5
Forwarded from Лепра
Айтишник в 32 года нанял няню из детского сада, чтобы она следила за тем, как он работает, ест, вовремя ли ложится спать, выходит ли на улицу и не отлынивает ли от дел

Айтишники изобрели жену, поздравим 👍

🙈 Подписаться на Лепру 🙈
Please open Telegram to view this post
VIEW IN TELEGRAM
😁5710🤡5🔥3🆒2
Forwarded from disasm.me channel
Разбираясь с тяжеловесными пакетами, нашёл вот такой интересный пакет: quick-logger-js

Занятно видеть разницу в весе релизов:
1.0.5 — 565 KB
1.0.6 — 40.7 KB
1.0.7 — 3.29 GB 👀
1.0.8 — 55.6 KB
1.0.9 — 55.6 KB

Что произошло? В релиз попал файл stdout.txt с результатами бенчмарка для библиотеки. Релиз не удалён. Много думал 😺

#npm
@disasm_me_ch
Please open Telegram to view this post
VIEW IN TELEGRAM
🤣43😁31🔥4🥰3👏2🐳1
Вышла новая Lua - https://www.opennet.ru/opennews/art.shtml?num=64476

https://github.com/luarocks/luarocks/issues/1215 - а вот тикет про MIMT в пакетнике для Lua, всем пофиг. Похоже, они так 11 лет назад починили битый сертификат у репы - https://github.com/luarocks/luarocks/issues/286. К слову, сертификат всё ещё битый

А вот, например, меня спрашивают, почему я написал свой пакетник на python, а не на lua, я даже растерялся с ответом - https://github.com/stal-ix/ix/issues/803
😁13🔥4🤡3🐳1
https://www.phoronix.com/news/Meta-SCX-LAVD-Steam-Deck-Server

"An interesting anecdote from this month's Linux Plumbers Conference in Tokyo is that Meta (Facebook) is using the Linux scheduler originally designed for the needs of Valve's Steam Deck... On Meta Servers. Meta has found that the scheduler can actually adapt and work very well on the hyperscaler's large servers"

TL;DR - опять Миша не разобрался.

https://lpc.events/event/19/contributions/2099/attachments/1875/4020/lpc-2025-lavd-meta.pdf

Не "Meta использует тот же шедулер, что работает на Steam Deck", а "Meta взяли фреймворк шедулеров на ebpf, и творчески запилили свой вариант", #sched_ext #ebpf
😁16🔥94🐳2🆒1
Forwarded from Мост на Жепи (Валерия Бр.)
😁46🗿74😭2💘1
commit -m "better"
Искал тут в инторнетах ответ на вопрос "а как напечатать содержимое thread local переменной в статически слинкованной программе в gdb" (ответ, кстати, совершенно нетривиальный, но про это в другой раз)
Пару лет назад писал, что в gdb нельзя печатать thread local переменные, с musl и/или статической сборкой - https://xn--r1a.website/itpgchannel/1420.

И, ура, это починили!

https://www.opennet.ru/opennews/art.shtml?num=64463

"На платформе Linux реализована встроенная возможность доступа к локальным переменным потоков (Thread-Local Storage, TLS), используемая при отсутствии библиотеки libthread_db. Возможность доступна для архитектур x86_64, aarch64, ppc64, s390x и riscv при сборке с GLIBC или MUSL"

На КДПВ видно, что это реально работает!

(бонусом на КДПВ можно увидеть эмодзи в gdb, сука, глаза бы мои не видели это непотребство)
😁25🔥15👍5❤‍🔥3🆒21
Forwarded from Блог*
#prog #article

Advent of code optimizations — сборник декабрьских статей, по одной в день (в обратном хронологическом порядке), демонстрирующих на отдельных небольших примерах различные оптимизации компиляторов. Написано Мэттом Годболтом (да-да, тот самый, который godbolt.org).
👍26🔥63🆒1
https://www.opennet.ru/opennews/art.shtml?num=64485

"Исследователи из компании CodeRabbit проанализировали 470 pull-запросов (350 - созданные AI, 150 - написанные вручную) в открытых проектах на GitHub и пришли к выводу, что в изменениях, сгенерированных AI-ассистентами, присутствует в 1.7 раза больше значительных дефектов и в 1.4 раза больше критических проблем, чем во вручную написанном коде. В среднем в сгенерированных через AI pull-запросах присутствовало 10.83 проблем, в то время как в созданных вручную изменениях данный показатель составил 6.45.

При рассмотрении отдельных категорий проблем, в созданном AI коде было в 1.75 раз больше логических ошибок, в 1.64 раза больше проблем с качеством и сопровождаемостью кода, в 1.56 больше проблем с безопасностью и в 1.41 раз больше проблем с производительностью. Дополнительно отмечается, что в генерируемом через AI коде в 1.88 раз выше вероятность некорректной обработки паролей, в 1.91 раз - небезопасного предоставления доступа к объектам, 2.74 раза - межсайтового скриптинга (XSS) и в 1.82 раза - небезопасной десериализации данных. При этом в написанном людьми коде в 1.76 раз больше орфографических ошибок и в 1.32 раза больше ошибок, связанных с тестированием"
👍13🤡5🔥31🆒1
Будни #bootstrap. #gold

Закончил прямо большой рефакторинг части своей магии для статлинковки.

TL;DR - у меня есть враппер над линкером, который делает много вещей под капотом, например:

* когда сборка просит слинковать .so, он строит "теневой" .a, соответствующей этой .so, и дальше заменяет линковку с этой .so на линковку с .a

* создает регистраторы для функций-"конструкторов" (это специально помеченные функции, которые вызываются при инициализации .so, и полностью игнорируются линковкой с .a файлом)

И так далее.

Довольно часто требуется какая-то кастомная история, которая требует модификации этой магии. Не знаю, для примера - при линковке glib приложений нужно дернуть все *_get_resources() перед запуском main (не спрашивайте).

Я, когда мне нужно было что-то такое, не заморачивался, просто копировал папочку с магией в новое место, вносил правки, и использовал по месту. Дорабатывать общий код тут не вариант, потому что в разных окружениях нужна разная "магия".

Понятное дело, изменения в основной враппер переставали попадать в эти копии.

В итоге, сделал так - есть основной враппер, который делает базовые вещи, а после этого вызывает маленькие плагинчики, которые реализуют кастомную логику. Базово они общаются через jsonline - на вход плагину весь command line линкера, плагин его читает, делает свою частную "магию", и возвращает назад полный новый command line. Например, плагин может удалить или добавить аргументы, добавить дополнительные (и даже сгенеренные на лету!) .o файлы.

Вот драйвер - https://github.com/pg83/ix/blob/main/pkgs/bld/wrap/cc/exe/exelink.py

Вот цикл, который вызывает все зареганные плагины - https://github.com/pg83/ix/blob/main/pkgs/bld/wrap/cc/exe/exelink.py#L19-L28

Кстати, регистрация плагина выглядит довольно всрато необычно - это аргумент в LDFLAGS, имеющий вид -L/PLUGIN:/path/to/plugin/exe. Пример регистрации - https://github.com/pg83/ix/blob/main/pkgs/bld/wrap/cc/plugins/dedup/ix.sh#L11-L13.

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

-L - самый надежный способ передать через вызов компилятора в linker wrapper какую-то информацию, такие дела.

Вот пример элементарного плагина - https://github.com/pg83/ix/blob/main/pkgs/bld/wrap/cc/plugins/dedup/dedup.py#L6-L19. Он читает команду линковки из stdin (через jsonline протокол), модифицирует команду, и пишет результат в stdout, через jsonline. Делает он весьма тривиальную вещь - отфильтровывает из команды дубликаты .o файлов. Есть странные программы, которые передают в линкер дубликаты, и это приводит к ошибкам линковки, из-за дублирующихся символов. Теперь я в таких программах просто делаю зависимость на этот плагин, и случается "магия".

Есть и более сложные плагины. Вот, например, плагин, который реализует магию для вызова *_get_resource() - https://github.com/pg83/ix/blob/main/pkgs/bld/wrap/cc/plugins/gnome/gnome.py

В итоге, я так отрефакторил все копии linker wrapper script, стало хорошо. Вместо кучи копипасты - набор composable кубиков.

Стоит отметить, что такой рефакторинг я изначально придумал не для #IX, а на моей day job. В большой монорепе для линковки странных внешних библиотек и не так приходится приседать, дизайн я целиком стянул оттуда.
👍22🤯12🔥73🙈2💊1
commit -m "better"
после этого вызывает маленькие плагинчики
Мне тут в комментариях пеняют, что я борюсь с динлинковкой, но сам использую плагины.

Коллеги, максимально четко хочу прояснить, что борюсь я исключительно с динамически слинкованным нативным кодом, в виде .so/.dylib.

Причины этого я хорошо изложил в https://xn--r1a.website/itpgchannel/2939. Возьмите, пройдитесь по пунктам, как проблемы динлинковки соотносятся с загрузкой отдельных программ, и общением с ними по RPC. Спойлер - почти никак.

Программы надо как-то уметь расширять #plugins, и всякого рода сайдкары - отличный способ делать это.

Сайдкары - лучший способ, .so/.dylib - самый отвратный, посреди есть целый спектр возможностей, со своими плюсами и минусами:

* classloader в Java - сильно лучше, чем загрузка .so, потому что загрузчик проверяет огромное число инвариантов про загружаемый байткод, в том числе, совместимость типов и сигнатур методов. Но, все равно, это исполнение стороннего кода в своем адресном пространстве.

* загрузка .py файлов в виде модулей в основную программу. Опять, есть понятные плюсы перед .so/.dylib, и понятные же минусы, по сравнению с сайдкаром.

* всякие песочницы по типу wasm - второй удачный способ, после sidecar. Лучше, чем тот же classloader, потому что ты явно указываешь, к каким ресурсам будет иметь доступ плагин.
👍13🤡8❤‍🔥4🔥1
Между тем, просрочился серт у https://releases.bazel.build, и у людей встали релизные процессы - https://github.com/bazelbuild/bazel/issues/28101

Такое ощущение, что люди ничему не учатся - как можно в своих релизных процессах делать зависимость на внешний сетевой ресурс?
😁25👍6🆒2🔥1
https://pikabu.ru/story/bmw_patentuyut_novyiy_vid_boltov__a_u_nas_dlya_nikh_uzhe_est_vstrechnoe_predlozhenie_foto_13539183

"BMW патентуют болты с головкой в виде своего логотипа, которые смогут откручивать только в официальных сервисах. Вот так будет выглядеть этот шедевр инженерной мысли:"
🤡28😁9💊7🔥2🆒1