Показаны сообщения с ярлыком XE3. Показать все сообщения
Показаны сообщения с ярлыком XE3. Показать все сообщения

понедельник, 3 июня 2013 г.

HashLittle не работает БЕЗ OverflowChecks Off

function HashLittle(const Data; Len, InitVal: Integer): Integer;
var
  pb: PByte;
  pd: PCardinal absolute pb;
  a, b, c: Cardinal;
label
  case_1, case_2, case_3, case_4, case_5, case_6,
  case_7, case_8, case_9, case_10, case_11, case_12;
begin
  a := Cardinal($DEADBEEF) + Cardinal(Len shl 2) + Cardinal(InitVal);
  b := a;
  c := a;

  pb := @Data;

  // 4-byte aligned data
  if (Cardinal(pb) and 3) = 0 then
  begin
    while Len > 12 do
    begin
      Inc(a, pd[0]);
      Inc(b, pd[1]);
      Inc(c, pd[2]);
      Mix(a, b, c);
      Dec(Len, 12);
      Inc(pd, 3);
    end;

    case Len of
      0: Exit(Integer(c));
      1: Inc(a, pd[0] and $FF);
      2: Inc(a, pd[0] and $FFFF);
      3: Inc(a, pd[0] and $FFFFFF);
      4: Inc(a, pd[0]);
      5:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1] and $FF);
      end;
      6:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1] and $FFFF);
      end;
      7:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1] and $FFFFFF);
      end;
      8:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1]);
      end;
      9:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1]);
        Inc(c, pd[2] and $FF);
      end;
      10:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1]);
        Inc(c, pd[2] and $FFFF);
      end;
      11:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1]);
        Inc(c, pd[2] and $FFFFFF);
      end;
      12:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1]);
        Inc(c, pd[2]);
      end;
    end;
  end
  else
  begin
    // Ignoring rare case of 2-byte aligned data. This handles all other cases.
    while Len > 12 do
    begin
      Inc(a, pb[0] + pb[1] shl 8 + pb[2] shl 16 + pb[3] shl 24);
      Inc(b, pb[4] + pb[5] shl 8 + pb[6] shl 16 + pb[7] shl 24);
      Inc(c, pb[8] + pb[9] shl 8 + pb[10] shl 16 + pb[11] shl 24);
      Mix(a, b, c);
      Dec(Len, 12);
      Inc(pb, 12);
    end;

    case Len of
      0: Exit(c);
      1: goto case_1;
      2: goto case_2;
      3: goto case_3;
      4: goto case_4;
      5: goto case_5;
      6: goto case_6;
      7: goto case_7;
      8: goto case_8;
      9: goto case_9;
      10: goto case_10;
      11: goto case_11;
      12: goto case_12;
    end;

case_12:
    Inc(c, pb[11] shl 24);
case_11:
    Inc(c, pb[10] shl 16);
case_10:
    Inc(c, pb[9] shl 8);
case_9:
    Inc(c, pb[8]);
case_8:
    Inc(b, pb[7] shl 24);
case_7:
    Inc(b, pb[6] shl 16);
case_6:
    Inc(b, pb[5] shl 8);
case_5:
    Inc(b, pb[4]);
case_4:
    Inc(a, pb[3] shl 24);
case_3:
    Inc(a, pb[2] shl 16);
case_2:
    Inc(a, pb[1] shl 8);
case_1:
    Inc(a, pb[0]);
  end;

  Final(a, b, c); <<----- падает тут
  Result := Integer(c);
end;

Вообще конечно комильфо было бы, если бы авторы предварили функцию директивой OverflowChecks Off.

пятница, 31 мая 2013 г.

Где-то за неделю перепортировал все проекты с XE3 на XE4

Где-то за неделю перепортировал все проекты с XE3 на XE4.

Они - СОБИРАЮТСЯ. Но пока ничего - НЕ РАБОТАЕТ из-за -http://18delphi.blogspot.com/2013/05/xe4.html

