release all resources in resetFrame

Code including subroutines and conditionals can result in frame and
register resources being held by values which aren't in scope when
resetFrame is called, so we need to clean them up after cleaning the
in-scope values.
This commit is contained in:
Joel Dice 2011-03-27 14:15:05 -06:00
parent 8283e1da46
commit c75cf7ebb6

View File

@ -218,7 +218,8 @@ class LogicalInstruction {
class Resource {
public:
Resource(bool reserved = false):
value(0), site(0), freezeCount(0), referenceCount(0), reserved(reserved)
value(0), site(0), previousAcquired(0), nextAcquired(0), freezeCount(0),
referenceCount(0), reserved(reserved)
{ }
virtual void freeze(Context*, Value*) = 0;
@ -229,6 +230,8 @@ class Resource {
Value* value;
Site* site;
Resource* previousAcquired;
Resource* nextAcquired;
uint8_t freezeCount;
uint8_t referenceCount;
bool reserved;
@ -379,6 +382,7 @@ class Context {
(static_cast<RegisterResource*>
(zone->allocate(sizeof(RegisterResource) * registerLimit))),
frameResources(0),
acquiredResources(0),
firstConstant(0),
lastConstant(0),
machineCode(0),
@ -426,6 +430,7 @@ class Context {
uint8_t floatRegisterLimit;
RegisterResource* registerResources;
FrameResource* frameResources;
Resource* acquiredResources;
ConstantPoolNode* firstConstant;
ConstantPoolNode* lastConstant;
uint8_t* machineCode;
@ -2586,6 +2591,12 @@ acquire(Context* c, Resource* resource, Value* value, Site* site)
steal(c, resource, value);
}
if (c->acquiredResources) {
c->acquiredResources->previousAcquired = resource;
resource->nextAcquired = c->acquiredResources;
}
c->acquiredResources = resource;
resource->value = value;
resource->site = site;
}
@ -2605,6 +2616,21 @@ release(Context* c, Resource* resource, Value* value UNUSED, Site* site UNUSED)
assert(c, buddies(resource->value, value));
assert(c, site == resource->site);
Resource* next = resource->nextAcquired;
if (next) {
next->previousAcquired = resource->previousAcquired;
resource->nextAcquired = 0;
}
Resource* previous = resource->previousAcquired;
if (previous) {
previous->nextAcquired = next;
resource->previousAcquired = 0;
} else {
assert(c, c->acquiredResources == resource);
c->acquiredResources = next;
}
resource->value = 0;
resource->site = 0;
@ -5527,6 +5553,15 @@ resetFrame(Context* c, Event* e)
FrameIterator::Element el = it.next(c);
clearSites(c, el.value);
}
for (Resource* r = c->acquiredResources; r;) {
Resource* next = r->nextAcquired;
Value* v = r->value;
if (v) {
clearSites(c, v);
}
r = next;
}
}
void