author | Jeff Walden <jwalden@mit.edu> |
Thu, 12 Apr 2012 18:15:26 -0700 | |
changeset 91600 | 95fd0e0254396ec64d0f568e40ad58525fa28fb8 |
parent 91599 | 4cfb132c7c16f6b76b9397091a7f54fc5e62d82a |
child 91601 | 94eb880e0cad9382f650d7437c01dd096e029099 |
push id | 8291 |
push user | mbrubeck@mozilla.com |
push date | Fri, 13 Apr 2012 14:50:38 +0000 |
treeherder | mozilla-inbound@94eb880e0cad [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | billm |
milestone | 14.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
|
js/public/Utility.h | file | annotate | diff | comparison | revisions | |
js/src/gc/Root.h | file | annotate | diff | comparison | revisions | |
js/src/jsapi.h | file | annotate | diff | comparison | revisions | |
js/src/jsstr.cpp | file | annotate | diff | comparison | revisions | |
js/src/vm/RegExpObject.cpp | file | annotate | diff | comparison | revisions |
--- a/js/public/Utility.h +++ b/js/public/Utility.h @@ -899,16 +899,50 @@ class ReentrancyGuard JS_ALWAYS_INLINE size_t RoundUpPow2(size_t x) { return size_t(1) << JS_CEILING_LOG2W(x); } } /* namespace js */ +namespace JS { + +/* + * Methods for poisoning GC heap pointer words and checking for poisoned words. + * These are in this file for use in Value methods and so forth. + * + * If the moving GC hazard analysis is in use and detects a non-rooted stack + * pointer to a GC thing, one byte of that pointer is poisoned to refer to an + * invalid location. For both 32 bit and 64 bit systems, the fourth byte of the + * pointer is overwritten, to reduce the likelihood of accidentally changing + * a live integer value. + */ + +inline void PoisonPtr(uintptr_t *v) +{ +#if defined(JSGC_ROOT_ANALYSIS) && defined(DEBUG) + uint8_t *ptr = (uint8_t *) v + 3; + *ptr = JS_FREE_PATTERN; +#endif +} + +template <typename T> +inline bool IsPoisonedPtr(T *v) +{ +#if defined(JSGC_ROOT_ANALYSIS) && defined(DEBUG) + uint32_t mask = uintptr_t(v) & 0xff000000; + return mask == uint32_t(JS_FREE_PATTERN << 24); +#else + return false; +#endif +} + +} + #endif /* defined(__cplusplus) */ /* * This is SpiderMonkey's equivalent to |nsMallocSizeOfFun|. */ typedef size_t(*JSMallocSizeOfFun)(const void *p); /* sixgill annotation defines */
--- a/js/src/gc/Root.h +++ b/js/src/gc/Root.h @@ -37,16 +37,18 @@ * * ***** END LICENSE BLOCK ***** */ #ifndef jsgc_root_h__ #define jsgc_root_h__ #include "jspubtd.h" +#include "js/Utility.h" + #ifdef __cplusplus namespace JS { /* * Moving GC Stack Rooting * * A moving GC may change the physical location of GC allocated things, even @@ -279,49 +281,58 @@ class SkipRoot }; /* Make a local variable which stays rooted throughout its lifetime. */ template <typename T> class RootedVar { public: RootedVar(JSContext *cx) - : ptr(RootMethods<T>::initial()), root(cx, &ptr) + : ptr(RootMethods<T>::initial()), root(cx, &ptr) {} RootedVar(JSContext *cx, T initial) - : ptr(initial), root(cx, &ptr) + : ptr(initial), root(cx, &ptr) {} - RootedVar() MOZ_DELETE; - RootedVar(const RootedVar &) MOZ_DELETE; - operator T () const { return ptr; } T operator ->() const { return ptr; } T * address() { return &ptr; } const T * address() const { return &ptr; } T & reference() { return ptr; } T raw() { return ptr; } + /* + * This method is only necessary due to an obscure C++98 requirement (that + * there be an accessible, usable copy constructor when passing a temporary + * to an implicitly-called constructor for use with a const-ref parameter). + * (Head spinning yet?) We can remove this when we build the JS engine + * with -std=c++11. + */ + operator Handle<T> () const { return Handle<T>(*this); } + T & operator =(T value) { JS_ASSERT(!RootMethods<T>::poisoned(value)); ptr = value; return ptr; } T & operator =(const RootedVar &value) { ptr = value; return ptr; } private: T ptr; Root<T> root; + + RootedVar() MOZ_DELETE; + RootedVar(const RootedVar &) MOZ_DELETE; }; template <typename T> template <typename S> inline Handle<T>::Handle(const RootedVar<S> &root) { ptr = reinterpret_cast<const T *>(root.address()); }
--- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -213,46 +213,16 @@ inline Anchor<T>::~Anchor() * NB: there is a Anchor<Value>::~Anchor() specialization below. */ volatile T sink; sink = hold; } #endif /* defined(__GNUC__) */ /* - * Methods for poisoning GC heap pointer words and checking for poisoned words. - * These are in this file for use in Value methods and so forth. - * - * If the moving GC hazard analysis is in use and detects a non-rooted stack - * pointer to a GC thing, one byte of that pointer is poisoned to refer to an - * invalid location. For both 32 bit and 64 bit systems, the fourth byte of the - * pointer is overwritten, to reduce the likelihood of accidentally changing - * a live integer value. - */ - -inline void PoisonPtr(uintptr_t *v) -{ -#if defined(JSGC_ROOT_ANALYSIS) && defined(DEBUG) - uint8_t *ptr = (uint8_t *) v + 3; - *ptr = JS_FREE_PATTERN; -#endif -} - -template <typename T> -inline bool IsPoisonedPtr(T *v) -{ -#if defined(JSGC_ROOT_ANALYSIS) && defined(DEBUG) - uint32_t mask = uintptr_t(v) & 0xff000000; - return mask == uint32_t(JS_FREE_PATTERN << 24); -#else - return false; -#endif -} - -/* * JS::Value is the C++ interface for a single JavaScript Engine value. * A few general notes on JS::Value: * * - JS::Value has setX() and isX() members for X in * * { Int32, Double, String, Boolean, Undefined, Null, Object, Magic } * * JS::Value also contains toX() for each of the non-singleton types.
--- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -2389,17 +2389,18 @@ class SplitMatchResult { void setResult(size_t length, size_t endIndex) { length_ = length; endIndex_ = endIndex; } }; template<class Matcher> static JSObject * -SplitHelper(JSContext *cx, Handle<JSLinearString*> str, uint32_t limit, Matcher splitMatch, TypeObject *type) +SplitHelper(JSContext *cx, Handle<JSLinearString*> str, uint32_t limit, const Matcher &splitMatch, + TypeObject *type) { size_t strLength = str->length(); SplitMatchResult result; /* Step 11. */ if (strLength == 0) { if (!splitMatch(cx, str, 0, &result)) return NULL; @@ -2530,17 +2531,18 @@ class SplitRegExpMatcher RegExpShared &re; RegExpStatics *res; public: SplitRegExpMatcher(RegExpShared &re, RegExpStatics *res) : re(re), res(res) {} static const bool returnsCaptures = true; - bool operator()(JSContext *cx, JSLinearString *str, size_t index, SplitMatchResult *result) + bool operator()(JSContext *cx, JSLinearString *str, size_t index, + SplitMatchResult *result) const { Value rval = UndefinedValue(); const jschar *chars = str->chars(); size_t length = str->length(); if (!ExecuteRegExp(cx, res, re, str, chars, length, &index, RegExpTest, &rval)) return false; if (!rval.isTrue()) { result->setFailure(); @@ -2560,17 +2562,17 @@ class SplitStringMatcher public: SplitStringMatcher(JSContext *cx, JSLinearString *sep) : sep(cx, sep) {} static const bool returnsCaptures = false; - bool operator()(JSContext *cx, JSLinearString *str, size_t index, SplitMatchResult *res) + bool operator()(JSContext *cx, JSLinearString *str, size_t index, SplitMatchResult *res) const { JS_ASSERT(index == 0 || index < str->length()); const jschar *chars = str->chars(); int match = StringMatch(chars + index, str->length() - index, sep->chars(), sep->length()); if (match == -1) res->setFailure(); else
--- a/js/src/vm/RegExpObject.cpp +++ b/js/src/vm/RegExpObject.cpp @@ -125,17 +125,17 @@ RegExpObjectBuilder::clone(Handle<RegExp * the clone -- if the |RegExpStatics| provides more flags we'll * need a different |RegExpShared|. */ RegExpStatics *res = cx->regExpStatics(); RegExpFlag origFlags = other->getFlags(); RegExpFlag staticsFlags = res->getFlags(); if ((origFlags & staticsFlags) != staticsFlags) { RegExpFlag newFlags = RegExpFlag(origFlags | staticsFlags); - return build(RootedVar<JSLinearString*>(cx, other->getSource()), newFlags); + return build(RootedVar<JSAtom *>(cx, other->getSource()), newFlags); } RegExpGuard g; if (!other->getShared(cx, &g)) return NULL; return build(RootedVarAtom(cx, other->getSource()), *g); }