Bug 1169213 - SharedStubs: Introduce JitFrame_IonStub to allow vmcalls out of sharedstubs in IonMonkey, r=npb

This commit is contained in:
Hannes Verschore 2015-06-08 16:39:19 +02:00
parent 38e079708e
commit b774730849
4 changed files with 79 additions and 14 deletions

View File

@ -2707,6 +2707,9 @@ InvalidateActivation(FreeOp* fop, const JitActivationIterator& activations, bool
it.maybeCallee(), (JSScript*)it.script(), it.returnAddressToFp());
break;
}
case JitFrame_IonStub:
JitSpew(JitSpew_IonInvalidate, "#%d ion stub frame @ %p", frameno, it.fp());
break;
case JitFrame_BaselineStub:
JitSpew(JitSpew_IonInvalidate, "#%d baseline stub frame @ %p", frameno, it.fp());
break;
@ -2714,6 +2717,7 @@ InvalidateActivation(FreeOp* fop, const JitActivationIterator& activations, bool
JitSpew(JitSpew_IonInvalidate, "#%d rectifier frame @ %p", frameno, it.fp());
break;
case JitFrame_Unwound_IonJS:
case JitFrame_Unwound_IonStub:
case JitFrame_Unwound_BaselineJS:
case JitFrame_Unwound_BaselineStub:
case JitFrame_Unwound_IonAccessorIC:

View File

@ -34,9 +34,10 @@ enum FrameType
// JS frame used by the baseline JIT.
JitFrame_BaselineJS,
// Frame pushed for baseline JIT stubs that make non-tail calls, so that the
// Frame pushed for JIT stubs that make non-tail calls, so that the
// return address -> ICEntry mapping works.
JitFrame_BaselineStub,
JitFrame_IonStub,
// The entry frame is the initial prologue block transitioning from the VM
// into the Ion world.
@ -55,6 +56,7 @@ enum FrameType
JitFrame_Unwound_BaselineJS,
JitFrame_Unwound_IonJS,
JitFrame_Unwound_BaselineStub,
JitFrame_Unwound_IonStub,
JitFrame_Unwound_Rectifier,
JitFrame_Unwound_IonAccessorIC,
@ -166,6 +168,9 @@ class JitFrameIterator
bool isIonJS() const {
return type_ == JitFrame_IonJS;
}
bool isIonStub() const {
return type_ == JitFrame_IonStub;
}
bool isBailoutJS() const {
return type_ == JitFrame_Bailout;
}

View File

@ -265,6 +265,9 @@ SizeOfFramePrefix(FrameType type)
case JitFrame_BaselineStub:
case JitFrame_Unwound_BaselineStub:
return BaselineStubFrameLayout::Size();
case JitFrame_IonStub:
case JitFrame_Unwound_IonStub:
return JitStubFrameLayout::Size();
case JitFrame_Rectifier:
return RectifierFrameLayout::Size();
case JitFrame_Unwound_Rectifier:
@ -317,6 +320,8 @@ JitFrameIterator::operator++()
type_ = current()->prevType();
if (type_ == JitFrame_Unwound_IonJS)
type_ = JitFrame_IonJS;
else if (type_ == JitFrame_Unwound_IonStub)
type_ = JitFrame_IonStub;
else if (type_ == JitFrame_Unwound_BaselineJS)
type_ = JitFrame_BaselineJS;
else if (type_ == JitFrame_Unwound_BaselineStub)
@ -939,6 +944,7 @@ EnsureExitFrame(CommonFrameLayout* frame)
{
switch (frame->prevType()) {
case JitFrame_Unwound_IonJS:
case JitFrame_Unwound_IonStub:
case JitFrame_Unwound_BaselineJS:
case JitFrame_Unwound_BaselineStub:
case JitFrame_Unwound_Rectifier:
@ -971,6 +977,10 @@ EnsureExitFrame(CommonFrameLayout* frame)
frame->changePrevType(JitFrame_Unwound_IonJS);
return;
case JitFrame_IonStub:
frame->changePrevType(JitFrame_Unwound_IonStub);
return;
case JitFrame_IonAccessorIC:
frame->changePrevType(JitFrame_Unwound_IonAccessorIC);
return;
@ -1222,13 +1232,13 @@ UpdateIonJSFrameForMinorGC(JSTracer* trc, const JitFrameIterator& frame)
}
static void
MarkBaselineStubFrame(JSTracer* trc, const JitFrameIterator& frame)
MarkJitStubFrame(JSTracer* trc, const JitFrameIterator& 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.
MOZ_ASSERT(frame.type() == JitFrame_BaselineStub);
BaselineStubFrameLayout* layout = (BaselineStubFrameLayout*)frame.fp();
MOZ_ASSERT(frame.type() == JitFrame_IonStub || frame.type() == JitFrame_BaselineStub);
JitStubFrameLayout* layout = (JitStubFrameLayout*)frame.fp();
if (ICStub* stub = layout->maybeStubPtr()) {
MOZ_ASSERT(ICStub::CanMakeCalls(stub->kind()));
@ -1523,12 +1533,13 @@ MarkJitActivation(JSTracer* trc, const JitActivationIterator& activations)
case JitFrame_BaselineJS:
frames.baselineFrame()->trace(trc, frames);
break;
case JitFrame_BaselineStub:
MarkBaselineStubFrame(trc, frames);
break;
case JitFrame_IonJS:
MarkIonJSFrame(trc, frames);
break;
case JitFrame_BaselineStub:
case JitFrame_IonStub:
MarkJitStubFrame(trc, frames);
break;
case JitFrame_Bailout:
MarkBailoutFrame(trc, frames);
break;
@ -2780,6 +2791,11 @@ JitFrameIterator::dump() const
}
break;
}
case JitFrame_IonStub:
case JitFrame_Unwound_IonStub:
fprintf(stderr, " Ion stub frame\n");
fprintf(stderr, " Frame size: %u\n", unsigned(current()->prevFrameLocalSize()));
break;
case JitFrame_Rectifier:
case JitFrame_Unwound_Rectifier:
fprintf(stderr, " Rectifier frame\n");
@ -2795,7 +2811,10 @@ JitFrameIterator::dump() const
fprintf(stderr, "Warning! Unwound JS frames are not observable.\n");
break;
case JitFrame_Exit:
fprintf(stderr, " Exit frame\n");
break;
case JitFrame_LazyLink:
fprintf(stderr, " Lazy link frame\n");
break;
};
fputc('\n', stderr);

View File

@ -894,16 +894,57 @@ ExitFrameLayout::as<LazyLinkExitFrameLayout>()
class ICStub;
class BaselineStubFrameLayout : public CommonFrameLayout
class JitStubFrameLayout : public CommonFrameLayout
{
// Info on the stack
//
// --------------------
// |JitStubFrameLayout|
// +------------------+
// | - Descriptor | => Marks end of JitFrame_IonJS
// | - returnaddres |
// +------------------+
// | - StubPtr | => First thing pushed in a stub only when the stub will do
// -------------------- a vmcall. Else we cannot have JitStubFrame. But technically
// not a member of the layout.
public:
static inline size_t Size() {
return sizeof(BaselineStubFrameLayout);
static size_t Size() {
return sizeof(JitStubFrameLayout);
}
static inline int reverseOffsetOfStubPtr() {
return -int(sizeof(void*));
}
inline ICStub* maybeStubPtr() {
uint8_t* fp = reinterpret_cast<uint8_t*>(this);
return *reinterpret_cast<ICStub**>(fp + reverseOffsetOfStubPtr());
}
};
class BaselineStubFrameLayout : public JitStubFrameLayout
{
// Info on the stack
//
// -------------------------
// |BaselineStubFrameLayout|
// +-----------------------+
// | - Descriptor | => Marks end of JitFrame_BaselineJS
// | - returnaddres |
// +-----------------------+
// | - StubPtr | => First thing pushed in a stub only when the stub will do
// +-----------------------+ a vmcall. Else we cannot have BaselineStubFrame.
// | - FramePtr | => Baseline stubs also need to push the frame ptr when doing
// ------------------------- a vmcall.
// Technically these last two variables are not part of the
// layout.
public:
static inline size_t Size() {
return sizeof(BaselineStubFrameLayout);
}
static inline int reverseOffsetOfSavedFramePtr() {
return -int(2 * sizeof(void*));
}
@ -913,10 +954,6 @@ class BaselineStubFrameLayout : public CommonFrameLayout
return *(void**)addr;
}
inline ICStub* maybeStubPtr() {
uint8_t* fp = reinterpret_cast<uint8_t*>(this);
return *reinterpret_cast<ICStub**>(fp + reverseOffsetOfStubPtr());
}
inline void setStubPtr(ICStub* stub) {
uint8_t* fp = reinterpret_cast<uint8_t*>(this);
*reinterpret_cast<ICStub**>(fp + reverseOffsetOfStubPtr()) = stub;