mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 790051 - Add IonMonkey OOLNativeGetterExitFrame to support callouts to native getters from OOL IC stubs. (r=jandem)
This commit is contained in:
parent
312412d741
commit
8adaf120df
@ -113,6 +113,7 @@ class IonFrameIterator
|
|||||||
return type_ == IonFrame_JS;
|
return type_ == IonFrame_JS;
|
||||||
}
|
}
|
||||||
bool isNative() const;
|
bool isNative() const;
|
||||||
|
bool isOOLNativeGetter() const;
|
||||||
bool isDOMExit() const;
|
bool isDOMExit() const;
|
||||||
bool isEntry() const {
|
bool isEntry() const {
|
||||||
return type_ == IonFrame_Entry;
|
return type_ == IonFrame_Entry;
|
||||||
|
@ -82,11 +82,20 @@ IonFrameIterator::frameSize() const
|
|||||||
|
|
||||||
// Returns the JSScript associated with the topmost Ion frame.
|
// Returns the JSScript associated with the topmost Ion frame.
|
||||||
inline JSScript *
|
inline JSScript *
|
||||||
GetTopIonJSScript(JSContext *cx)
|
GetTopIonJSScript(JSContext *cx, const SafepointIndex **safepointIndexOut, void **returnAddrOut)
|
||||||
{
|
{
|
||||||
IonFrameIterator iter(cx->runtime->ionTop);
|
IonFrameIterator iter(cx->runtime->ionTop);
|
||||||
JS_ASSERT(iter.type() == IonFrame_Exit);
|
JS_ASSERT(iter.type() == IonFrame_Exit);
|
||||||
++iter;
|
++iter;
|
||||||
|
|
||||||
|
// If needed, grab the safepoint index.
|
||||||
|
if (safepointIndexOut)
|
||||||
|
*safepointIndexOut = iter.safepoint();
|
||||||
|
|
||||||
|
JS_ASSERT(iter.returnAddressToFp() != NULL);
|
||||||
|
if (returnAddrOut)
|
||||||
|
*returnAddrOut = (void *) iter.returnAddressToFp();
|
||||||
|
|
||||||
JS_ASSERT(iter.type() == IonFrame_JS);
|
JS_ASSERT(iter.type() == IonFrame_JS);
|
||||||
IonJSFrameLayout *frame = static_cast<IonJSFrameLayout*>(iter.current());
|
IonJSFrameLayout *frame = static_cast<IonJSFrameLayout*>(iter.current());
|
||||||
switch (GetCalleeTokenTag(frame->calleeToken())) {
|
switch (GetCalleeTokenTag(frame->calleeToken())) {
|
||||||
|
@ -117,6 +117,14 @@ IonFrameIterator::isNative() const
|
|||||||
return exitFrame()->footer()->ionCode() == NULL;
|
return exitFrame()->footer()->ionCode() == NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
IonFrameIterator::isOOLNativeGetter() const
|
||||||
|
{
|
||||||
|
if (type_ != IonFrame_Exit)
|
||||||
|
return false;
|
||||||
|
return exitFrame()->footer()->ionCode() == ION_FRAME_OOL_NATIVE_GETTER;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
IonFrameIterator::isDOMExit() const
|
IonFrameIterator::isDOMExit() const
|
||||||
{
|
{
|
||||||
@ -530,6 +538,13 @@ MarkIonExitFrame(JSTracer *trc, const IonFrameIterator &frame)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (frame.isOOLNativeGetter()) {
|
||||||
|
IonOOLNativeGetterExitFrameLayout *oolgetter = frame.exitFrame()->oolNativeGetterExit();
|
||||||
|
gc::MarkValueRoot(trc, oolgetter->vp(), "ion-ool-getter-callee");
|
||||||
|
gc::MarkValueRoot(trc, oolgetter->vp() + 1, "ion-ool-getter-this");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (frame.isDOMExit()) {
|
if (frame.isDOMExit()) {
|
||||||
IonDOMExitFrameLayout *dom = frame.exitFrame()->DOMExit();
|
IonDOMExitFrameLayout *dom = frame.exitFrame()->DOMExit();
|
||||||
gc::MarkObjectRoot(trc, dom->thisObjAddress(), "ion-dom-args");
|
gc::MarkObjectRoot(trc, dom->thisObjAddress(), "ion-dom-args");
|
||||||
|
@ -257,7 +257,9 @@ namespace js {
|
|||||||
namespace ion {
|
namespace ion {
|
||||||
|
|
||||||
JSScript *
|
JSScript *
|
||||||
GetTopIonJSScript(JSContext *cx);
|
GetTopIonJSScript(JSContext *cx,
|
||||||
|
const SafepointIndex **safepointIndexOut = NULL,
|
||||||
|
void **returnAddrOut = NULL);
|
||||||
|
|
||||||
void
|
void
|
||||||
GetPcScript(JSContext *cx, JSScript **scriptRes, jsbytecode **pcRes);
|
GetPcScript(JSContext *cx, JSScript **scriptRes, jsbytecode **pcRes);
|
||||||
|
@ -156,6 +156,7 @@ class IonOsrFrameLayout : public IonJSFrameLayout
|
|||||||
};
|
};
|
||||||
|
|
||||||
class IonNativeExitFrameLayout;
|
class IonNativeExitFrameLayout;
|
||||||
|
class IonOOLNativeGetterExitFrameLayout;
|
||||||
class IonDOMExitFrameLayout;
|
class IonDOMExitFrameLayout;
|
||||||
|
|
||||||
// this is the frame layout when we are exiting ion code, and about to enter EABI code
|
// this is the frame layout when we are exiting ion code, and about to enter EABI code
|
||||||
@ -192,6 +193,9 @@ class IonExitFrameLayout : public IonCommonFrameLayout
|
|||||||
inline bool isNativeExit() {
|
inline bool isNativeExit() {
|
||||||
return footer()->ionCode() == NULL;
|
return footer()->ionCode() == NULL;
|
||||||
}
|
}
|
||||||
|
inline bool isOOLNativeGetterExit() {
|
||||||
|
return footer()->ionCode() == ION_FRAME_OOL_NATIVE_GETTER;
|
||||||
|
}
|
||||||
inline bool isDomExit() {
|
inline bool isDomExit() {
|
||||||
IonCode *code = footer()->ionCode();
|
IonCode *code = footer()->ionCode();
|
||||||
return
|
return
|
||||||
@ -205,6 +209,10 @@ class IonExitFrameLayout : public IonCommonFrameLayout
|
|||||||
JS_ASSERT(isNativeExit());
|
JS_ASSERT(isNativeExit());
|
||||||
return reinterpret_cast<IonNativeExitFrameLayout *>(footer());
|
return reinterpret_cast<IonNativeExitFrameLayout *>(footer());
|
||||||
}
|
}
|
||||||
|
inline IonOOLNativeGetterExitFrameLayout *oolNativeGetterExit() {
|
||||||
|
JS_ASSERT(isOOLNativeGetterExit());
|
||||||
|
return reinterpret_cast<IonOOLNativeGetterExitFrameLayout *>(footer());
|
||||||
|
}
|
||||||
inline IonDOMExitFrameLayout *DOMExit() {
|
inline IonDOMExitFrameLayout *DOMExit() {
|
||||||
JS_ASSERT(isDomExit());
|
JS_ASSERT(isDomExit());
|
||||||
return reinterpret_cast<IonDOMExitFrameLayout *>(footer());
|
return reinterpret_cast<IonDOMExitFrameLayout *>(footer());
|
||||||
@ -240,6 +248,36 @@ class IonNativeExitFrameLayout
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class IonOOLNativeGetterExitFrameLayout
|
||||||
|
{
|
||||||
|
IonExitFooterFrame footer_;
|
||||||
|
IonExitFrameLayout exit_;
|
||||||
|
|
||||||
|
// We need to split the Value into 2 fields of 32 bits, otherwise the C++
|
||||||
|
// compiler may add some padding between the fields.
|
||||||
|
uint32_t loCalleeResult_;
|
||||||
|
uint32_t hiCalleeResult_;
|
||||||
|
|
||||||
|
// The frame includes the object argument.
|
||||||
|
uint32_t loThis_;
|
||||||
|
uint32_t hiThis_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static inline size_t Size() {
|
||||||
|
return sizeof(IonOOLNativeGetterExitFrameLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t offsetOfResult() {
|
||||||
|
return offsetof(IonOOLNativeGetterExitFrameLayout, loCalleeResult_);
|
||||||
|
}
|
||||||
|
inline Value *vp() {
|
||||||
|
return reinterpret_cast<Value*>(&loCalleeResult_);
|
||||||
|
}
|
||||||
|
inline uintptr_t argc() const {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class IonDOMExitFrameLayout
|
class IonDOMExitFrameLayout
|
||||||
{
|
{
|
||||||
IonExitFooterFrame footer_;
|
IonExitFooterFrame footer_;
|
||||||
|
@ -44,5 +44,6 @@
|
|||||||
#define ION_FRAME_DOMGETTER ((IonCode *)0x1)
|
#define ION_FRAME_DOMGETTER ((IonCode *)0x1)
|
||||||
#define ION_FRAME_DOMSETTER ((IonCode *)0x2)
|
#define ION_FRAME_DOMSETTER ((IonCode *)0x2)
|
||||||
#define ION_FRAME_DOMMETHOD ((IonCode *)0x3)
|
#define ION_FRAME_DOMMETHOD ((IonCode *)0x3)
|
||||||
|
#define ION_FRAME_OOL_NATIVE_GETTER ((IonCode *)0x4)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -141,6 +141,7 @@ class IonExitFooterFrame
|
|||||||
};
|
};
|
||||||
|
|
||||||
class IonNativeExitFrameLayout;
|
class IonNativeExitFrameLayout;
|
||||||
|
class IonOOLNativeGetterExitFrameLayout;
|
||||||
class IonDOMExitFrameLayout;
|
class IonDOMExitFrameLayout;
|
||||||
|
|
||||||
class IonExitFrameLayout : public IonCommonFrameLayout
|
class IonExitFrameLayout : public IonCommonFrameLayout
|
||||||
@ -189,6 +190,11 @@ class IonExitFrameLayout : public IonCommonFrameLayout
|
|||||||
JS_ASSERT(isNativeExit());
|
JS_ASSERT(isNativeExit());
|
||||||
return reinterpret_cast<IonNativeExitFrameLayout *>(footer());
|
return reinterpret_cast<IonNativeExitFrameLayout *>(footer());
|
||||||
}
|
}
|
||||||
|
inline IonOOLNativeGetterExitFrameLayout *oolNativeGetterExit() {
|
||||||
|
// see CodeGenerator::visitCallNative
|
||||||
|
JS_ASSERT(footer()->ionCode() == ION_FRAME_OOL_NATIVE_GETTER);
|
||||||
|
return reinterpret_cast<IonOOLNativeGetterExitFrameLayout *>(footer());
|
||||||
|
}
|
||||||
inline IonDOMExitFrameLayout *DOMExit() {
|
inline IonDOMExitFrameLayout *DOMExit() {
|
||||||
JS_ASSERT(isDomExit());
|
JS_ASSERT(isDomExit());
|
||||||
return reinterpret_cast<IonDOMExitFrameLayout *>(footer());
|
return reinterpret_cast<IonDOMExitFrameLayout *>(footer());
|
||||||
@ -223,6 +229,37 @@ class IonNativeExitFrameLayout
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class IonOOLNativeGetterExitFrameLayout
|
||||||
|
{
|
||||||
|
IonExitFooterFrame footer_;
|
||||||
|
IonExitFrameLayout exit_;
|
||||||
|
|
||||||
|
// We need to split the Value into 2 fields of 32 bits, otherwise the C++
|
||||||
|
// compiler may add some padding between the fields.
|
||||||
|
uint32_t loCalleeResult_;
|
||||||
|
uint32_t hiCalleeResult_;
|
||||||
|
|
||||||
|
// The frame includes the object argument.
|
||||||
|
uint32_t loThisResult_;
|
||||||
|
uint32_t hiThisResult_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static inline size_t Size() {
|
||||||
|
return sizeof(IonOOLNativeGetterExitFrameLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t offsetOfResult() {
|
||||||
|
return offsetof(IonOOLNativeGetterExitFrameLayout, loCalleeResult_);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Value *vp() {
|
||||||
|
return reinterpret_cast<Value*>(&loCalleeResult_);
|
||||||
|
}
|
||||||
|
inline uintptr_t argc() const {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class IonDOMExitFrameLayout
|
class IonDOMExitFrameLayout
|
||||||
{
|
{
|
||||||
protected: // only to silence a clang warning about unused private fields
|
protected: // only to silence a clang warning about unused private fields
|
||||||
|
Loading…
Reference in New Issue
Block a user