Жду теперь когда Resolved превратится в Closed.

P.S. я кстати нашёл ТРИ workaround'а ошибки. Попробую завтра всё же ЗАПУСТИТЬ простейшие тесты под XE4. РУКИ ЧЕШУТСЯ на это посмотреть.

четверг, 16 мая 2013 г.

На что надо обратить внимание при портировании с Delphi 7 на Delphi XE3


1. String = WideString
PChar = PWideChar
Char = WideChar
– это - более чем весело (особенно PChar <> PByte, ведь ни для кого не секрет, что многие использовали PChar Не как "указатель на символ", а как "указатель на byte к которому применима адресная арифметика". Fail тут - обеспечен).
Я "тупо" взял и поменял всё это на AnsiString, PAnsiChar, AnsiChar. Поиском/заменой. А потом - поменял обратно - там где не собралось - в стандартных классах. Там где override. Типа KeyDown. Ну и естественно поменял - шаблоны кодогенерации.
2. FormatSettings - теперь запись с полями и методами. ShortDateFormat теперь равно FormatSettings.ShortDateFormat etc.
3. менеджер памяти - другой. Со всеми вытекающими. Кстати при ПРАВИЛЬНОМ подходе - позволяет найти много ошибок в старом коде "не сходя с места".
4. канва почему-то несколько по-иному себя ведёт
5. NativeInt etc. И их несовместимость с Integer и Cardinal. ДАЖЕ в 32 битах.
6. Часть функций API стали принимать/возвращать беззнаковые значения, вместо знаковых. И наоборот.
7. Записи по умолчанию на 8 байт выравниваются. Если вы использовали, что-то типа THackControl или записи на диск - тут надо быть внимательным.
8. Forms -> VCL.Forms etc.

Ну и ссылка от Embarcadero. Не совсем в тему, но полезная:
http://docwiki.embarcadero.com/RADStudio/XE4/en/Converting_32-bit_Delphi_Applications_to_64-bit_Windows

среда, 15 мая 2013 г.

Предварительная статистика по портированию на Delphi XE3

Предварительная статистика и итоги по портированию на Delphi XE3 с Delphi 7:

