author | Kannan Vijayan <kvijayan@mozilla.com> |
Wed, 26 Sep 2012 12:05:50 -0400 | |
changeset 108150 | 5ebf745a3a40d1c489fab9fe95ad65fef8d18daf |
parent 108149 | 29fe3da0ea11d3c6a050fc6fdf2e1a1fd4c17bd7 |
child 108151 | 0450cb4ef66ab6d4f23cb6868de8c87d0e08b783 |
push id | 23539 |
push user | ryanvm@gmail.com |
push date | Wed, 26 Sep 2012 22:55:55 +0000 |
treeherder | mozilla-central@ec079fd92224 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jandem |
bugs | 790051 |
milestone | 18.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/ion/IonFrameIterator.h +++ b/js/src/ion/IonFrameIterator.h @@ -108,16 +108,17 @@ class IonFrameIterator // places the invalidated Ion script in |ionScript|. bool checkInvalidation(IonScript **ionScript) const; bool checkInvalidation() const; bool isScripted() const { return type_ == IonFrame_JS; } bool isNative() const; + bool isOOLNativeGetter() const; bool isDOMExit() const; bool isEntry() const { return type_ == IonFrame_Entry; } bool isFunctionFrame() const; bool isConstructing() const;
--- a/js/src/ion/IonFrames-inl.h +++ b/js/src/ion/IonFrames-inl.h @@ -77,21 +77,30 @@ size_t IonFrameIterator::frameSize() const { JS_ASSERT(type_ != IonFrame_Exit); return frameSize_; } // Returns the JSScript associated with the topmost Ion frame. inline JSScript * -GetTopIonJSScript(JSContext *cx) +GetTopIonJSScript(JSContext *cx, const SafepointIndex **safepointIndexOut, void **returnAddrOut) { IonFrameIterator iter(cx->runtime->ionTop); JS_ASSERT(iter.type() == IonFrame_Exit); ++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); IonJSFrameLayout *frame = static_cast<IonJSFrameLayout*>(iter.current()); switch (GetCalleeTokenTag(frame->calleeToken())) { case CalleeToken_Function: { JSFunction *fun = CalleeTokenToFunction(frame->calleeToken()); return fun->script(); } case CalleeToken_Script:
--- a/js/src/ion/IonFrames.cpp +++ b/js/src/ion/IonFrames.cpp @@ -113,16 +113,24 @@ bool IonFrameIterator::isNative() const { if (type_ != IonFrame_Exit) return false; 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 IonFrameIterator::isDOMExit() const { if (type_ != IonFrame_Exit) return false; return exitFrame()->isDomExit(); } bool @@ -525,16 +533,23 @@ MarkIonExitFrame(JSTracer *trc, const Io if (frame.isNative()) { IonNativeExitFrameLayout *native = frame.exitFrame()->nativeExit(); size_t len = native->argc() + 2; Value *vp = native->vp(); gc::MarkValueRootRange(trc, len, vp, "ion-native-args"); 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()) { IonDOMExitFrameLayout *dom = frame.exitFrame()->DOMExit(); gc::MarkObjectRoot(trc, dom->thisObjAddress(), "ion-dom-args"); if (dom->isSetterFrame()) { gc::MarkValueRoot(trc, dom->vp(), "ion-dom-args"); } else if (dom->isMethodFrame()) { IonDOMMethodExitFrameLayout *method = reinterpret_cast<IonDOMMethodExitFrameLayout *>(dom);
--- a/js/src/ion/IonFrames.h +++ b/js/src/ion/IonFrames.h @@ -252,17 +252,19 @@ MakeFrameDescriptor(uint32 frameSize, Fr #else # error "unsupported architecture" #endif namespace js { namespace ion { JSScript * -GetTopIonJSScript(JSContext *cx); +GetTopIonJSScript(JSContext *cx, + const SafepointIndex **safepointIndexOut = NULL, + void **returnAddrOut = NULL); void GetPcScript(JSContext *cx, JSScript **scriptRes, jsbytecode **pcRes); // Given a slot index, returns the offset, in bytes, of that slot from an // IonJSFrameLayout. Slot distances are uniform across architectures, however, // the distance does depend on the size of the frame header. static inline int32
--- a/js/src/ion/arm/IonFrames-arm.h +++ b/js/src/ion/arm/IonFrames-arm.h @@ -151,16 +151,17 @@ class IonOsrFrameLayout : public IonJSFr { public: static inline size_t Size() { return sizeof(IonOsrFrameLayout); } }; class IonNativeExitFrameLayout; +class IonOOLNativeGetterExitFrameLayout; class IonDOMExitFrameLayout; // this is the frame layout when we are exiting ion code, and about to enter EABI code class IonExitFrameLayout : public IonCommonFrameLayout { inline uint8 *top() { return reinterpret_cast<uint8 *>(this + 1); } @@ -187,29 +188,36 @@ class IonExitFrameLayout : public IonCom } inline bool isWrapperExit() { return footer()->function() != NULL; } inline bool isNativeExit() { return footer()->ionCode() == NULL; } + inline bool isOOLNativeGetterExit() { + return footer()->ionCode() == ION_FRAME_OOL_NATIVE_GETTER; + } inline bool isDomExit() { IonCode *code = footer()->ionCode(); return code == ION_FRAME_DOMGETTER || code == ION_FRAME_DOMSETTER || code == ION_FRAME_DOMMETHOD; } inline IonNativeExitFrameLayout *nativeExit() { // see CodeGenerator::visitCallNative JS_ASSERT(isNativeExit()); return reinterpret_cast<IonNativeExitFrameLayout *>(footer()); } + inline IonOOLNativeGetterExitFrameLayout *oolNativeGetterExit() { + JS_ASSERT(isOOLNativeGetterExit()); + return reinterpret_cast<IonOOLNativeGetterExitFrameLayout *>(footer()); + } inline IonDOMExitFrameLayout *DOMExit() { JS_ASSERT(isDomExit()); return reinterpret_cast<IonDOMExitFrameLayout *>(footer()); } }; // Cannot inherit implementa<tion since we need to extend the top of // IonExitFrameLayout. @@ -235,16 +243,46 @@ class IonNativeExitFrameLayout inline Value *vp() { return reinterpret_cast<Value*>(&loCalleeResult_); } inline uintptr_t argc() const { return argc_; } }; +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 { IonExitFooterFrame footer_; IonExitFrameLayout exit_; JSObject *thisObj; // We need to split the Value in 2 field of 32 bits, otherwise the C++ // compiler may add some padding between the fields.
--- a/js/src/ion/shared/IonFrames-shared.h +++ b/js/src/ion/shared/IonFrames-shared.h @@ -39,10 +39,11 @@ * * ***** END LICENSE BLOCK ***** */ #ifndef jsion_ionframes_shared_h__ #define jsion_ionframes_shared_h__ #define ION_FRAME_DOMGETTER ((IonCode *)0x1) #define ION_FRAME_DOMSETTER ((IonCode *)0x2) #define ION_FRAME_DOMMETHOD ((IonCode *)0x3) +#define ION_FRAME_OOL_NATIVE_GETTER ((IonCode *)0x4) #endif
--- a/js/src/ion/shared/IonFrames-x86-shared.h +++ b/js/src/ion/shared/IonFrames-x86-shared.h @@ -136,16 +136,17 @@ class IonExitFooterFrame // This should only be called for function()->outParam == Type_Handle Value *outVp() { return reinterpret_cast<Value *>(reinterpret_cast<char *>(this) - sizeof(Value)); } }; class IonNativeExitFrameLayout; +class IonOOLNativeGetterExitFrameLayout; class IonDOMExitFrameLayout; class IonExitFrameLayout : public IonCommonFrameLayout { inline uint8 *top() { return reinterpret_cast<uint8 *>(this + 1); } @@ -184,16 +185,21 @@ class IonExitFrameLayout : public IonCom code == ION_FRAME_DOMMETHOD; } inline IonNativeExitFrameLayout *nativeExit() { // see CodeGenerator::visitCallNative JS_ASSERT(isNativeExit()); 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() { JS_ASSERT(isDomExit()); return reinterpret_cast<IonDOMExitFrameLayout *>(footer()); } }; class IonNativeExitFrameLayout { @@ -218,16 +224,47 @@ class IonNativeExitFrameLayout inline Value *vp() { return reinterpret_cast<Value*>(&loCalleeResult_); } inline uintptr_t argc() const { return argc_; } }; +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 { protected: // only to silence a clang warning about unused private fields IonExitFooterFrame footer_; IonExitFrameLayout exit_; JSObject *thisObj; // We need to split the Value in 2 field of 32 bits, otherwise the C++