|
From: Roger H. <rog...@mi...> - 2005-01-25 13:56:13
|
Thanks for all your feedback on this, and thanks for fixing the dump code. I had realised the memory would not be cleared and that if they existed, a whole hierarchy of void constructors could be called which could either clear their data or hopefully set it to a more useful value. It is the constructors I want to use, and I don't think there is any way of doing this without using this syntax. I think I had better read the latest information on "operator new", it seems to have become rather more complicated than when I first learnt C++. I am looking for a way to define an "operator new" which I can specify when I create my objects which can call Q3Memory_AllocateClear. For allocating the class info objects I am not worried about the overhead of clearing the memory. However, if we decide to use constructors for the objects themselves then clearing the memory before we initialise it does seem inefficient. Anyone had a chance to check the speed of the new version yet? We see up to 19% in some cases, though nothing at all in others. I have been running the old 'Sampler' tool on it as 'Shark' does not seem to work properly in my configuration. I find it is spending a lot of time checking that object are of the correct type so maybe I should concentrate on that. One possible optimisation would be to hold an array of 6 elements in the E3ClassInfo record. Six being the maximum depth of the built in class hierarchy. Then for example, a class such as Display Group, element zero would contain kQ3ObjectTypeRoot, element 1 would contains kQ3ObjectTypeShared, 2 = kQ3SharedTypeShape, 3 = kQ3ShapeTypeGroup, 4 = kQ3GroupTypeDisplay and 5 and 6 would be zero. There would also have to be something like an enum for each class giving its depth in the hierarchy. Following our example, there would be a kQ3GroupTypeDisplay_Depth which would be 4. Then where we current test again a constant class type such as kQ3GroupTypeDisplay we could instead call a macro , something like OBJECT_IS_CLASS ( theObject, kQ3GroupTypeDisplay ) which would expand to be ( (theObject)->IsClass ( kQ3GroupTypeDisplay , kQ3GroupTypeDisplay_Depth ) ) and OpaqueTQ3Object::IsClass would be an inline which would do this return theClass->typesArray [ depth ] == classType ; As in the inline, 'depth' would be a constant, this should optimise out as a simple test against a value at fixed offset in the class record. If it were not of the correct type, then either the entry would be the class type of another type, or zero if the object were of a type at a lower depth in the class hierarchy. Of course you will be thinking about user defined classes, but we never need to test against them as constants, the existing code would be used. Anyone see any holes in this proposal? Roger. On Monday, January 24, 2005, at 06:41 pm, James W. Walker wrote: > At 1:23 PM +0000 1/24/05, Roger Holmes wrote: > >> For my remaining 'slack' time I would like your opinions on the >> possible use of C++ memory >> allocation and construction facilities. On Macintosh I think that >> using statements like: >> >> E3ClassInfo* theInfo = new E3ClassInfo ; >> >> E3ClassInfo* theClass = (E3ClassInfo*) Q3Memory_AllocateClear ( >> sizeof ( E3ClassInfo ) ) ; >> >> are (except for the zeroing of the block of memory) equivalent as >> they both end up calling >> malloc to actually reserve the memory. Am I correct, and what is the >> situation on the other >> platforms? > > When compiled with Q3_MEMORY_DEBUG, E3Memory_AllocateClear uses a > block trailer to test for buffer overruns. Exactly what operator new > does on the Mac with CodeWarrior depends on whether we're talking CFM > or Mach-O, and what options were used to compile the runtime library. > The default on Mach-O is that operator new calls malloc. > > Also bear in mind that E3ClassInfo* theInfo = new E3ClassInfo ; would > throw an exception if the allocation fails, unless you write it as > E3ClassInfo* theInfo = new(std::nothrow) E3ClassInfo ; > -- > James W. Walker On Monday, January 24, 2005, at 07:40 pm, Joseph J. Strout wrote: > At 11:26 AM -0800 1/24/05, James W. Walker wrote: > >> When compiled with Q3_MEMORY_DEBUG, E3Memory_AllocateClear uses a >> block trailer to test for buffer overruns. Exactly what operator new >> does on the Mac with CodeWarrior depends on whether we're talking CFM >> or Mach-O, and what options were used to compile the runtime library. >> The default on Mach-O is that operator new calls malloc. > > It also depends on whether someone has added a custom new operator in > the appropriate namespace -- something you'd think we have control > over, but also something very easy to miss when reading the code. > >> Also bear in mind that E3ClassInfo* theInfo = new E3ClassInfo ; would >> throw an exception if the allocation fails, unless you write it as >> E3ClassInfo* theInfo = new(std::nothrow) E3ClassInfo ; > > Yes, though this also depends on compiler options. > > For all those reasons, I think it's better to call > Q3Memory_AllocateClear. > > Best, > - Joe On Monday, January 24, 2005, at 08:13 pm, Lane Roathe wrote: > on Mon, Jan 24, 2005 Roger Holmes may have said: > >> For my remaining 'slack' time I would like your opinions on the >> possible use of C++ memory >> allocation and construction facilities. On Macintosh I think that >> using >> statements like: >> >> E3ClassInfo* theInfo = new E3ClassInfo ; >> >> E3ClassInfo* theClass = (E3ClassInfo*) Q3Memory_AllocateClear ( sizeof >> ( E3ClassInfo ) ) ; >> >> are (except for the zeroing of the block of memory) equivalent as they >> both end up calling >> malloc to actually reserve the memory. Am I correct, and what is the >> situation on the other >> platforms? > > Actually, after a bit of thought I do not believe these are the same: > > new - get a chunk of memory via some unknown allocator. > > AllocateClear - get a chunk of memory via a known allocator, and CLEAR > it > (ie, memset(p,0,size) of similar), plus whatever mem debugging may be > going on. > > > > Lane Roathe |