![]() |
Delphi-Version: XE2
Assembler Routine - korrekt so?
Kurze Hintergrundinfo:
Ich in gerade dabei, die DSharp Multicast Events etwas zu überarbeiten. Momentan gibt es 3 verschiedene Methoden, ein Event aufzurufen (inline asm für Delphi 2010 und XE und jeweils pure pascal ab XE2 für 32-bit und 64-bit) Da die pure Pascal Versionen ziemlich viel Overhead (erst die aus der ObjAuto gelieferten Parameter im auf TValue umbasteln um sie dann an die Rtti.Invoke Methode zu übergeben) und Wartungsaufwand mit sich bringen, hab ich mich mal hingesetzt und hab 2 reine asm Routinen geschrieben. Da ich nicht gerade der Assembler Crack bin, wär es prima, wenn die, die sich damit etwas besser auskennen, mal drüber schauen könnten und mich auf Fehler und/oder Optimierungsmöglichkeiten hinweisen würden (speziell bei der 64bit Version, die ich mir nur mit Hilfe der Rtti Sourcen zusammen gefrickelt hab).
Delphi-Quellcode:
procedure InvokeMethod(const Method: TMethod; Parameters: PParameters; StackSize: Integer);
const PointerSize = SizeOf(Pointer); type TParameters = packed record {$IFDEF CPUX86} Registers: array[paEDX..paECX] of Cardinal; EAXRegister: Cardinal; ReturnAddress: Pointer; {$ENDIF CPUX86} Stack: array[0..1023] of Byte; end; {$IF Defined(CPUX86)} asm push ebp mov ebp,esp push eax // ebp-4 = Method push ebx mov ebx, edx // ebx = Parameters // if StackSize > 0 test ecx,ecx jz @@no_stack // stack address alignment add ecx,PointerSize-1 and ecx,not(PointerSize-1) and ecx,$ffff sub esp,ecx // put stack address as second parameter mov edx,esp // put params on stack as first parameter lea eax,[ebx].TParameters.Stack call Move @@no_stack: mov edx,[ebx].TParameters.Registers.dword[0] mov ecx,[ebx].TParameters.Registers.dword[4] mov ebx,[ebp-$04] mov eax,[ebx].TMethod.Data call [ebx].TMethod.Code pop ebx pop eax mov esp,ebp pop ebp end; {$ELSEIF Defined(CPUX64)} asm .params 60 mov [rbp+$200],Method mov [rbp+$208],Parameters test r8,r8 jz @@no_stack // put params on stack as first parameter lea rcx,[Parameters].TParameters.Stack // put stack address as second parameter mov rdx,rsp call Move mov rdx,[rbp+$208] @@no_stack: mov rcx,[rdx].TParameters.Stack.qword[0] mov r8,[rdx].TParameters.Stack.qword[16] mov r9,[rdx].TParameters.Stack.qword[24] movsd xmm0,[rdx].TParameters.Stack.qword[0] movsd xmm1,[rdx].TParameters.Stack.qword[8] movsd xmm2,[rdx].TParameters.Stack.qword[16] movsd xmm3,[rdx].TParameters.Stack.qword[24] mov rdx,[rdx].TParameters.Stack.qword[8] mov rax,[rbp+$200] lea rax,[rax] mov rcx,[rax].TMethod.Data call [rax].TMethod.Code end; {$IFEND} |
AW: Assembler Routine - korrekt so?
Ich würde versuchen einfach was Fertiges zu nutzen.
RTTI hat es schon fertige Invoke-Methoden ... man müsste sich nur zur Laufzeit (beim Erstellen des MulticastEvents) eine TRTTIMethod (oder so) manuell zusammenstellen oder aus der TypeInfo einer EventMethode erstellen und könnte Dieses dann verwenden. Beim Umstellen auf andere Zielplattformen würde Emba dann für dich den Rest mit anpassen. [edit] Der Nachteil wäre dann zwar, daß dieser Code dann nicht zu alten Delphis kompatibel ist, wo es die neue RTTI noch nicht gibt. Hätte es erst richtig/komplett durchlesen sollen Dann halt kein Pascal ._. |
AW: Assembler Routine - korrekt so?
Zitat:
Problem 1.: Ich darf erstmal tonnenweise Bugs in verschiedenen Delphi Versionen in der Rtti reporten und fixen Problem 2.: Für das dynamische Zusammenbauen einer TRttiMethod nur über die TypeInfo eines Events oder einer anonymen Methode ist noch mehr Fuckelei notwendig als für das da oben Problem 3.: Die Invoke Methoden sind inperformant |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:26 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz