On Fri, 20 Nov 2009, Tamas TEVESZ wrote: Hi,
> > ../../../dlmalloc.c: In function 'void* dlmalloc(size_t)': > > ../../../dlmalloc.c:4107: warning: dereferencing pointer 'b' does break > strict-aliasing rules > there is an updated dlmalloc available from > ftp://gee.cs.oswego.edu/pub/misc/ (2.8.4 as opposed to the in-tree > 2.8.3, with a good 3.5yrs between them). my quick build tests show > that neither watcom nor mingw (4.2.1 here) like it as-is, but to my > untrained eye they don't look too difficult (from a cursory look it > looks like they have something to do with mmap, to which end the > in-tree version has some local changes). > maybe przemek would want to take a peek whether updating to the newer > upstream is of any benefit to hvm. I haven't time too look at this whole code so I cannot say what exactly is fixed by version 2.8.4 in comparison to 2.8.3. 2.8.4 is used with nedmalloc designed to improve performance in MT programs but I added to Harbour exactly the same functionality using pure 2.8.3 code (it's enabled by HB_FM_DLMT_ALLOC macro). Anyhow the above problem is exactly the same in both versions and the warning messages are perfectly valid. This code really breaks stric-aliasing rules to make a trick with lists of small memory chunks: struct malloc_chunk { size_t prev_foot; /* Size of previous chunk (if free). */ size_t head; /* Size and inuse bits. */ struct malloc_chunk* fd; /* double links -- used only if free. */ struct malloc_chunk* bk; }; [...] struct malloc_state { [...] mchunkptr smallbins[(NSMALLBINS+1)*2]; [...] } [...] #define smallbin_at(M, i) ((sbinptr)((char*)&((M)->smallbins[(i)<<1]))) ^^^^^^^^^^^^^^^^^ As you can see it's a trick to safe few bytes in allocated memory and chunks are overlapped. It works because effectively only fk and bk is used but it really confuse compilers which tries to optimize code assuming that any two different structures cannot use common memory region. Such situation is legal only for structures which are aliases of the same memory area. In fact it's a bug for modern C compiler which in some cases can cause that wrong code is generated. The clean solution is very simple. It's enough to remove above hack and declare smallbins as: mchunk smallbins[NSMALLBINS]; and smallbin_at(M, i) as: #define smallbin_at(M, i) (&((M)->smallbins[(i)])) In such varsion to code is clean without any hacks like above but for each mstate we need few additional bytes which will not be used, it's exactly 31 * 2 * sizeof( void* ) per mstate what gives 248 byte @ 32bit machines and 496 @ 64bit machines. In ST mode we are using only one mstate and in MT mode if Harbour is compiled with HB_FM_DLMT_ALLOC we can use one mspace per thread. In all cases it's rather small peace of memory which can be ignored so if you want then I can commit such modification. Probably it's also possible to make some tricks with casting which may also hide the problem (at least warnings). Anyhow in this case we have real structure overlapping so there is a risk that in some cases wrong code will be generated though silently without any warnings. best regards, Przemek _______________________________________________ Harbour mailing list (attachment size limit: 40KB) Harbour@harbour-project.org http://lists.harbour-project.org/mailman/listinfo/harbour