1. Сделано более 5000 коммитов.
2. Найдено два десятка ошибок в СТАРОМ коде.
3. Написано три десятка новых тестов.
4. Выяснено, что менеджер памяти в XE3 гораздо лучше, чем в Delphi 7.
5. Десяток классов нарисовано на модели.
6. Поправлен десяток шаблонов кодогенерации с учётом специфики XE3.
7. Вчерне заработано 8 проектов собранных под XE3. При этом их версии собранные под Delphi 7 (из ТЕХ ЖЕ САМЫХ исходников) - НЕ РАЗЛОМАЛИСЬ.
8. Порядка 100 тестов из ~2000 ещё не проходят.
9. Поправлен десяток страниц документации.
10. Стало окончательно понятно - зачем нужны "атомарные" тесты.
11. Выяснено, что несколько ошибок VCL - так и не поправлено.
12. Выяснено как получать размер куска памяти распределённого новым менеджером памяти (ну это хоккей конечно).
13. Выяснено, что "заглушки" (http://18delphi.blogspot.com/2013/03/blog-post_5929.html) взамен "анонимных функций" - продолжают работать.
14. Выяснено, что "Generic'и без Generic'ов" (http://18delphi.blogspot.com/2013/03/generic-generic.html) - продолжают работать.
15. Выяснено, что старая VGScene - прекрасно собирается и работает под XE3 И смешивается с контролами VCL.

Следующий этап - 64 бита. Подозреваю, что там уже без родных "анонимных функций" - уже не обойтись. Там ведь нету встроенного ассемблера.

Портирование на Delphi XE3 прошло не зря и в общем - удачно

Скоро приедет более десятка ключей на Delphi XE4. Так что - будем работать дальше.

суббота, 27 апреля 2013 г.

пятница, 26 апреля 2013 г.

Проблемы с докингом в VCL


destructor TControl.Destroy;
begin
  Application.ControlDestroyed(Self);
  if (FHostDockSite <> nil) 
      and not (csDestroying in FHostDockSite.ComponentState) // - это я добавил
  then
  begin
    FHostDockSite.Perform(CM_UNDOCKCLIENT, 0, Integer(Self));
    SetParent(nil);
    Dock(NullDockSite, BoundsRect);
    FHostDockSite := nil;
  end else
    SetParent(nil);
...
end;

Без этого падало на Delphi 7 и продолжает падать на Delphi XE3. Если просто сделать конструкцию из нескольких панелей и вдоченных форм. А потом попытаться одну из вдоченных форм убить. Честными средствами.

Это тоже был долгий разбор лет 10-ть назад. Примеры повторения - есть. Но рафинированный - пока не выделил.

Но опять же - никакого "хоккея" - там не было. Просто чистое использование VCL.

Проезд по памяти в VCL



procedure TControlCanvas.CreateHandle;
...
 
  if FControl = nil then
    inherited CreateHandle
  else
  begin
    // Creation of a window could trigger messages that require
    // the canvas to have a valid handle. Prevents creating two DCs.
    if (FDeviceContext = 0) and (FControl is TWinControl) then
      TWinControl(FControl).HandleNeeded;
    if FDeviceContext = 0 then
    begin
      with CanvasList.LockList do
      try
        if Count >= CanvasListCacheSize then FreeDeviceContext;
        FDeviceContext := FControl.GetDeviceContext(FWindowHandle);
        if (IndexOf(Self) < 0) then {V} // - это я добавил
         Add(Self);
      finally
        CanvasList.UnlockList;
      end;
    end;
    Handle := FDeviceContext;
    UpdateTextFlags;
  end;
...
end;


Без этого падает тут:


// Free the first available device context
procedure FreeDeviceContext;
var
  I: Integer;
begin
  with CanvasList.LockList do
  try
    for I := 0 to Count-1 do
      with TControlCanvas(Items[I]) do
        if TryLock then
        try
          FreeHandle; // - тут
          Exit;
        finally
          Unlock;
        end;
  finally
    CanvasList.UnlockList;
  end;
end;

Или тут:



procedure FreeDeviceContexts;
var
  I: Integer;
begin
  with CanvasList.LockList do
  try
    for I := Count-1 downto 0 do
      with TControlCanvas(Items[I]) do
        if TryLock then
        try
          FreeHandle; // - тут
        finally
          Unlock;
        end;
  finally
    CanvasList.UnlockList;
  end;
end;


Как повезёт.

Что в общем-то и понятно - одна канва может несколько раз попасть в CanvasList.

Сейчас попробую найти рафинированный сценарий повторения ошибки.

Поправил я эту ошибку 18 апреля 2002 года. 11-ть лет назад. Я тогда искал её ДВЕ НЕДЕЛИ. Выпуск даже затягивался. Весь мозг себе сломал. В Delphi XE3 - она до сих пор присутствует.

Вот в частности для этого и нужны автоматические тесты. Чтобы за повторяемостью таких непростых ошибок следить.

Сегодня эту ошибку под XE3 показали именно - автоматические тесты.

четверг, 25 апреля 2013 г.

САМЫЙ БОЛЬШОЙ проект сегодня взлетел под XE3, но там что-то падает

САМЫЙ БОЛЬШОЙ проект сегодня взлетел под XE3, но там что-то падает. В основном из-за хоккея. Отладим.

Самые БОЛЬШИЕ проблемы были из-за доступа к приватным полям, через объявление "зеркального" класса..

вторник, 23 апреля 2013 г.

Жду теперь ключ к XE4

Жду теперь ключ к XE4. Как только приедет - опробую на тех проектах, которые уже были портированы на XE3.

пятница, 19 апреля 2013 г.

Запустил сегодня БОЛЬШОЙ проект

Запустил сегодня БОЛЬШОЙ проект, который собрал вчера под Delphi XE3. Он заработал. Не падает. Выполняет основные свои функции.

Тесты проходят не все.

Но там ~15 млн. строк.

Будем работать дальше.

P.S. В связи со сменой менеджера памяти - нашли проезды по памяти. "Американский метод №3" :-)

четверг, 18 апреля 2013 г.

Сегодня собрал ещё одно приложение под Delphi XE3

Сегодня собрал ещё одно приложение под Delphi XE3. Внутренней автоматизации. Оно собралось. Но не заработало. Завтра попробую заставить его работать и прогнать тесты.

среда, 17 апреля 2013 г.

Сегодня заработал отдельностоящий редактор портированный с Delphi 7 на Delphi XE3

Сегодня заработал отдельностоящий редактор портированный с Delphi 7 на Delphi XE3.

В целом - работает. Полёт нормальный.

Не прошло несколько тестов.

Но очень специфических.

Для кода который писал не я. С наскока - разобраться - не удалось. Что-то там в бизне-логике. Или банально - неинициализированные переменные. Разберёмся. Либо я, либо автора привлеку. Что-то мне подсказывает, что я там "какую-то запятую забыл".

Короче - процесс идёт семимильными шагами.

Хочется следующим шагом приступить к 64 битам.

Там чувствую много интересного. Я уже у себя много где поправил *4 или shl 2.

Время покажет.

P.S. 10 миллионов строк кода кстати.

P.P.S. А не было бы тестов - можно было бы УЖЕ СЕГОДНЯ считать, что всё работает :-) Тесты вредны, да?

