From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,74b55538385b7366 X-Google-Attributes: gid103376,public From: "Vladimir Olensky" Subject: Re: Which is right here - GNAT or OA ? Date: 1999/06/05 Message-ID: <928529202.956.79@news.remarQ.com> X-Deja-AN: 485805469 References: <928083159.436.79@news.remarQ.com> <928174549.336.98@news.remarQ.com> <7iuqkc$ln6$1@nnrp1.deja.com> X-MimeOLE: Produced By Microsoft MimeOLE V4.72.3110.3 X-Complaints-To: newsabuse@remarQ.com X-Trace: 928529202.956.79 K3TLTKYJOA5C9C7F8C qube-01.us-ca.remarq.com Organization: Posted via RemarQ Communities, Inc. NNTP-Posting-Date: Fri, 04 Jun 1999 20:46:42 GMT Newsgroups: comp.lang.ada Date: 1999-06-05T00:00:00+00:00 List-Id: Robert Dewar wrote in message <7iuqkc$ln6$1@nnrp1.deja.com>... >> The cost of this is one additional hidden field in the type >> representation which is set to needed value during object >> creation. > >Yes, and that cost is much too high, for example, if you have >a simple linked list type, you could be talking about adding >a storage overhead of 20-25%. I fully agree about additional cost and it may be even higher. But for types which size is more than 100 bytes the cost will be less than 4%. So if compiler could provide such runtime supports for objects marked for example as TRACED (just contrary to Modula-3 UNTRACED to exclude selected objects from GB process) than it could reduce the list of situations when Ada program peforms erroneous execution. I do not think that this is bad. >Surely you must realize your method is completely obvious! The >fact that the RM makes this situation erroneous is an explicit >indication that the designers of the language have considered >your solution and rejected it as introducing excessive overhead. Of course I realize that it is very obvious. It is first_come_to_mind solution for user built types in situations when there is no compiler support for that and I agree that it is not very suitable to be built into compiler. Compiler implementation could be handled completely differently. Each program has several memory areas (at least three - CODE, DATA and STACK). Compiler can same create special record with the fields CODE_START, CODE_END, STACK_START, STACK_END, PROGRAM_STATIC_DATA1_START, PROGRAM_STATIC_DATA1_END, PROGRAM_STATIC_DATA2_START, PROGRAM_STATIC_DATA2_END etc. Compiler and linker have all the information to be able to do this. When Free(X) is invoked then RTS could do something like this (in reality it may be much more complex): If (X_referenced_ object_Address NOT in CODE_ADDRESS_RANGE) and then (X_referenced_ object_Address NOT in STACK_ADDRES_RANGE) and then (X_referenced_ object_Address NOT in STATIC_DATA_ADDRESS_RANGE) and then (all other necessary checks) then Deallocate_Referenced_Object; -- or raise name_exception here to be close to RM X:=null; else X:=null; end; Such solution have very little overhead and it is not very difficult to be implemented. Such thing could be turned on/off by compiler pragma in order not to introduce anything in language definition. Doing so it is possible reduce the number of situation when Ada program can perform erroneous execution (with unpredictable effect). Again there is nothing new in this. Similar technique was used earlier in assembler programming for many purposes. (e.g. old DOS TSR programs used to calculate it's code size (CODE_END-CODE_START) to allocate themselves into computer memory) >The design is very sensitive to avoiding unnecessary storage >use. For example, the confusing difference between: > > A : aliased constant String (1 .. 80) := " 80 chars ..."; > A : aliased constant String := " 80 chars ..."; > >is solely to save the 8 bytes that would otherwise be required >for the bounds in the first case. This is indeed very interesting example. I think it ( and a bit of assembler code) could be placed in AdaPower in section named something like "Ada Tips and Tricks". ----------------------------------------------------------- procedure Ada_Rts is a : aliased constant String (1 .. 10) := "1234567890"; b : aliased constant String := "1234567890"; begin null; end Ada_Rts; ---------------------------------------------------------- gcc2_compiled.: ___gnu_compiled_ada: ..text LC0: ..ascii "1234567890\0" ..data _a.0: ..ascii "1234567890" ..text ..align 4 _b.1: ..long 1 ..long 10 ..ascii "1234567890" ..space 2 ..align 4 ..globl __ada_ada_rts __ada_ada_rts: pushl %ebp movl %esp,%ebp movl %ebp,%esp popl %ebp ret --------------------------------------------------- Such optimization is extremely important for embedded applications. In practice there exist general use applications running on top of different OSs. For them small overhead does not make much difference. Executable size for the above example with GNAT 3.11p for Windows NT is 110 kb. So adding to it some amount of code won't make any difference. Another thing that is worth to the importance of how compiler and linker work together in order to provide minimum executable size by cutting off unused code. For example Windows demo Keylook that was built using GNAT with -O3 has size of 378 Kbytes. And this was using only thin Win32 bindings. MS VC98 simple Win32 application with menus ,dialogs (direct calls to Win APIs - without MFC) has size of only 28 kb. Building simple application using Claw & GNAT results in executable size above 1.5Mb. Simple Win32 application that uses MFC (MS OOP Win32 libraries) has size of 252 kb when MFC libraries are statically linked to the executable. When MFC is used as shared DLL the exe size is 28 kb. This comparison shows where one should be talking about size overhead. It seems that GCC linker links everything contained in packages WITHed to main program. This is problem of the compiler-linker cooperation in producing smallest possible code. I understand that GNAT here has more difficult situation with GCC linker than other compiler vendors with their own linkers. Please take me right. I am not complaining about GNAT. I just trying to show that when we are talking about overhead and cost of additional memory usage to perform some system tasks we should have broader view on things. One thing is when we are talking about embedded systems where Ada is running sometimes on a bare hardware or it is using small size RTS tailored to particular requirements . When we are talking about general purpose Win32 app ( or Unix app maybe) that uses a lot of standard libraries then situation is different. Of course I know about Gnatelim and I played with it some time ago. I found it not very convenient for me. I tried it with test application that uses Claw . It can take several iterations and results in hour or more of waste time to obtain some small reduction of file size. STRIP in GNAT3.10 was much more convenient. I think that this work should be performed by compiler-linker tandem. Please do not tell me that I am complaining ! This is just my personal considerations that may be different from other's. That was not me who started talking about memory overhead. -------------------------------------------------------------- > Share what you know. Learn what you don't. I like this phrase and I completely agree with it. It is very constructive. It could be used as motto for c.l.a. Best regards, Vladimir Olensky