пятница, марта 11, 2016

Delphi ARC такой ARC...

Проверил на Андроиде. Delphi 10 Seattle Update 1.

Procedure Run;
Var

 Proc : Procedure Of Object;

Begin

 TObj.Create('1');              // will be destroyed
 TObj.Create('2').Test;         // will be never destroyed
 Proc := TObj.Create('3').Test; // will be never destroyed

End; 


А будущий компилятор для линукса обещает быть ARC enabled по дефолту...
[RSP-13934]

7 комментариев:

Arioch, the комментирует...

Ну да, и не должны - как бы "время жизни переменных".
ARC is ARC.

Для RIAA есть .DisposeOf - аналог iDisposable, деактивация объекта без уничтожения.

При работе с каким-нибудь MS Office через COM такая же фигня.
Или явно делай Proc := nil;

Kazantsev Alexey комментирует...

С чего это не должны? Просто созданный объект удаляется, а если у него метод позвать то не должен? Странная логика. К тому же Proc объект не держит, у неё на него слабая ссылка. А переменные, кстати, есть, но они объявляются компилятором неявно. Всё ровно как с интерфейсами.

Arioch, the комментирует...

Pardon, не заметил, что это процедура. Показалось консольная пpограмма, test case.

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

Но вообще надо в асме смотреть, как финализируется невидимая переменная под объект. Возможно у неё отрицательный refcount, как у константы.

...и меня ещё сприашивали, почему я остаюсь на xe2 :-)
Там последним апдейтом поломали только строковые константы в BPL и работу с MS Office :-)

Kazantsev Alexey комментирует...

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

Это ничего не меняет, а по ссылке на баг-репорт есть полный код ;)

>Но вообще надо в асме смотреть, как финализируется невидимая переменная под объект

Для первого объекта компилятор вызывает финализатор System.InstClear, для второго и третьего вызовы финализатора отсутствуют. Однако, переменную Proc он финализировать не забыл :)

А с XE2, кстати, тоже приколов хватает. Особенно доставляет inline и 64-битный компилятор, который в некоторых случаях генерирует нерабочий код. Хорошо, что случаи крайне редкие.

Arioch, the комментирует...

Есть, наверное. Пароль от Джиры дашь? :-D
Ты же не просто так пост писал, а не просто ссылку на Джиру.


...а невидимую переменную из второй строки ?
Если не забыл (мог и забыть) для интерфейсов в этом случае счетчики ссылок дергаются и скрытая переменная создается.

Хватает, инлайн там бешенный, да, и исключения в win64.
Но - они УЖЕ известны. И новые не появляются :-D

Кстати, ты те самые тесты по эффективности кодогенератора работы со строками не прогонял на более новых win32 ?

Kazantsev Alexey комментирует...

>Есть, наверное. Пароль от Джиры дашь?
Если учётка в BDN/EDN есть, то проблем быть не должно ;) ОК. В следующий раз буду весь код постить.

>...а невидимую переменную из второй строки ?
Не финалит он ничего, кроме первой переменной, ну и Proc ещё.

>для интерфейсов в этом случае счетчики ссылок дергаются и скрытая переменная создается
Да, тут всё то же самое... должно быть :)

Тесты прогонял. Код тестов был подправлен, чтобы на компиляторах с проблемным inline небыло просадок. На D10U1 производительность ниже чем на XE2, примерно, на 10%. А вот на NEXTGEN есть какие-то более серьезные косяки (причём в D10U1 стало значительно хуже, чем было в XE7 и XE8), но в чём именно там дело я разбираться не стал т.к. отладка под ведроид это боль. Дождусь линуксового NEXTGEN, там посмотрю детальнее :)

Kazantsev Alexey комментирует...

>Дождусь линуксового NEXTGEN, там посмотрю детальнее :)
Посмотрел причину тормозов на линуксовом NEXTGEN. Описание здесь: https://quality.embarcadero.com/browse/RSP-17724 Там во вложении есть наглядный пример того, как новый компилятор раздувает код. А в этом комментарии есть код другого компилятора для сравнения.