77 lines
1.7 KiB
V
77 lines
1.7 KiB
V
// vtest retry: 4
|
|
/*
|
|
* To verify the effect of "[keep_args_alive]", this attribute may be commented out.
|
|
* However it is not guaranteed that then this test will fail.
|
|
* To provoke a failure it seems to be best to use `gcc` with optimization:
|
|
* `gcc -gc boehm -cc gcc-9 -prod test keep_args_alive_test.v`.
|
|
* Without optimization, pointer variables may remain on the stack even if
|
|
* not used any more.
|
|
*/
|
|
import rand
|
|
import sync
|
|
|
|
#flag -I@VEXEROOT/vlib/v/tests
|
|
#include "keep_args_alive_test_c.h"
|
|
|
|
fn C.atomic_load_ptr(voidptr) voidptr
|
|
|
|
fn C.atomic_store_ptr(voidptr, voidptr)
|
|
|
|
[keep_args_alive]
|
|
fn C.calc_expr_after_delay(voidptr, int, voidptr) int
|
|
|
|
fn set_vals() voidptr {
|
|
unsafe {
|
|
p := &int(malloc(8000000))
|
|
q := &int(malloc(8000000))
|
|
aa := p + 769345
|
|
*aa = -4578
|
|
bb := q + 572397
|
|
*bb = 793254
|
|
p = &int(0)
|
|
q = &int(0)
|
|
r := &voidptr(malloc(1000000))
|
|
r[456] = aa
|
|
r[7932] = bb
|
|
aa = &int(0)
|
|
bb = &int(0)
|
|
return r
|
|
}
|
|
}
|
|
|
|
fn tt(mut sem sync.Semaphore) int {
|
|
waste_mem(10000, mut sem)
|
|
r := &voidptr(set_vals())
|
|
g := unsafe { C.calc_expr_after_delay(r[456], 12, r[7932]) }
|
|
return g
|
|
}
|
|
|
|
fn waste_mem(n int, mut sem sync.Semaphore) {
|
|
mut m := []voidptr{len: 30}
|
|
for j := 0; n < 0 || j < n; j++ {
|
|
i := rand.intn(30)
|
|
m[i] = unsafe { malloc(10000) }
|
|
fill := rand.intn(256)
|
|
unsafe { C.memset(m[i], fill, 10000) }
|
|
if n < 0 && sem.try_wait() {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
fn test_keep_args_alive_attribute() {
|
|
mut sem := sync.new_semaphore()
|
|
$if gcboehm ? {
|
|
go waste_mem(-1, mut sem)
|
|
go waste_mem(-1, mut sem)
|
|
waste_mem(10000, mut sem)
|
|
}
|
|
r := &voidptr(set_vals())
|
|
v := unsafe { C.calc_expr_after_delay(r[456], 12, r[7932]) }
|
|
$if gcboehm ? {
|
|
sem.post()
|
|
sem.post()
|
|
}
|
|
assert v == 738318
|
|
}
|