mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1008421 - Remove JSString::parent. r=luke
--HG-- extra : rebase_source : d624662d22bdb11c2cc992138daff081729805c5
This commit is contained in:
parent
98c9f31d64
commit
6974cfa696
@ -87,7 +87,7 @@ JSString::validateLength(js::ThreadSafeContext *maybecx, size_t length)
|
||||
MOZ_ALWAYS_INLINE void
|
||||
JSRope::init(js::ThreadSafeContext *cx, JSString *left, JSString *right, size_t length)
|
||||
{
|
||||
d.lengthAndFlags = buildLengthAndFlags(length, ROPE_FLAGS);
|
||||
d.u0.lengthAndFlags = buildLengthAndFlags(length, ROPE_FLAGS);
|
||||
d.u1.left = left;
|
||||
d.s.u2.right = right;
|
||||
js::StringWriteBarrierPost(cx, &d.u1.left);
|
||||
@ -122,7 +122,7 @@ JSDependentString::init(js::ThreadSafeContext *cx, JSLinearString *base, const j
|
||||
size_t length)
|
||||
{
|
||||
JS_ASSERT(!js::IsPoisonedPtr(base));
|
||||
d.lengthAndFlags = buildLengthAndFlags(length, DEPENDENT_FLAGS);
|
||||
d.u0.lengthAndFlags = buildLengthAndFlags(length, DEPENDENT_FLAGS);
|
||||
d.u1.chars = chars;
|
||||
d.s.u2.base = base;
|
||||
js::StringWriteBarrierPost(cx, reinterpret_cast<JSString **>(&d.s.u2.base));
|
||||
@ -185,7 +185,7 @@ JSString::markBase(JSTracer *trc)
|
||||
MOZ_ALWAYS_INLINE void
|
||||
JSFlatString::init(const jschar *chars, size_t length)
|
||||
{
|
||||
d.lengthAndFlags = buildLengthAndFlags(length, FIXED_FLAGS);
|
||||
d.u0.lengthAndFlags = buildLengthAndFlags(length, FIXED_FLAGS);
|
||||
d.u1.chars = chars;
|
||||
}
|
||||
|
||||
@ -229,7 +229,7 @@ JSInlineString::new_(js::ThreadSafeContext *cx)
|
||||
MOZ_ALWAYS_INLINE jschar *
|
||||
JSInlineString::init(size_t length)
|
||||
{
|
||||
d.lengthAndFlags = buildLengthAndFlags(length, FIXED_FLAGS);
|
||||
d.u0.lengthAndFlags = buildLengthAndFlags(length, FIXED_FLAGS);
|
||||
d.u1.chars = d.inlineStorage;
|
||||
JS_ASSERT(lengthFits(length) || (isFatInline() && JSFatInlineString::lengthFits(length)));
|
||||
return d.inlineStorage;
|
||||
@ -238,7 +238,7 @@ JSInlineString::init(size_t length)
|
||||
MOZ_ALWAYS_INLINE void
|
||||
JSInlineString::resetLength(size_t length)
|
||||
{
|
||||
d.lengthAndFlags = buildLengthAndFlags(length, FIXED_FLAGS);
|
||||
d.u0.lengthAndFlags = buildLengthAndFlags(length, FIXED_FLAGS);
|
||||
JS_ASSERT(lengthFits(length) || (isFatInline() && JSFatInlineString::lengthFits(length)));
|
||||
}
|
||||
|
||||
@ -254,7 +254,7 @@ JSExternalString::init(const jschar *chars, size_t length, const JSStringFinaliz
|
||||
{
|
||||
JS_ASSERT(fin);
|
||||
JS_ASSERT(fin->finalize);
|
||||
d.lengthAndFlags = buildLengthAndFlags(length, FIXED_FLAGS);
|
||||
d.u0.lengthAndFlags = buildLengthAndFlags(length, FIXED_FLAGS);
|
||||
d.u1.chars = chars;
|
||||
d.s.u2.externalFinalizer = fin;
|
||||
}
|
||||
|
@ -231,8 +231,7 @@ JSRope::flattenInternal(ExclusiveContext *maybecx)
|
||||
* To avoid maintaining a stack, tree nodes are mutated to indicate how many
|
||||
* times they have been visited. Since ropes can be dags, a node may be
|
||||
* encountered multiple times during traversal. However, step 3 above leaves
|
||||
* a valid dependent string, so everything works out. This algorithm is
|
||||
* homomorphic to marking code.
|
||||
* a valid dependent string, so everything works out.
|
||||
*
|
||||
* While ropes avoid all sorts of quadratic cases with string
|
||||
* concatenation, they can't help when ropes are immediately flattened.
|
||||
@ -260,6 +259,14 @@ JSRope::flattenInternal(ExclusiveContext *maybecx)
|
||||
JSString *str = this;
|
||||
jschar *pos;
|
||||
|
||||
/*
|
||||
* JSString::flattenData is a tagged pointer to the parent node.
|
||||
* The tag indicates what to do when we return to the parent.
|
||||
*/
|
||||
static const uintptr_t Tag_Mask = 0x3;
|
||||
static const uintptr_t Tag_FinishNode = 0x0;
|
||||
static const uintptr_t Tag_VisitRightChild = 0x1;
|
||||
|
||||
/* Find the left most string, containing the first string. */
|
||||
JSRope *leftMostRope = this;
|
||||
while (leftMostRope->leftChild()->isRope())
|
||||
@ -273,16 +280,16 @@ JSRope::flattenInternal(ExclusiveContext *maybecx)
|
||||
* Simulate a left-most traversal from the root to leftMost->leftChild()
|
||||
* via first_visit_node
|
||||
*/
|
||||
JS_ASSERT(str->isRope());
|
||||
while (str != leftMostRope) {
|
||||
JS_ASSERT(str->isRope());
|
||||
if (b == WithIncrementalBarrier) {
|
||||
JSString::writeBarrierPre(str->d.u1.left);
|
||||
JSString::writeBarrierPre(str->d.s.u2.right);
|
||||
}
|
||||
JSString *child = str->d.u1.left;
|
||||
JS_ASSERT(child->isRope());
|
||||
str->d.u1.chars = left.chars();
|
||||
child->d.s.u3.parent = str;
|
||||
child->d.lengthAndFlags = 0x200;
|
||||
child->d.u0.flattenData = uintptr_t(str) | Tag_VisitRightChild;
|
||||
str = child;
|
||||
}
|
||||
if (b == WithIncrementalBarrier) {
|
||||
@ -292,10 +299,10 @@ JSRope::flattenInternal(ExclusiveContext *maybecx)
|
||||
str->d.u1.chars = left.chars();
|
||||
wholeCapacity = capacity;
|
||||
wholeChars = const_cast<jschar *>(left.chars());
|
||||
size_t bits = left.d.lengthAndFlags;
|
||||
size_t bits = left.d.u0.lengthAndFlags;
|
||||
pos = wholeChars + (bits >> LENGTH_SHIFT);
|
||||
JS_STATIC_ASSERT(!(EXTENSIBLE_FLAGS & DEPENDENT_FLAGS));
|
||||
left.d.lengthAndFlags = bits ^ (EXTENSIBLE_FLAGS | DEPENDENT_FLAGS);
|
||||
left.d.u0.lengthAndFlags = bits ^ (EXTENSIBLE_FLAGS | DEPENDENT_FLAGS);
|
||||
left.d.s.u2.base = (JSLinearString *)this; /* will be true on exit */
|
||||
StringWriteBarrierPostRemove(maybecx, &left.d.u1.left);
|
||||
StringWriteBarrierPost(maybecx, (JSString **)&left.d.s.u2.base);
|
||||
@ -317,8 +324,8 @@ JSRope::flattenInternal(ExclusiveContext *maybecx)
|
||||
str->d.u1.chars = pos;
|
||||
StringWriteBarrierPostRemove(maybecx, &str->d.u1.left);
|
||||
if (left.isRope()) {
|
||||
left.d.s.u3.parent = str; /* Return to this when 'left' done, */
|
||||
left.d.lengthAndFlags = 0x200; /* but goto visit_right_child. */
|
||||
/* Return to this node when 'left' done, then goto visit_right_child. */
|
||||
left.d.u0.flattenData = uintptr_t(str) | Tag_VisitRightChild;
|
||||
str = &left;
|
||||
goto first_visit_node;
|
||||
}
|
||||
@ -329,8 +336,8 @@ JSRope::flattenInternal(ExclusiveContext *maybecx)
|
||||
visit_right_child: {
|
||||
JSString &right = *str->d.s.u2.right;
|
||||
if (right.isRope()) {
|
||||
right.d.s.u3.parent = str; /* Return to this node when 'right' done, */
|
||||
right.d.lengthAndFlags = 0x300; /* but goto finish_node. */
|
||||
/* Return to this node when 'right' done, then goto finish_node. */
|
||||
right.d.u0.flattenData = uintptr_t(str) | Tag_FinishNode;
|
||||
str = &right;
|
||||
goto first_visit_node;
|
||||
}
|
||||
@ -342,21 +349,21 @@ JSRope::flattenInternal(ExclusiveContext *maybecx)
|
||||
if (str == this) {
|
||||
JS_ASSERT(pos == wholeChars + wholeLength);
|
||||
*pos = '\0';
|
||||
str->d.lengthAndFlags = buildLengthAndFlags(wholeLength, EXTENSIBLE_FLAGS);
|
||||
str->d.u0.lengthAndFlags = buildLengthAndFlags(wholeLength, EXTENSIBLE_FLAGS);
|
||||
str->d.u1.chars = wholeChars;
|
||||
str->d.s.u2.capacity = wholeCapacity;
|
||||
StringWriteBarrierPostRemove(maybecx, &str->d.u1.left);
|
||||
StringWriteBarrierPostRemove(maybecx, &str->d.s.u2.right);
|
||||
return &this->asFlat();
|
||||
}
|
||||
size_t progress = str->d.lengthAndFlags;
|
||||
str->d.lengthAndFlags = buildLengthAndFlags(pos - str->d.u1.chars, DEPENDENT_FLAGS);
|
||||
uintptr_t flattenData = str->d.u0.flattenData;
|
||||
str->d.u0.lengthAndFlags = buildLengthAndFlags(pos - str->d.u1.chars, DEPENDENT_FLAGS);
|
||||
str->d.s.u2.base = (JSLinearString *)this; /* will be true on exit */
|
||||
StringWriteBarrierPost(maybecx, (JSString **)&str->d.s.u2.base);
|
||||
str = str->d.s.u3.parent;
|
||||
if (progress == 0x200)
|
||||
str = (JSString *)(flattenData & ~Tag_Mask);
|
||||
if ((flattenData & Tag_Mask) == Tag_VisitRightChild)
|
||||
goto visit_right_child;
|
||||
JS_ASSERT(progress == 0x300);
|
||||
JS_ASSERT((flattenData & Tag_Mask) == Tag_FinishNode);
|
||||
goto finish_node;
|
||||
}
|
||||
}
|
||||
@ -465,7 +472,7 @@ JSDependentString::undepend(ExclusiveContext *cx)
|
||||
* Transform *this into an undepended string so 'base' will remain rooted
|
||||
* for the benefit of any other dependent string that depends on *this.
|
||||
*/
|
||||
d.lengthAndFlags = buildLengthAndFlags(n, UNDEPENDED_FLAGS);
|
||||
d.u0.lengthAndFlags = buildLengthAndFlags(n, UNDEPENDED_FLAGS);
|
||||
|
||||
return &this->asFlat();
|
||||
}
|
||||
|
@ -136,7 +136,10 @@ class JSString : public js::gc::BarrieredCell<JSString>
|
||||
/* Fields only apply to string types commented on the right. */
|
||||
struct Data
|
||||
{
|
||||
size_t lengthAndFlags; /* JSString */
|
||||
union {
|
||||
size_t lengthAndFlags; /* JSString */
|
||||
uintptr_t flattenData; /* JSRope (temporary while flattening) */
|
||||
} u0;
|
||||
union {
|
||||
const jschar *chars; /* JSLinearString */
|
||||
JSString *left; /* JSRope */
|
||||
@ -150,10 +153,6 @@ class JSString : public js::gc::BarrieredCell<JSString>
|
||||
size_t capacity; /* JSFlatString (extensible) */
|
||||
const JSStringFinalizer *externalFinalizer;/* JSExternalString */
|
||||
} u2;
|
||||
union {
|
||||
JSString *parent; /* JSRope (temporary) */
|
||||
size_t reserved; /* may use for bug 615290 */
|
||||
} u3;
|
||||
} s;
|
||||
};
|
||||
} d;
|
||||
@ -252,12 +251,12 @@ class JSString : public js::gc::BarrieredCell<JSString>
|
||||
|
||||
MOZ_ALWAYS_INLINE
|
||||
size_t length() const {
|
||||
return d.lengthAndFlags >> LENGTH_SHIFT;
|
||||
return d.u0.lengthAndFlags >> LENGTH_SHIFT;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE
|
||||
bool empty() const {
|
||||
return d.lengthAndFlags <= FLAGS_MASK;
|
||||
return d.u0.lengthAndFlags <= FLAGS_MASK;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -299,7 +298,7 @@ class JSString : public js::gc::BarrieredCell<JSString>
|
||||
|
||||
MOZ_ALWAYS_INLINE
|
||||
bool isRope() const {
|
||||
return (d.lengthAndFlags & FLAGS_MASK) == ROPE_FLAGS;
|
||||
return (d.u0.lengthAndFlags & FLAGS_MASK) == ROPE_FLAGS;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE
|
||||
@ -321,7 +320,7 @@ class JSString : public js::gc::BarrieredCell<JSString>
|
||||
|
||||
MOZ_ALWAYS_INLINE
|
||||
bool isDependent() const {
|
||||
return (d.lengthAndFlags & FLAGS_MASK) == DEPENDENT_FLAGS;
|
||||
return (d.u0.lengthAndFlags & FLAGS_MASK) == DEPENDENT_FLAGS;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE
|
||||
@ -343,7 +342,7 @@ class JSString : public js::gc::BarrieredCell<JSString>
|
||||
|
||||
MOZ_ALWAYS_INLINE
|
||||
bool isExtensible() const {
|
||||
return (d.lengthAndFlags & FLAGS_MASK) == EXTENSIBLE_FLAGS;
|
||||
return (d.u0.lengthAndFlags & FLAGS_MASK) == EXTENSIBLE_FLAGS;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE
|
||||
@ -376,17 +375,17 @@ class JSString : public js::gc::BarrieredCell<JSString>
|
||||
|
||||
MOZ_ALWAYS_INLINE
|
||||
bool isUndepended() const {
|
||||
return (d.lengthAndFlags & FLAGS_MASK) == UNDEPENDED_FLAGS;
|
||||
return (d.u0.lengthAndFlags & FLAGS_MASK) == UNDEPENDED_FLAGS;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE
|
||||
bool isAtom() const {
|
||||
return d.lengthAndFlags & ATOM_BIT;
|
||||
return d.u0.lengthAndFlags & ATOM_BIT;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE
|
||||
bool isPermanentAtom() const {
|
||||
return (d.lengthAndFlags & FLAGS_MASK) == PERMANENT_ATOM_FLAGS;
|
||||
return (d.u0.lengthAndFlags & FLAGS_MASK) == PERMANENT_ATOM_FLAGS;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE
|
||||
@ -399,7 +398,7 @@ class JSString : public js::gc::BarrieredCell<JSString>
|
||||
|
||||
inline bool hasBase() const {
|
||||
JS_STATIC_ASSERT((DEPENDENT_FLAGS | JS_BIT(1)) == UNDEPENDED_FLAGS);
|
||||
return d.lengthAndFlags & HAS_BASE_BIT;
|
||||
return d.u0.lengthAndFlags & HAS_BASE_BIT;
|
||||
}
|
||||
|
||||
inline JSLinearString *base() const;
|
||||
@ -417,7 +416,7 @@ class JSString : public js::gc::BarrieredCell<JSString>
|
||||
/* Offsets for direct field from jit code. */
|
||||
|
||||
static size_t offsetOfLengthAndFlags() {
|
||||
return offsetof(JSString, d.lengthAndFlags);
|
||||
return offsetof(JSString, d.u0.lengthAndFlags);
|
||||
}
|
||||
|
||||
static size_t offsetOfChars() {
|
||||
@ -594,11 +593,11 @@ class JSFlatString : public JSLinearString
|
||||
* operation changes the string to the JSAtom type, in place.
|
||||
*/
|
||||
MOZ_ALWAYS_INLINE JSAtom *morphAtomizedStringIntoAtom() {
|
||||
d.lengthAndFlags = buildLengthAndFlags(length(), ATOM_BIT);
|
||||
d.u0.lengthAndFlags = buildLengthAndFlags(length(), ATOM_BIT);
|
||||
return &asAtom();
|
||||
}
|
||||
MOZ_ALWAYS_INLINE JSAtom *morphAtomizedStringIntoPermanentAtom() {
|
||||
d.lengthAndFlags = buildLengthAndFlags(length(), PERMANENT_ATOM_FLAGS);
|
||||
d.u0.lengthAndFlags = buildLengthAndFlags(length(), PERMANENT_ATOM_FLAGS);
|
||||
return &asAtom();
|
||||
}
|
||||
|
||||
@ -740,13 +739,13 @@ class JSAtom : public JSFlatString
|
||||
|
||||
MOZ_ALWAYS_INLINE
|
||||
bool isPermanent() const {
|
||||
return d.lengthAndFlags & PERMANENT_BIT;
|
||||
return d.u0.lengthAndFlags & PERMANENT_BIT;
|
||||
}
|
||||
|
||||
// Transform this atom into a permanent atom. This is only done during
|
||||
// initialization of the runtime.
|
||||
MOZ_ALWAYS_INLINE void morphIntoPermanentAtom() {
|
||||
d.lengthAndFlags = buildLengthAndFlags(length(), PERMANENT_ATOM_FLAGS);
|
||||
d.u0.lengthAndFlags = buildLengthAndFlags(length(), PERMANENT_ATOM_FLAGS);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
Loading…
Reference in New Issue
Block a user