Commit a99235e8 authored by Chris Toshok's avatar Chris Toshok

free generator stacks both in the destructor and when a generator exits.

also, don't register MAX_STACK_SIZE bytes with the GC, register INITIAL_STACK_SIZE.
parent 71840bc9
......@@ -60,6 +60,29 @@ public:
}
};
static void freeGeneratorStack(BoxedGenerator* g) {
if (g->stack_begin == NULL)
return;
available_addrs.push_back((uint64_t)g->stack_begin);
// Limit the number of generator stacks we keep around:
if (available_addrs.size() > 5) {
uint64_t addr = available_addrs.front();
available_addrs.pop_front();
int r = munmap((void*)(addr - MAX_STACK_SIZE), MAX_STACK_SIZE);
assert(r == 0);
// also unmap the redzone
#if STACK_GROWS_DOWN
r = munmap((void*)addr, STACK_REDZONE_SIZE);
assert(r == 0);
#else
#error "implement me"
#endif
}
g->stack_begin = NULL;
}
Context* getReturnContextForGeneratorFrame(void* frame_addr) {
BoxedGenerator* generator = s_generator_map[frame_addr];
assert(generator);
......@@ -88,6 +111,7 @@ void generatorEntry(BoxedGenerator* g) {
// we returned from the body of the generator. next/send/throw will notify the caller
g->entryExited = true;
threading::popGenerator();
freeGeneratorStack(g);
swapContext(&g->context, g->returnContext, 0);
}
......@@ -220,7 +244,12 @@ extern "C" BoxedGenerator::BoxedGenerator(BoxedFunctionBase* function, Box* arg1
#error "implement me"
#endif
gc::registerGCManagedBytes(MAX_STACK_SIZE);
// we're registering memory that isn't in the gc heap here,
// which may sound wrong. Generators, however, can represent
// a larger tax on system resources than just their GC
// allocation, so we try to encode that here as additional gc
// heap pressure.
gc::registerGCManagedBytes(INITIAL_STACK_SIZE);
} else {
generator_stack_reused.log();
......@@ -290,18 +319,7 @@ Box* generatorName(Box* _self, void* context) {
void generatorDestructor(Box* b) {
assert(isSubclass(b->cls, generator_cls));
BoxedGenerator* self = static_cast<BoxedGenerator*>(b);
if (self->stack_begin) {
available_addrs.push_back((uint64_t)self->stack_begin);
// Limit the number of generator stacks we keep around:
if (available_addrs.size() > 5) {
uint64_t addr = available_addrs.front();
available_addrs.pop_front();
int r = munmap((void*)(addr - MAX_STACK_SIZE), MAX_STACK_SIZE);
assert(r == 0);
}
}
self->stack_begin = NULL;
freeGeneratorStack(self);
}
void setupGenerator() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment