Bug 787703. r=terrence

This commit is contained in:
Jason Orendorff 2012-10-25 17:43:25 -04:00
parent de4a6659f1
commit 8960a647d5
3 changed files with 36 additions and 0 deletions

View File

@ -498,6 +498,34 @@ struct RootMethods<T *>
static bool poisoned(T *v) { return IsPoisonedPtr(v); }
};
#if !defined(JSGC_ROOT_ANALYSIS) && !defined(JSGC_USE_EXACT_ROOTING)
template <typename T>
struct RootSink {
static inline void dispose(const T &) {}
};
/*
* The *alleged* killer whale hack (see JS::Anchor<T> in jsapi.h) duplicated
* here because using JS::Anchor causes clang to emit bad instructions.
*
* In exact-gc builds, Rooted<T> always keeps the T reachable. In non-exact-gc
* builds, it does not, but conservative scanning usually picks up the slack.
* However in the case where the Rooted pointer is no longer used, but some
* subobject or malloc'd memory with the same lifetime may be used,
* conservative scanning can fail. JSStableString's chars() method makes it
* particularly attractive to use that way, so we use some voodoo to convince
* the compiler to keep the string pointer on the stack for the full lifetime
* of the Rooted<JSStableString *>.
*/
template <>
struct RootSink<JSStableString *> {
static void dispose(JSStableString *ptr) {
JSStableString * volatile sink;
sink = ptr;
}
};
#endif
template <typename T>
class RootedBase {};
@ -587,6 +615,8 @@ class Rooted : public RootedBase<T>
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
JS_ASSERT(*stack == this);
*stack = prev;
#else
RootSink<T>::dispose(ptr);
#endif
}

View File

@ -0,0 +1,5 @@
eval(" function x() {}" + Array(241).join(" "));
for (var i = 0; i < 100; i++) {
gczeal(4, 2);
String(x);
}

View File

@ -203,6 +203,7 @@ typedef struct JSTracer JSTracer;
#ifdef __cplusplus
class JSFlatString;
class JSStableString; // long story
class JSString;
#else
typedef struct JSFlatString JSFlatString;