mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
builtin: implement -d debug_realloc
This commit is contained in:
parent
aa878161e9
commit
ca5f88eb7d
@ -77,25 +77,27 @@ pub fn panic(s string) {
|
|||||||
|
|
||||||
// eprintln prints a message with a line end, to stderr. Both stderr and stdout are flushed.
|
// eprintln prints a message with a line end, to stderr. Both stderr and stdout are flushed.
|
||||||
pub fn eprintln(s string) {
|
pub fn eprintln(s string) {
|
||||||
// eprintln is used in panics, so it should not fail at all
|
|
||||||
if s.str == 0 {
|
|
||||||
eprintln('eprintln(NIL)')
|
|
||||||
}
|
|
||||||
C.fflush(C.stdout)
|
C.fflush(C.stdout)
|
||||||
C.fflush(C.stderr)
|
C.fflush(C.stderr)
|
||||||
C.write(2, s.str, s.len)
|
// eprintln is used in panics, so it should not fail at all
|
||||||
C.write(2, c'\n', 1)
|
if s.str == 0 {
|
||||||
|
C.write(2, c'eprintln(NIL)\n', 14)
|
||||||
|
} else {
|
||||||
|
C.write(2, s.str, s.len)
|
||||||
|
C.write(2, c'\n', 1)
|
||||||
|
}
|
||||||
C.fflush(C.stderr)
|
C.fflush(C.stderr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// eprint prints a message to stderr. Both stderr and stdout are flushed.
|
// eprint prints a message to stderr. Both stderr and stdout are flushed.
|
||||||
pub fn eprint(s string) {
|
pub fn eprint(s string) {
|
||||||
if s.str == 0 {
|
|
||||||
eprint('eprint(NIL)')
|
|
||||||
}
|
|
||||||
C.fflush(C.stdout)
|
C.fflush(C.stdout)
|
||||||
C.fflush(C.stderr)
|
C.fflush(C.stderr)
|
||||||
C.write(2, s.str, s.len)
|
if s.str == 0 {
|
||||||
|
C.write(2, c'eprint(NIL)\n', 12)
|
||||||
|
} else {
|
||||||
|
C.write(2, s.str, s.len)
|
||||||
|
}
|
||||||
C.fflush(C.stderr)
|
C.fflush(C.stderr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,36 +145,32 @@ pub fn println(s string) {
|
|||||||
[unsafe]
|
[unsafe]
|
||||||
pub fn malloc(n int) byteptr {
|
pub fn malloc(n int) byteptr {
|
||||||
if n <= 0 {
|
if n <= 0 {
|
||||||
panic('malloc(<=0)')
|
panic('> V malloc(<=0)')
|
||||||
}
|
}
|
||||||
|
$if vplayground ? {
|
||||||
|
if n > 10000 {
|
||||||
|
panic('allocating more than 10 KB is not allowed in the playground')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$if trace_malloc ? {
|
||||||
|
total_m += n
|
||||||
|
C.fprintf(C.stderr, c'v_malloc %d total %d\n', n, total_m)
|
||||||
|
// print_backtrace()
|
||||||
|
}
|
||||||
|
mut res := byteptr(0)
|
||||||
$if prealloc {
|
$if prealloc {
|
||||||
// println('p')
|
res = g_m2_ptr
|
||||||
res := g_m2_ptr
|
|
||||||
unsafe {
|
unsafe {
|
||||||
g_m2_ptr += n
|
g_m2_ptr += n
|
||||||
}
|
}
|
||||||
nr_mallocs++
|
nr_mallocs++
|
||||||
return res
|
|
||||||
} $else {
|
} $else {
|
||||||
ptr := unsafe {C.malloc(n)}
|
res = unsafe { C.malloc(n) }
|
||||||
if ptr == 0 {
|
if res == 0 {
|
||||||
panic('malloc($n) failed')
|
panic('malloc($n) failed')
|
||||||
}
|
}
|
||||||
return ptr
|
|
||||||
}
|
}
|
||||||
/*
|
return res
|
||||||
TODO
|
|
||||||
#ifdef VPLAY
|
|
||||||
if n > 10000 {
|
|
||||||
panic('allocating more than 10 KB is not allowed in the playground')
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef DEBUG_ALLOC
|
|
||||||
total_m += n
|
|
||||||
println('\n\n\nmalloc($n) total=$total_m')
|
|
||||||
print_backtrace()
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -180,23 +178,38 @@ pub fn malloc(n int) byteptr {
|
|||||||
fn malloc_size(b byteptr) int
|
fn malloc_size(b byteptr) int
|
||||||
*/
|
*/
|
||||||
// v_realloc resizes the memory block `b` with `n` bytes.
|
// v_realloc resizes the memory block `b` with `n` bytes.
|
||||||
// The `b byteptr` must be a pointer to an existing memory block previously allocated with `malloc`, `v_calloc` or `vcalloc`.
|
// The `b byteptr` must be a pointer to an existing memory block
|
||||||
|
// previously allocated with `malloc`, `v_calloc` or `vcalloc`.
|
||||||
[unsafe]
|
[unsafe]
|
||||||
pub fn v_realloc(b byteptr, n int) byteptr {
|
pub fn v_realloc(b byteptr, n int) byteptr {
|
||||||
|
mut new_ptr := byteptr(0)
|
||||||
$if prealloc {
|
$if prealloc {
|
||||||
unsafe {
|
unsafe {
|
||||||
new_ptr := malloc(n)
|
new_ptr = malloc(n)
|
||||||
size := 0 // malloc_size(b)
|
C.memcpy(new_ptr, b, n)
|
||||||
C.memcpy(new_ptr, b, size)
|
|
||||||
return new_ptr
|
|
||||||
}
|
}
|
||||||
} $else {
|
} $else {
|
||||||
ptr := unsafe {C.realloc(b, n)}
|
$if debug_realloc ? {
|
||||||
if ptr == 0 {
|
// NB: this is slower, but helps debugging memory problems.
|
||||||
panic('realloc($n) failed')
|
// The main idea is to always force reallocating:
|
||||||
|
// 1) allocate a new memory block
|
||||||
|
// 2) copy the old to the new
|
||||||
|
// 3) fill the old with 0x57 (`W`)
|
||||||
|
// 4) free the old block
|
||||||
|
// => if there is still a pointer to the old block somewhere
|
||||||
|
// it will point to memory that is now filled with 0x57.
|
||||||
|
new_ptr = malloc(n)
|
||||||
|
C.memcpy(new_ptr, b, n)
|
||||||
|
C.memset(b, 0x57, n)
|
||||||
|
C.free(b)
|
||||||
|
} $else {
|
||||||
|
new_ptr = unsafe { C.realloc(b, n) }
|
||||||
|
if new_ptr == 0 {
|
||||||
|
panic('realloc($n) failed')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ptr
|
|
||||||
}
|
}
|
||||||
|
return new_ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
// v_calloc dynamically allocates a zeroed `n` bytes block of memory on the heap.
|
// v_calloc dynamically allocates a zeroed `n` bytes block of memory on the heap.
|
||||||
|
Loading…
Reference in New Issue
Block a user