Feature #8985 ยป xwillfree.diff
array.c | ||
---|---|---|
ARY_SET_HEAP_LEN(ary, len);
|
||
}
|
||
else {
|
||
xwillfree(RARRAY(ary)->as.heap.aux.capa * sizeof(VALUE));
|
||
REALLOC_N(RARRAY(ary)->as.heap.ptr, VALUE, (capacity));
|
||
}
|
||
ARY_SET_CAPA(ary, (capacity));
|
||
... | ... | |
if (!ARY_EMBED_P(ary)) {
|
||
long len = RARRAY_LEN(ary);
|
||
const VALUE *ptr = RARRAY_CONST_PTR(ary);
|
||
xwillfree(RARRAY(ary)->as.heap.aux.capa * sizeof(VALUE));
|
||
if (len > capacity) len = capacity;
|
||
MEMCPY((VALUE *)RARRAY(ary)->as.ary, ptr, VALUE, len);
|
||
FL_SET_EMBED(ary);
|
||
... | ... | |
long old_capa = RARRAY(ary)->as.heap.aux.capa;
|
||
assert(!ARY_SHARED_P(ary));
|
||
assert(old_capa >= capacity);
|
||
if (old_capa > capacity)
|
||
if (old_capa > capacity) {
|
||
xwillfree(old_capa * sizeof(VALUE));
|
||
REALLOC_N(RARRAY(ary)->as.heap.ptr, VALUE, capacity);
|
||
}
|
||
}
|
||
static void
|
||
... | ... | |
rb_ary_free(VALUE ary)
|
||
{
|
||
if (ARY_OWNS_HEAP_P(ary)) {
|
||
xwillfree(RARRAY(ary)->as.heap.aux.capa * sizeof(VALUE));
|
||
xfree((void *)ARY_HEAP_PTR(ary));
|
||
}
|
||
}
|
||
... | ... | |
rb_ary_modify(ary);
|
||
if (argc == 0) {
|
||
if (ARY_OWNS_HEAP_P(ary) && RARRAY_CONST_PTR(ary) != 0) {
|
||
xwillfree(RARRAY(ary)->as.heap.aux.capa * sizeof(VALUE));
|
||
xfree((void *)RARRAY_CONST_PTR(ary));
|
||
}
|
||
rb_ary_unshare_safe(ary);
|
||
... | ... | |
}
|
||
else {
|
||
if (olen > len + ARY_DEFAULT_SIZE) {
|
||
xwillfree(RARRAY(ary)->as.heap.aux.capa * sizeof(VALUE));
|
||
REALLOC_N(RARRAY(ary)->as.heap.ptr, VALUE, len);
|
||
ARY_SET_CAPA(ary, len);
|
||
}
|
||
... | ... | |
rb_ary_unshare(ary);
|
||
}
|
||
else {
|
||
xwillfree(RARRAY(ary)->as.heap.aux.capa * sizeof(VALUE));
|
||
xfree((void *)ARY_HEAP_PTR(ary));
|
||
}
|
||
ARY_SET_PTR(ary, RARRAY_CONST_PTR(tmp));
|
||
... | ... | |
VALUE shared = 0;
|
||
if (ARY_OWNS_HEAP_P(copy)) {
|
||
xwillfree(RARRAY(copy)->as.heap.aux.capa * sizeof(VALUE));
|
||
RARRAY_PTR_USE(copy, ptr, xfree(ptr));
|
||
}
|
||
else if (ARY_SHARED_P(copy)) {
|
||
... | ... | |
else {
|
||
VALUE shared = ary_make_shared(orig);
|
||
if (ARY_OWNS_HEAP_P(copy)) {
|
||
xwillfree(RARRAY(copy)->as.heap.aux.capa * sizeof(VALUE));
|
||
RARRAY_PTR_USE(copy, ptr, xfree(ptr));
|
||
}
|
||
else {
|
gc.c | ||
---|---|---|
#define GC_MALLOC_LIMIT (8 /* 8 MB */ * 1024 * 1024 /* 1MB */)
|
||
#endif
|
||
#ifndef GC_MALLOC_LIMIT_MAX
|
||
#define GC_MALLOC_LIMIT_MAX (512 /* 512 MB */ * 1024 * 1024 /* 1MB */)
|
||
#define GC_MALLOC_LIMIT_MAX (256 /* 256 MB */ * 1024 * 1024 /* 1MB */)
|
||
#endif
|
||
#ifndef GC_MALLOC_LIMIT_GROWTH_FACTOR
|
||
#define GC_MALLOC_LIMIT_GROWTH_FACTOR 1.8
|
||
... | ... | |
typedef struct rb_objspace {
|
||
struct {
|
||
size_t limit;
|
||
size_t increase;
|
||
ssize_t limit;
|
||
ssize_t increase;
|
||
#if CALC_EXACT_MALLOC_SIZE
|
||
size_t allocated_size;
|
||
size_t allocations;
|
||
... | ... | |
case T_OBJECT:
|
||
if (!(RANY(obj)->as.basic.flags & ROBJECT_EMBED) &&
|
||
RANY(obj)->as.object.as.heap.ivptr) {
|
||
xwillfree(RANY(obj)->as.object.as.heap.numiv * sizeof(VALUE));
|
||
xfree(RANY(obj)->as.object.as.heap.ivptr);
|
||
}
|
||
break;
|
||
... | ... | |
case T_BIGNUM:
|
||
if (!(RBASIC(obj)->flags & RBIGNUM_EMBED_FLAG) && RBIGNUM_DIGITS(obj)) {
|
||
xwillfree(RANY(obj)->as.bignum.as.heap.len * sizeof(BDIGIT));
|
||
xfree(RBIGNUM_DIGITS(obj));
|
||
}
|
||
break;
|
||
... | ... | |
case T_STRUCT:
|
||
if ((RBASIC(obj)->flags & RSTRUCT_EMBED_LEN_MASK) == 0 &&
|
||
RANY(obj)->as.rstruct.as.heap.ptr) {
|
||
xwillfree(RANY(obj)->as.rstruct.as.heap.len * sizeof(VALUE));
|
||
xfree((void *)RANY(obj)->as.rstruct.as.heap.ptr);
|
||
}
|
||
break;
|
||
... | ... | |
/* reset malloc info */
|
||
{
|
||
size_t inc = ATOMIC_SIZE_EXCHANGE(malloc_increase, 0);
|
||
size_t old_limit = malloc_limit;
|
||
ssize_t inc = ATOMIC_SIZE_EXCHANGE(malloc_increase, 0);
|
||
ssize_t old_limit = malloc_limit;
|
||
if (inc > malloc_limit) {
|
||
malloc_limit += (size_t)(malloc_limit * (initial_malloc_limit_growth_factor - 1));
|
||
... | ... | |
}
|
||
static void
|
||
vm_malloc_increase(rb_objspace_t *objspace, size_t size, int do_gc)
|
||
vm_malloc_increase(rb_objspace_t *objspace, size_t size)
|
||
{
|
||
ATOMIC_SIZE_ADD(malloc_increase, size);
|
||
if ((ruby_gc_stress && !ruby_disable_gc_stress) ||
|
||
(do_gc && (malloc_increase > malloc_limit))) {
|
||
(malloc_increase > malloc_limit)) {
|
||
garbage_collect_with_gvl(objspace, 0, 0, GPR_FLAG_MALLOC);
|
||
}
|
||
}
|
||
static void
|
||
vm_malloc_decrease(rb_objspace_t *objspace, size_t size)
|
||
{
|
||
ATOMIC_SIZE_SUB(malloc_increase, size);
|
||
}
|
||
static inline size_t
|
||
vm_malloc_prepare(rb_objspace_t *objspace, size_t size)
|
||
{
|
||
... | ... | |
size += sizeof(size_t);
|
||
#endif
|
||
vm_malloc_increase(objspace, size, TRUE);
|
||
vm_malloc_increase(objspace, size);
|
||
return size;
|
||
}
|
||
... | ... | |
return 0;
|
||
}
|
||
vm_malloc_increase(objspace, size, FALSE);
|
||
vm_malloc_increase(objspace, size);
|
||
#if CALC_EXACT_MALLOC_SIZE
|
||
size += sizeof(size_t);
|
||
... | ... | |
vm_xfree(&rb_objspace, x);
|
||
}
|
||
void
|
||
ruby_xwill_free(ssize_t size)
|
||
{
|
||
vm_malloc_decrease(&rb_objspace, size);
|
||
}
|
||
/* Mimic ruby_xmalloc, but need not rb_objspace.
|
||
* should return pointer suitable for ruby_xfree
|
include/ruby/defines.h | ||
---|---|---|
#define xrealloc ruby_xrealloc
|
||
#define xrealloc2 ruby_xrealloc2
|
||
#define xfree ruby_xfree
|
||
#define xwillfree ruby_xwill_free
|
||
#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3
|
||
# define RUBY_ATTR_ALLOC_SIZE(params) __attribute__ ((__alloc_size__ params))
|
||
... | ... | |
void *xrealloc(void*,size_t) RUBY_ATTR_ALLOC_SIZE((2));
|
||
void *xrealloc2(void*,size_t,size_t) RUBY_ATTR_ALLOC_SIZE((2,3));
|
||
void xfree(void*);
|
||
void xwillfree(ssize_t);
|
||
#define STRINGIZE(expr) STRINGIZE0(expr)
|
||
#ifndef STRINGIZE0
|
st.c | ||
---|---|---|
#define calloc xcalloc
|
||
#define realloc xrealloc
|
||
#define free(x) xfree(x)
|
||
#define willfree(x) xwillfree(x)
|
||
#else
|
||
#define willfree(x)
|
||
#endif
|
||
#define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
|
||
... | ... | |
/* preparation for possible allocation improvements */
|
||
#define st_alloc_entry() (st_table_entry *)malloc(sizeof(st_table_entry))
|
||
#define st_free_entry(entry) free(entry)
|
||
#define st_free_entry(entry) do { xwillfree(sizeof(*entry)); free(entry); } while(0)
|
||
#define st_alloc_table() (st_table *)malloc(sizeof(st_table))
|
||
#define st_dealloc_table(table) free(table)
|
||
#define st_dealloc_table(table) do { xwillfree(sizeof(*table)); free(table); } while(0)
|
||
#define st_alloc_bins(size) (st_table_entry **)calloc(size, sizeof(st_table_entry *))
|
||
#define st_free_bins(bins, size) free(bins)
|
||
#define st_free_bins(bins, size) do { xwillfree(size*sizeof(*bins)); free(bins); } while(0)
|
||
static inline st_table_entry**
|
||
st_realloc_bins(st_table_entry **bins, st_index_t newsize, st_index_t oldsize)
|
||
{
|
string.c | ||
---|---|---|
}\
|
||
}\
|
||
else {\
|
||
xwillfree(RSTRING(str)->as.heap.aux.capa);\
|
||
REALLOC_N(RSTRING(str)->as.heap.ptr, char, (capacity)+termlen);\
|
||
if (!STR_NOCAPA_P(str))\
|
||
RSTRING(str)->as.heap.aux.capa = (capacity);\
|
||
... | ... | |
st_delete(frozen_strings, &fstr, NULL);
|
||
}
|
||
if (!STR_EMBED_P(str) && !STR_SHARED_P(str)) {
|
||
xwillfree(RSTRING(str)->as.heap.aux.capa);
|
||
xfree(RSTRING(str)->as.heap.ptr);
|
||
}
|
||
}
|
||
... | ... | |
long capa = len + expand;
|
||
int termlen = TERM_LEN(str);
|
||
if (!STR_EMBED_P(str)) {
|
||
xwillfree(RSTRING(str)->as.heap.aux.capa);
|
||
REALLOC_N(RSTRING(str)->as.heap.ptr, char, capa + termlen);
|
||
RSTRING(str)->as.heap.aux.capa = capa;
|
||
}
|
||
... | ... | |
{
|
||
str_modifiable(str);
|
||
if (!STR_SHARED_P(str) && !STR_EMBED_P(str)) {
|
||
xwillfree(RSTRING(str)->as.heap.aux.capa);
|
||
xfree(RSTRING_PTR(str));
|
||
RSTRING(str)->as.heap.ptr = 0;
|
||
RSTRING(str)->as.heap.len = 0;
|
||
... | ... | |
}
|
||
else if (len + termlen <= RSTRING_EMBED_LEN_MAX + 1) {
|
||
char *ptr = RSTRING(str)->as.heap.ptr;
|
||
ssize_t oldlen = RSTRING(str)->as.heap.aux.capa;
|
||
STR_SET_EMBED(str);
|
||
if (slen > len) slen = len;
|
||
if (slen > 0) MEMCPY(RSTRING(str)->as.ary, ptr, char, slen);
|
||
TERM_FILL(RSTRING(str)->as.ary + len, termlen);
|
||
STR_SET_EMBED_LEN(str, len);
|
||
if (independent) xfree(ptr);
|
||
if (independent) {
|
||
xwillfree(oldlen);
|
||
xfree(ptr);
|
||
}
|
||
return str;
|
||
}
|
||
else if (!independent) {
|
||
str_make_independent_expand(str, len - slen);
|
||
}
|
||
else if (slen < len || slen - len > 1024) {
|
||
xwillfree(RSTRING(str)->as.heap.aux.capa);
|
||
REALLOC_N(RSTRING(str)->as.heap.ptr, char, len + termlen);
|
||
}
|
||
if (!STR_NOCAPA_P(str)) {
|
||
... | ... | |
if (nlen <= RSTRING_EMBED_LEN_MAX) {
|
||
char *oldptr = ptr;
|
||
int fl = (int)(RBASIC(str)->flags & (STR_NOEMBED|ELTS_SHARED));
|
||
ssize_t oldlen = RSTRING(str)->as.heap.aux.capa;
|
||
STR_SET_EMBED(str);
|
||
STR_SET_EMBED_LEN(str, nlen);
|
||
ptr = RSTRING(str)->as.ary;
|
||
memmove(ptr, oldptr + len, nlen);
|
||
if (fl == STR_NOEMBED) xfree(oldptr);
|
||
if (fl == STR_NOEMBED) {
|
||
xwillfree(oldlen);
|
||
xfree(oldptr);
|
||
}
|
||
}
|
||
else {
|
||
if (!STR_SHARED_P(str)) rb_str_new4(str);
|
||
... | ... | |
t += tlen;
|
||
}
|
||
if (!STR_EMBED_P(str)) {
|
||
xwillfree(RSTRING(str)->as.heap.aux.capa);
|
||
xfree(RSTRING(str)->as.heap.ptr);
|
||
}
|
||
*t = '\0';
|
||
... | ... | |
t += tlen;
|
||
}
|
||
if (!STR_EMBED_P(str)) {
|
||
xwillfree(RSTRING(str)->as.heap.aux.capa);
|
||
xfree(RSTRING(str)->as.heap.ptr);
|
||
}
|
||
*t = '\0';
|
time.c | ||
---|---|---|
static void
|
||
time_free(void *tobj)
|
||
{
|
||
if (tobj) xfree(tobj);
|
||
if (tobj) {
|
||
xwillfree(sizeof(struct time_object));
|
||
xfree(tobj);
|
||
}
|
||
}
|
||
static size_t
|
variable.c | ||
---|---|---|
ROBJECT(obj)->as.heap.ivptr = newptr;
|
||
}
|
||
else {
|
||
xwillfree(ROBJECT(obj)->as.heap.numiv * sizeof(VALUE));
|
||
REALLOC_N(ROBJECT(obj)->as.heap.ivptr, VALUE, newsize);
|
||
newptr = ROBJECT(obj)->as.heap.ivptr;
|
||
}
|