P.P.P.S Засим - я доволен. И собой и окружающими. И Embarcadero кстати - тоже.. :-) Я думал - будет хуже.. Бейте меня ногами... У меня конечно есть вопросы к Embarcadero.. Но она сделала свою работу не так уж плохо как пишут в форумах... Я ожидал - ГОРАЗДО худшего... Сторонних компонент у нас правда практически - нет. А уж без исходников - и подавно. Но в этом - наша сила.

P.P.P.P.S. А те кто мне не верит - попробуйте FreePascal и Lazarus. Хотя в целом разработка неплохая. Но я могу вам в красках рассказать, как я это на Мак ставил.... fink все дела.. ручная правка скриптов.. Мне как человеку далёкому от мира *nix - было конечно крайне интересно... И поставил в итоге.. Но - плюнул... И освоил xCode....

пятница, 12 апреля 2013 г.

Портировал весь свой "хоккей" с Delphi 7 на Delphi XE3

Прошло 95% тестов...

Осталась бизнес-логика и реальные "непонятки"...

Порт с Delphi 1 на Delphi 2 занял несколько месяцев...

С Delphi 2 на Delphi 6 - аналогично...

четверг, 11 апреля 2013 г.

Портирование с Delphi 7 на Delphi XE3 идёт со скрипом, но идёт

Ну а что ж вы хотели называется...

Несколько МИЛЛИОНОВ строк своего кода. Большие самописные компоненты и библиотеки.

Причём "банальная" бизнес-логика портируется - ЛЕГКО. Ну за исключением той где нет String и PChar и записи их на "внешние носители".

А вот с портированием "хоккея" - время от времени случаются непонятки.

Но тестов проходит всё больше и больше...

вторник, 9 апреля 2013 г.

Сегодня мне показалось, что я нашёл ошибку в менеджере памяти Delphi XE

Все симптомы говорили об этом.

Я даже выделил тест:


procedure TReallocMemTest.DoIt;
var
 l_Index : Integer;
 l_P : PAnsiChar;
 l_I : Integer;
 l_Size : Integer;
 l_OldSize : Integer;
