From: Howard T. <how...@di...> - 2007-08-02 23:14:39
|
Hi Eric, On Thursday 02 August 2007 19:53, you wrote: > Hi Howard, > > Howard Thomson wrote: > > I am continuing to work on my project based on gobo-eiffel, named EDP, > > the Eiffel Developer's Project on Sourceforge, although I haven't been > > keeping the SF SVN repository up-to-date with my work. > > > > In preparation for adding a stack trace, I have modified my > > ET_C_GENERATOR to be able to allocate stack locals and Result within a > > locally declared C struct, with the intention of adding, within each > > routine, a 'once' section of code that generates an instance of TYPE (or > > similar), so that capturing a stack trace captures a list of objects > > cloned from the stack frames and also captures the detail to enable > > Eiffel code to examine it. > > As I already mentioned with Wolfgang, I wonder whether we should > have a class ET_DEBUG_C_GENERATOR which inherits from ET_C_GENERATOR. > Or have something like that: > > ET_C_GENERATOR* > ^ ^ > / \ > ET_FINALIZE_C_GENERATOR ET_WORKBENCH_C_GENERATOR > > The code for stack trace and other debugging facilities could > then go to ET_WORKBENCH_C_GENERATOR (or ET_DEBUG_C_GENERATOR, > or whatever the name), and optimized code (what is in fact currently > implemented in ET_C_GENERATOR, even though more optimization > could/should be implemented) could go to ET_FINALIZE_C_GENERATOR. > And common code stays in ET_C_GENERATOR. We could also have other > descendants for multi-threaded application generation. There is certainly a need to separate out some aspects of the existing ET_C_GENERATOR. I want to be able to generate x86-ELF, x86-COFF, x86-64-ELF, and x86-64-COFF (shared) libraries directly instead of using gcc etc, and intend using or re-implementing in Eiffel the concepts in the LLVM code generation system at llvm.org. > > > The ability to do an exact inspection of the stack is also necessary for > > a precise Garbage Collector implementation, which I am also working on, > > on the basis that the GC should operate per-thread, and the primary > > (preferably only) means of communication between threads (other than > > probing for debugging) should be using some form of messaging implemented > > using deep_copy semantics. > > > > As my adapted code from the Slyboots GUI project uses user-expanded > > types, I have also adapted ET_C_GENERATOR to generate dynamic_types to > > avoid the 'C struct' inclusion ordering error that afflicted the version > > from which I started. > > This should be fixed in the current version in SourceForge. > > > I am interested in any existing and proposed introspection code in that > > it is needed for the debugging inspection of a suspended thread, and I > > will also need it for future Eiffel projects using database storage etc. > > I'm still dreaming to have an introspection mechanism that would > work with all compilers. > > BTW Wolfgang, I saw that you also approached the SmartEiffel 1.2 team > about your introspection library. Did you get any answer? > > > I have added some code to generate tracing information, currently only > > routine entry/exit with a stack depth counter, which I have needed to > > discover some (rare !) faults in the tools library, although I have not > > yet added the code to select the option from the command line, > > necessitating recompiling the compiler to change settings ..... ! > > > > On the performance front, I think that some level of routine inlining is > > fairly urgent; doing a C routine call to evaluate INTEGER_32.infix ">=, > > and similarly with ">", "|", "|<<", "|>>", INTEGER_8.to_integer_32 etc is > > somewhat performance limiting .... > > I'll see what I can do. > Do you have any benchmarks showing how bad performance is? Well it is most noticeable in my GUI code that has, re-coded in Eiffel, routines to process icon images etc for the screen dialogs, and it is very apparent that the original C++ code in the Fox library is MUCH faster. There is a quite noticeable delay in opening a dialog with several icons the first time, whereas for other aspects of Gobo compiled code the performance hit is more diffuse. The advantage of having the option to retain the existing 'C' routines for such simple operations is the ability to report assertion failures and to provide precise details about the feature where an assertion fails, but for production code having a (frozen) routine generated to execute a single instruction is less than ideal. > > I have modified the report_giaaa calls to be of the form: > > error_handler.report_giaaa ("__CLASS__", "__LINE__") > > where ET_C_GENERATOR substitutes the above strings for the appropriate > > strings for the textual location of the report_giaaa call. Although the > > code from where I tracked down a call to this routine has since been > > modified, I think the facility could be useful in future. > > This really looks like a hack. When I have internal errors, I run > gec in EiffelStudio and I put some break-points on that routine. > That way I get even more information from EiffelStudio's debugger > about the context of the internal error. It IS a hack (of course), only made necessary by the current lack of stack trace information and assertion checking. I intend that for 'debug' generated code, that there would be a separate GUI capable initial thread that would be capable of suspending, reacting to suspensions of, and probing other threads in the debug executable, with some needed wrapping of system calls to avoid unwanted interactions between the debug thread and the rest of the system. Whereas ES (I think) uses instruction modification to do breakpoints, I envisage using (slower) trace capable code and flag checks. First I need to move to two threads ..... > > > For the longer term, I am still interested in the problems and potential > > solutions needed to be able to dynamically add one or more class > > libraries into a running system, as one can do (carefully !) with Java. > > The added classes would have to have been compiled against the same > > kernel/base classes as the running system, or at least have no > > incompatibilities with them. > > > > Firstly, for performance reasons I want to be able to separately compile > > the classes that are changing rapidly from those that are unchanging when > > developing a project. > > > > And secondly I think that one of the aspects of Eiffel that is holding > > back some commercial acceptance is that to compile a system, or any > > variant of any system, one currently needs a complete set of source code > > to all classes in the system for the compiler to work. > > > > It should be possible for the IDE/compiler to dynamically load a > > pre-compiled library (.so or .dll), inspect it to retrieve the same > > required information that one would derive from compiling the sources, > > and generate new clients/descendants that can be based on the loaded > > library. > > > > I have been looking at ET_C_GENERATOR.print_polymorphic_xxx_calls and > > thinking about how one would dynamically allocate and register type_ids > > and data structures to lookup routine addresses and attribute offsets > > etc. > > One thing that should be considered when implementing dynamic > class loading is that gec currently relies on the dynamic > type set mechanism in order to determine which calls are polymorphic > or not, what are the possible types at run-time for a given entity, > etc. This is both convenient (because the dynamic type set mechanism > was implemented before the C code generation) and allows more > optimizations (less code needs to be compiled, reduce the number > of polymorphic calls). > > An alternative mechanism would need to be put in place in > order to take into account the fact that an entity can actually > have other types at run-time. Yes, absolutely. Either there would have to be some type-set analysis at dynamic-load time, or polymorphic calls would have to be more inclusive. > > > I went to a couple of workshops at the ECOOP '07 conference in Berlin at > > the weekend, and picked up some useful information and contacts relevant > > to this area of interest. > > > > In applications, I am working on a comparison program for Eiffel texts to > > compare classes, selectively excluding things like indexing clauses, > > comments, assertions etc, which I will also be integrating into the IDE. > > I started to work on a similar tool at work as well. > The way I do it is to have a canonical pretty printer that > does not display comments and other information I'm not > interested in for the diff, print features in alphabetical > order (each in its own feature clause with the clients > it is exported to), feature names in alphabetical order in > Redefine, Undefine, Create, ... clauses, etc. Then I can compare > (in a graphical diff tool) two versions of the same class > using their canonical pretty-printed versions. This is still > a work in progress, and I have nothing to show yet. Yes, re-ordering of features in texts is a difficulty that needs solutions. I want to be able to show the sources side-by-side with the differences highlighted on a symbol by symbol basis. > > > I am interested in working with others on what I am doing, and welcome > > feedback on ideas and from potential users of EDP, which is approaching > > (for me at any rate!) being useable as a substitute for my existing > > editing system (Code Crusader) and is already my only Eiffel compilation > > system in conjunction with the (modified) GEC command line equivalent. > > > > My immediate priorities are GC and threads, but the earlier I am able to > > cooperate with others in what is being designed and coded, the faster we > > will all achieve results. > > For the GC, last week I successfully plugged the Boehm GC: > > http://en.wikipedia.org/wiki/Boehm_GC > http://www.hpl.hp.com/personal/Hans_Boehm/gc/ > > to an application at work compiled with gec. Of course it is > not as optimal as a GC decicated to gec could be. But this is > encouraging. > > As for multi-threading, one thing that would need to be done > (if you haven't done that yet) is to determine in the C code > currently generated by gec what are the global variables, what > are the non-thread-safe function calls, etc. I know for sure > that the current implementation of once-functions is not > thread-safe. Agreed. Is there yet an agreed basis for the semantics of 'once' functions in a multi-threaded environment ? Where and how does one specifiy the variety of once semantics that applies to a given feature ? I used the Boehm-GC before when I was developing with SmartEiffel, and for a single threaded application it worked fine, at least more reliably than the SE GC. I feel the need for the code that I am working on to be lucid and complete, and the Boehm-GC doesn't meet my longer-term criteria. Regards, Howard -- "Only two things are infinite, the universe and human stupidity, and I'm not sure about the former." -- Albert Einstein |