}
-# define HBLK_IS_FREE(hdr) ((hdr) -> hb_map == GC_invalid_map)
# define PHDR(hhdr) HDR(hhdr -> hb_prev)
# define NHDR(hhdr) HDR(hhdr -> hb_next)
while ((ptr_t)lasthbp <= search_end
&& (thishbp = GC_is_black_listed(lasthbp,
- (word)eff_size_needed))) {
+ (word)eff_size_needed))
+ != 0) {
lasthbp = thishbp;
}
size_avail -= (ptr_t)lasthbp - (ptr_t)hbp;
&& orig_avail - size_needed
> (signed_word)BL_LIMIT) {
/* Punt, since anything else risks unreasonable heap growth. */
- if (0 != GETENV("GC_NO_BLACKLIST_WARNING")) {
- WARN("Needed to allocate blacklisted block at 0x%lx\n",
- (word)hbp);
+ if (++GC_large_alloc_warn_suppressed
+ >= GC_large_alloc_warn_interval) {
+ WARN("Repeated allocation of very large block "
+ "(appr. size %ld):\n"
+ "\tMay lead to memory leak and poor performance.\n",
+ size_needed);
+ GC_large_alloc_warn_suppressed = 0;
}
size_avail = orig_avail;
} else if (size_avail == 0 && size_needed == HBLKSIZE
if (0 == hbp) return 0;
- /* Notify virtual dirty bit implementation that we are about to write. */
- GC_write_hint(hbp);
-
/* Add it to map of valid blocks */
if (!GC_install_counts(hbp, (word)size_needed)) return(0);
/* This leaks memory under very rare conditions. */
GC_remove_counts(hbp, (word)size_needed);
return(0); /* ditto */
}
+
+ /* Notify virtual dirty bit implementation that we are about to write. */
+ /* Ensure that pointerfree objects are not protected if it's avoidable. */
+ GC_remove_protection(hbp, divHBLKSZ(size_needed),
+ (hhdr -> hb_descr == 0) /* pointer-free */);
/* We just successfully allocated a block. Restart count of */
/* consecutive failures. */
if (HBLK_IS_FREE(hhdr)) {
GC_printf1("Duplicate large block deallocation of 0x%lx\n",
(unsigned long) hbp);
+ ABORT("Duplicate large block deallocation");
}
GC_ASSERT(IS_MAPPED(hhdr));