begin
 for l_Index := 0 to 5000 do
 begin
  l_Size := 10;
  GetMem(l_P, l_Size);
  try
   while (l_Size <= 6144 * 2) do
   begin
    FillChar(l_P^, l_Size, Random($ff));
    l_OldSize := l_Size;
    l_I := PInteger(l_P + l_OldSize - SizeOf(Integer))^;
    Inc(l_Size, Random(20));
    ReallocMem(l_P, l_Size);
    Check(PInteger(l_P + l_OldSize - SizeOf(Integer))^ = l_I);
   end;//l_Size <= 6144
  finally
   FreeMem(l_P);
  end;//try..finally
 end;//for l_Index
end;//TReallocMemTest.DoIt
 
procedure TReallocMemTest.DoIt1;
const
 cMagicSize0 = 10;
 cMagicSize = 3120;
 cNewMagicSize = 6144;
var
 l_P : PAnsiChar;
 l_I : Integer;
begin
 GetMem(l_P, cMagicSize0);
 try
  FillChar(l_P^, cMagicSize0, 10);
  l_I := PInteger(l_P + cMagicSize0 - SizeOf(Integer))^;
  ReallocMem(l_P, cNewMagicSize);
  Check(PInteger(l_P + cMagicSize0 - SizeOf(Integer))^ = l_I);
 
  FillChar(l_P^, cMagicSize, 10);
  l_I := PInteger(l_P + cMagicSize - SizeOf(Integer))^;
  ReallocMem(l_P, cNewMagicSize);
  Check(PInteger(l_P + cMagicSize - SizeOf(Integer))^ = l_I);
 finally
  FreeMem(l_P);
 end;//try..finall
end;//TReallocMemTest.DoIt


И даже поделился с коллегами о своём "открытии". И даже написал в Embarcadero.

Но! Без предварительного вызова МОЕГО КОДА - этот тест - не падает.

Мячик на моей стороне.

Каким же я выглядел идиотом.

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

Как я уже писал - написанный и ОТЛАЖЕННЫЙ тест - надо не выкидывать, а включать в базу тестов. ЛЮБОЙ. За него "кровью и нервами уплочено".

Как говорится в сказках про Иванушку-дурачка - "не убивай меня - я тебе пригожусь".

Надеюсь, что итоги сегодняшнего дня помогут мне стать капельку мудрее.

P.S. а проблемы на самом деле были вот в этом "хоккее" - http://18delphi.blogspot.com/2013/04/getmem.html

Продолжаю борьбу с "хоккеем" в библиотеках при портировании на XE3

Думаю - это знак... ВЕСЬ код должен быть написан БЕЗ "хоккея"... А "хоккей" - только там где реально нужно.. Опционально включать.. Но не более того...

Ошибки молодости....

суббота, 6 апреля 2013 г.

Сегодня собрал БОЛЬШОЙ проект под XE3

Запускается. Даже кое-что - работает.

Но он - падает... Всему виной - "хоккей" с недокументированными фичами... Но я работаю над этим...

P.S. а потом я поехал к матушке - помогать готовить квартиру к ремонту.. Посему к активному кодированию я вернусь только в понедельник. Ну может быть "по заявкам трудящихся" - я успею за выходные закончить статью про минимальный подсчёт ссылок...

А пока - читайте про "хоккей":
http://18delphi.blogspot.com/2013/04/getmem.html
http://18delphi.blogspot.com/2013/04/delphi.html

Может быть вам и хоккей понравится.

четверг, 4 апреля 2013 г.

Менеджер памяти в XE3

Похоже - лучше, чем в Delphi 7.

Открутил собственное кеширование  объектов (ибо оно всё равно пока не работает в XE3 - не переваривают они копания в VMT).

Запустил performance-тесты. Они не показывают такой дикой деградации как в Delphi 7.

Молодцы! Правильной дорогой движутся.

Буду дальше проверять. Может быть опубликую конкретные цифры. Было/стало.

Может быть и собственный кеш объектов больше не понадобится.

P.S. Вот тут ещё - http://18delphi.blogspot.com/2013/07/xe4.html