Bug 854052 - Mark stub pointers stored in stub frames. r=djvj

This commit is contained in:
Jan de Mooij 2013-03-26 19:23:24 +01:00
Родитель b645ed9bed
Коммит f767f5cb2d
5 изменённых файлов: 52 добавлений и 3 удалений

Просмотреть файл

@ -378,9 +378,22 @@ ICFallbackStub::unlinkStub(Zone *zone, ICStub *prev, ICStub *stub)
stub->trace(zone->barrierTracer());
}
if (ICStub::CanMakeCalls(stub->kind()) && stub->isMonitored()) {
// This stub can make calls so we can return to it if it's on the stack.
// We just have to reset its firstMonitorStub_ field to avoid a stale
// pointer when purgeOptimizedStubs destroys all optimized monitor
// stubs (unlinked stubs won't be updated).
ICTypeMonitor_Fallback *monitorFallback = toMonitoredFallbackStub()->fallbackMonitorStub();
stub->toMonitoredStub()->resetFirstMonitorStub(monitorFallback);
}
#ifdef DEBUG
// Poison stub code to ensure we don't call this stub again.
stub->stubCode_ = (uint8_t *)0xbad;
// Poison stub code to ensure we don't call this stub again. However, if this
// stub can make calls, a pointer to it may be stored in a stub frame on the
// stack, so we can't touch the stubCode_ or GC will crash when marking this
// pointer.
if (!ICStub::CanMakeCalls(stub->kind()))
stub->stubCode_ = (uint8_t *)0xbad;
#endif
}

Просмотреть файл

@ -713,6 +713,7 @@ class ICStub
}
static bool CanMakeCalls(ICStub::Kind kind) {
JS_ASSERT(IsValidKind(kind));
switch (kind) {
case Call_Scripted:
case Call_AnyScripted:

Просмотреть файл

@ -689,6 +689,21 @@ MarkIonJSFrame(JSTracer *trc, const IonFrameIterator &frame)
#endif
}
static void
MarkBaselineStubFrame(JSTracer *trc, const IonFrameIterator &frame)
{
// Mark the ICStub pointer stored in the stub frame. This is necessary
// so that we don't destroy the stub code after unlinking the stub.
JS_ASSERT(frame.type() == IonFrame_BaselineStub);
IonBaselineStubFrameLayout *layout = (IonBaselineStubFrameLayout *)frame.fp();
ICStub *stub = layout->stubPtr();
JS_ASSERT(ICStub::CanMakeCalls(stub->kind()));
stub->trace(trc);
}
void
IonActivationIterator::ionStackRange(uintptr_t *&min, uintptr_t *&end)
{
@ -833,7 +848,7 @@ MarkIonActivation(JSTracer *trc, const IonActivationIterator &activations)
frames.baselineFrame()->trace(trc);
break;
case IonFrame_BaselineStub:
// Stub frames are not marked.
MarkBaselineStubFrame(trc, frames);
break;
case IonFrame_OptimizedJS:
MarkIonJSFrame(trc, frames);

Просмотреть файл

@ -167,6 +167,8 @@ class IonOsrFrameLayout : public IonJSFrameLayout
}
};
class ICStub;
class IonBaselineStubFrameLayout : public IonCommonFrameLayout
{
public:
@ -174,9 +176,17 @@ class IonBaselineStubFrameLayout : public IonCommonFrameLayout
return sizeof(IonBaselineStubFrameLayout);
}
static inline size_t reverseOffsetOfStubPtr() {
return -sizeof(void *);
}
static inline size_t reverseOffsetOfSavedFramePtr() {
return -(2 * sizeof(void *));
}
inline ICStub *stubPtr() {
uint8_t *fp = reinterpret_cast<uint8_t *>(this);
return *reinterpret_cast<ICStub **>(fp + reverseOffsetOfStubPtr());
}
};
class IonNativeExitFrameLayout;

Просмотреть файл

@ -412,6 +412,8 @@ class IonOsrFrameLayout : public IonJSFrameLayout
}
};
class ICStub;
class IonBaselineStubFrameLayout : public IonCommonFrameLayout
{
public:
@ -419,9 +421,17 @@ class IonBaselineStubFrameLayout : public IonCommonFrameLayout
return sizeof(IonBaselineStubFrameLayout);
}
static inline size_t reverseOffsetOfStubPtr() {
return -sizeof(void *);
}
static inline size_t reverseOffsetOfSavedFramePtr() {
return -(2 * sizeof(void *));
}
inline ICStub *stubPtr() {
uint8_t *fp = reinterpret_cast<uint8_t *>(this);
return *reinterpret_cast<ICStub **>(fp + reverseOffsetOfStubPtr());
}
};
// An invalidation bailout stack is at the stack pointer for the callee frame.