Merge branch 'master' into optimize_mcode
This commit is contained in:
151
vm_suite.ce
151
vm_suite.ce
@@ -5562,6 +5562,157 @@ run("gc blob forward pointer chase", function() {
|
||||
}
|
||||
})
|
||||
|
||||
// ============================================================================
|
||||
// GC CLOSURE FRAME SHORTENING
|
||||
// Verify that closure-captured variables survive GC collection, particularly
|
||||
// when the streamline optimizer remaps close slots to different positions.
|
||||
// ============================================================================
|
||||
|
||||
var force_gc = function() {
|
||||
var _g = 0
|
||||
var _gx = null
|
||||
for (_g = 0; _g < 200; _g = _g + 1) {
|
||||
_gx = {a: _g, b: [1, 2, 3], c: "garbage"}
|
||||
}
|
||||
}
|
||||
|
||||
run("gc closure basic - captured function survives gc", function() {
|
||||
var make = function() {
|
||||
function helper() { return 42 }
|
||||
var obj = { call() { return helper() } }
|
||||
return obj
|
||||
}
|
||||
var obj = make()
|
||||
force_gc()
|
||||
assert_eq(obj.call(), 42, "captured function should survive GC")
|
||||
})
|
||||
|
||||
run("gc closure - captured variable survives gc", function() {
|
||||
var make = function() {
|
||||
var val = 99
|
||||
var obj = { get() { return val } }
|
||||
return obj
|
||||
}
|
||||
var obj = make()
|
||||
force_gc()
|
||||
assert_eq(obj.get(), 99, "captured variable should survive GC")
|
||||
})
|
||||
|
||||
run("gc closure - multiple captured variables survive gc", function() {
|
||||
var make = function() {
|
||||
var a = 10
|
||||
var b = 20
|
||||
var c = 30
|
||||
var obj = {
|
||||
sum() { return a + b + c }
|
||||
}
|
||||
return obj
|
||||
}
|
||||
var obj = make()
|
||||
force_gc()
|
||||
assert_eq(obj.sum(), 60, "all captured vars should survive GC")
|
||||
})
|
||||
|
||||
run("gc closure - captured function and var survive gc", function() {
|
||||
var make = function() {
|
||||
function double(x) { return x * 2 }
|
||||
var base = 5
|
||||
var obj = { compute() { return double(base) } }
|
||||
return obj
|
||||
}
|
||||
var obj = make()
|
||||
force_gc()
|
||||
assert_eq(obj.compute(), 10, "captured fn and var should survive GC")
|
||||
})
|
||||
|
||||
run("gc closure - nested closure chain survives gc", function() {
|
||||
var outer = function() {
|
||||
var x = 7
|
||||
var mid = function() {
|
||||
var y = 3
|
||||
var inner = function() { return x + y }
|
||||
return inner
|
||||
}
|
||||
return mid()
|
||||
}
|
||||
var fn = outer()
|
||||
force_gc()
|
||||
assert_eq(fn(), 10, "nested closure chain should survive GC")
|
||||
})
|
||||
|
||||
run("gc closure - multiple methods share captured frame", function() {
|
||||
var make = function() {
|
||||
var count = 0
|
||||
function inc() { count = count + 1 }
|
||||
function get() { return count }
|
||||
var obj = {
|
||||
increment() { inc() },
|
||||
value() { return get() }
|
||||
}
|
||||
return obj
|
||||
}
|
||||
var obj = make()
|
||||
obj.increment()
|
||||
obj.increment()
|
||||
force_gc()
|
||||
obj.increment()
|
||||
assert_eq(obj.value(), 3, "shared closure frame should survive GC")
|
||||
})
|
||||
|
||||
run("gc closure - closure survives repeated gc cycles", function() {
|
||||
var make = function() {
|
||||
var val = 123
|
||||
var obj = { get() { return val } }
|
||||
return obj
|
||||
}
|
||||
var obj = make()
|
||||
force_gc()
|
||||
force_gc()
|
||||
force_gc()
|
||||
assert_eq(obj.get(), 123, "closure should survive repeated GC cycles")
|
||||
})
|
||||
|
||||
run("gc closure - object literal method with temp slot reuse", function() {
|
||||
var make = function() {
|
||||
function helper() { return "ok" }
|
||||
var temp = [1, 2, 3]
|
||||
var unused = {x: temp}
|
||||
var obj = { call() { return helper() } }
|
||||
return obj
|
||||
}
|
||||
var obj = make()
|
||||
force_gc()
|
||||
assert_eq(obj.call(), "ok", "closure should work after temp slots discarded")
|
||||
})
|
||||
|
||||
run("gc closure - closure array survives gc", function() {
|
||||
var make = function() {
|
||||
var items = [10, 20, 30]
|
||||
var obj = {
|
||||
first() { return items[0] },
|
||||
last() { return items[2] }
|
||||
}
|
||||
return obj
|
||||
}
|
||||
var obj = make()
|
||||
force_gc()
|
||||
assert_eq(obj.first(), 10, "captured array first element")
|
||||
assert_eq(obj.last(), 30, "captured array last element")
|
||||
})
|
||||
|
||||
run("gc closure - factory pattern survives gc", function() {
|
||||
var factory = function(name) {
|
||||
function greet() { return "hello " + name }
|
||||
var obj = { say() { return greet() } }
|
||||
return obj
|
||||
}
|
||||
var a = factory("alice")
|
||||
var b = factory("bob")
|
||||
force_gc()
|
||||
assert_eq(a.say(), "hello alice", "first factory closure")
|
||||
assert_eq(b.say(), "hello bob", "second factory closure")
|
||||
})
|
||||
|
||||
// ============================================================================
|
||||
// SUMMARY
|
||||
// ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user