Bug 943839 - Simplify Anchor and get rid of JS_AnchorPtr. r=terrence

--HG--
extra : rebase_source : f2d9e039f758b6078c57f601537effe8c7c39f82
This commit is contained in:
Jeff Walden 2013-12-02 15:43:30 -08:00
parent 3102bb964b
commit ec797804af
6 changed files with 29 additions and 29 deletions

View File

@ -93,14 +93,31 @@ class Anchor : AnchorPermitted<T>
Anchor() { } Anchor() { }
explicit Anchor(T t) { hold = t; } explicit Anchor(T t) { hold = t; }
inline ~Anchor(); inline ~Anchor();
T &get() { return hold; }
const T &get() const { return hold; }
void set(const T &t) { hold = t; }
void operator=(const T &t) { hold = t; }
void clear() { hold = 0; }
private: private:
T hold; T hold;
/*
* Rooting analysis considers use of operator= to be a use of an anchor.
* For simplicity, Anchor is treated as if it contained a GC thing, from
* construction. Thus if we had
*
* void operator=(const T &t) { hold = t; }
*
* and this code
*
* JS::Anchor<JSString*> anchor;
* stuff that could GC, producing |str|;
* anchor = str;
*
* the last line would be seen as a hazard, because the final = would "use"
* |anchor| that is a GC thing -- which could have been moved around by the
* GC. The workaround is to structure your code so that JS::Anchor is
* always constructed, living for however long the corresponding value must
* live.
*/
void operator=(const T &t) MOZ_DELETE;
Anchor(const Anchor &other) MOZ_DELETE; Anchor(const Anchor &other) MOZ_DELETE;
void operator=(const Anchor &other) MOZ_DELETE; void operator=(const Anchor &other) MOZ_DELETE;
}; };

View File

@ -954,10 +954,6 @@ class Value
data = STRING_TO_JSVAL_IMPL(str); data = STRING_TO_JSVAL_IMPL(str);
} }
void setString(const JS::Anchor<JSString *> &str) {
setString(str.get());
}
void setObject(JSObject &obj) { void setObject(JSObject &obj) {
MOZ_ASSERT(!IsPoisonedPtr(&obj)); MOZ_ASSERT(!IsPoisonedPtr(&obj));
data = OBJECT_TO_JSVAL_IMPL(&obj); data = OBJECT_TO_JSVAL_IMPL(&obj);
@ -1592,7 +1588,6 @@ class MutableValueOperations : public ValueOperations<Outer>
bool setNumber(uint32_t ui) { return value()->setNumber(ui); } bool setNumber(uint32_t ui) { return value()->setNumber(ui); }
bool setNumber(double d) { return value()->setNumber(d); } bool setNumber(double d) { return value()->setNumber(d); }
void setString(JSString *str) { this->value()->setString(str); } void setString(JSString *str) { this->value()->setString(str); }
void setString(const JS::Anchor<JSString *> &str) { this->value()->setString(str); }
void setObject(JSObject &obj) { this->value()->setObject(obj); } void setObject(JSObject &obj) { this->value()->setObject(obj); }
void setObjectOrNull(JSObject *arg) { this->value()->setObjectOrNull(arg); } void setObjectOrNull(JSObject *arg) { this->value()->setObjectOrNull(arg); }
}; };
@ -1623,7 +1618,6 @@ class HeapBase<JS::Value> : public ValueOperations<JS::Heap<JS::Value> >
void setBoolean(bool b) { setBarriered(JS::BooleanValue(b)); } void setBoolean(bool b) { setBarriered(JS::BooleanValue(b)); }
void setMagic(JSWhyMagic why) { setBarriered(JS::MagicValue(why)); } void setMagic(JSWhyMagic why) { setBarriered(JS::MagicValue(why)); }
void setString(JSString *str) { setBarriered(JS::StringValue(str)); } void setString(JSString *str) { setBarriered(JS::StringValue(str)); }
void setString(const JS::Anchor<JSString *> &str) { setBarriered(JS::StringValue(str.get())); }
void setObject(JSObject &obj) { setBarriered(JS::ObjectValue(obj)); } void setObject(JSObject &obj) { setBarriered(JS::ObjectValue(obj)); }
bool setNumber(uint32_t ui) { bool setNumber(uint32_t ui) {

View File

@ -1669,11 +1669,6 @@ JS_RemoveScriptRootRT(JSRuntime *rt, JSScript **rp)
RemoveRoot(rt, (void *)rp); RemoveRoot(rt, (void *)rp);
} }
JS_NEVER_INLINE JS_PUBLIC_API(void)
JS_AnchorPtr(void *p)
{
}
JS_PUBLIC_API(bool) JS_PUBLIC_API(bool)
JS_AddExtraGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data) JS_AddExtraGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data)
{ {

View File

@ -1987,13 +1987,6 @@ JS_RemoveObjectRootRT(JSRuntime *rt, JSObject **rp);
extern JS_PUBLIC_API(void) extern JS_PUBLIC_API(void)
JS_RemoveScriptRootRT(JSRuntime *rt, JSScript **rp); JS_RemoveScriptRootRT(JSRuntime *rt, JSScript **rp);
/*
* C-compatible version of the Anchor class. It should be called after the last
* use of the variable it protects.
*/
extern JS_NEVER_INLINE JS_PUBLIC_API(void)
JS_AnchorPtr(void *p);
/* /*
* Register externally maintained GC roots. * Register externally maintained GC roots.
* *

View File

@ -1095,11 +1095,14 @@ ArrayJoin(JSContext *cx, CallArgs &args)
return false; return false;
seplen = sepstr->length(); seplen = sepstr->length();
} else { } else {
static const jschar comma = ','; HandlePropertyName comma = cx->names().comma;
sepchars = &comma; sepstr = comma;
seplen = 1; sepchars = comma->chars();
seplen = comma->length();
} }
JS::Anchor<JSString*> anchor(sepstr);
// Step 6 is implicit in the loops below // Step 6 is implicit in the loops below
StringBuffer sb(cx); StringBuffer sb(cx);
@ -1124,9 +1127,6 @@ ArrayJoin(JSContext *cx, CallArgs &args)
return false; return false;
} }
// Ensure that sepstr stays alive longer than sepchars.
JS_AnchorPtr(sepstr);
// Step 11 // Step 11
JSString *str = sb.finishString(); JSString *str = sb.finishString();
if (!str) if (!str)

View File

@ -33,6 +33,7 @@
macro(Collator, Collator, "Collator") \ macro(Collator, Collator, "Collator") \
macro(CollatorCompareGet, CollatorCompareGet, "Intl_Collator_compare_get") \ macro(CollatorCompareGet, CollatorCompareGet, "Intl_Collator_compare_get") \
macro(columnNumber, columnNumber, "columnNumber") \ macro(columnNumber, columnNumber, "columnNumber") \
macro(comma, comma, ",") \
macro(compare, compare, "compare") \ macro(compare, compare, "compare") \
macro(configurable, configurable, "configurable") \ macro(configurable, configurable, "configurable") \
macro(construct, construct, "construct") \ macro(construct, construct, "construct") \