# define GC_ASSERT(expr) /* empty */
#endif
+#ifndef GC_PREFETCH_FOR_WRITE
+# define GC_PREFETCH_FOR_WRITE(x) (void)0
+#endif
+
/* Store a pointer to a list of newly allocated objects of kind k and */
/* size lb in *result. The caller must make sure that *result is */
/* traced even if objects are ptrfree. */
result = (void *)my_entry; \
*my_fl = next; \
init; \
- PREFETCH_FOR_WRITE(next); \
+ GC_PREFETCH_FOR_WRITE(next); \
GC_ASSERT(GC_size(result) >= (granules)*GC_GRANULE_BYTES); \
GC_ASSERT((kind) == PTRFREE || ((GC_word *)result)[1] == 0); \
break; \
* An architecture may define PREFETCH(x) to preload the cache with *x.
* This defaults to GCC built-in operation (or a no-op for other compilers).
*
- * PREFETCH_FOR_WRITE(x) is used if *x is about to be written.
+ * GC_PREFETCH_FOR_WRITE(x) is used if *x is about to be written.
*
* An architecture may also define CLEAR_DOUBLE(x) to be a fast way to
* clear the two words at GC_malloc-aligned address x. By default,
/* The performance impact of prefetches is untested */
# define PREFETCH(x) \
__asm__ __volatile__ ("dcbt 0,%0" : : "r" ((const void *) (x)))
-# define PREFETCH_FOR_WRITE(x) \
+# define GC_PREFETCH_FOR_WRITE(x) \
__asm__ __volatile__ ("dcbtst 0,%0" : : "r" ((const void *) (x)))
# endif
/* There seems to be some issues with trylock hanging on darwin. */
# ifdef FORCE_WRITE_PREFETCH
/* Using prefetches for write seems to have a slight negative */
/* impact on performance, at least for a PIII/500. */
-# define PREFETCH_FOR_WRITE(x) \
+# define GC_PREFETCH_FOR_WRITE(x) \
__asm__ __volatile__ ("prefetcht0 %0" : : "m"(*(char *)(x)))
# else
# define NO_PREFETCH_FOR_WRITE
# elif defined(USE_3DNOW_PREFETCH)
# define PREFETCH(x) \
__asm__ __volatile__ ("prefetch %0" : : "m"(*(char *)(x)))
-# define PREFETCH_FOR_WRITE(x) \
+# define GC_PREFETCH_FOR_WRITE(x) \
__asm__ __volatile__ ("prefetchw %0" : : "m"(*(char *)(x)))
# endif
# if defined(__GLIBC__)
# ifndef __INTEL_COMPILER
# define PREFETCH(x) \
__asm__ (" lfetch [%0]": : "r"(x))
-# define PREFETCH_FOR_WRITE(x) \
+# define GC_PREFETCH_FOR_WRITE(x) \
__asm__ (" lfetch.excl [%0]": : "r"(x))
# define CLEAR_DOUBLE(x) \
__asm__ (" stf.spill [%0]=f0": : "r"((void *)(x)))
# else
# include <ia64intrin.h>
# define PREFETCH(x) __lfetch(__lfhint_none, (x))
-# define PREFETCH_FOR_WRITE(x) __lfetch(__lfhint_nta, (x))
+# define GC_PREFETCH_FOR_WRITE(x) __lfetch(__lfhint_nta, (x))
# define CLEAR_DOUBLE(x) __stf_spill((void *)(x), 0)
# endif /* __INTEL_COMPILER */
# endif
# endif
#endif
-#ifndef PREFETCH_FOR_WRITE
+#ifndef GC_PREFETCH_FOR_WRITE
# if defined(__GNUC__) && __GNUC__ >= 3 && !defined(NO_PREFETCH_FOR_WRITE)
-# define PREFETCH_FOR_WRITE(x) __builtin_prefetch((x), 1)
+# define GC_PREFETCH_FOR_WRITE(x) __builtin_prefetch((x), 1)
# else
-# define PREFETCH_FOR_WRITE(x) (void)0
+# define GC_PREFETCH_FOR_WRITE(x) (void)0
# endif
#endif
p[3] = 0;
p += 4;
for (; (word)p < (word)lim; p += 4) {
- PREFETCH_FOR_WRITE((ptr_t)(p+64));
+ GC_PREFETCH_FOR_WRITE((ptr_t)(p + 64));
p[0] = (word)(p-4);
p[1] = 0;
CLEAR_DOUBLE(p+2);
p[4] = (word)p;
p += 8;
for (; (word)p < (word)lim; p += 8) {
- PREFETCH_FOR_WRITE((ptr_t)(p+64));
+ GC_PREFETCH_FOR_WRITE((ptr_t)(p + 64));
p[0] = (word)(p-4);
p[4] = (word)p;
};
/* If we were more serious about it, these should go inside */
/* the loops. But write prefetches usually don't seem to */
/* matter much. */
- PREFETCH_FOR_WRITE((ptr_t)h);
- PREFETCH_FOR_WRITE((ptr_t)h + 128);
- PREFETCH_FOR_WRITE((ptr_t)h + 256);
- PREFETCH_FOR_WRITE((ptr_t)h + 378);
+ GC_PREFETCH_FOR_WRITE((ptr_t)h);
+ GC_PREFETCH_FOR_WRITE((ptr_t)h + 128);
+ GC_PREFETCH_FOR_WRITE((ptr_t)h + 256);
+ GC_PREFETCH_FOR_WRITE((ptr_t)h + 378);
# ifndef SMALL_CONFIG
/* Handle small objects sizes more efficiently. For larger objects */
/* the difference is less significant. */