Bug 616562 - speed up JSString::isStatic (r=njn)

--HG--
extra : rebase_source : 9f0b553b8ab54bfbbd5290ba936581bda8bb40ec
This commit is contained in:
Luke Wagner 2011-03-14 13:55:55 -07:00
parent a3b82fb97c
commit 8d021fe786
16 changed files with 119 additions and 157 deletions

View File

@ -11,28 +11,28 @@ BEGIN_TEST(testIntString_bug515273)
EVAL("'1';", v.addr());
JSString *str = JSVAL_TO_STRING(v.value());
CHECK(JSString::isStatic(str));
CHECK(JSString::isGCThingStatic(str) && str->isStaticAtom());
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(str), "1"));
EVAL("'42';", v.addr());
str = JSVAL_TO_STRING(v.value());
CHECK(JSString::isStatic(str));
CHECK(JSString::isGCThingStatic(str) && str->isStaticAtom());
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(str), "42"));
EVAL("'111';", v.addr());
str = JSVAL_TO_STRING(v.value());
CHECK(JSString::isStatic(str));
CHECK(JSString::isGCThingStatic(str) && str->isStaticAtom());
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(str), "111"));
/* Test other types of static strings. */
EVAL("'a';", v.addr());
str = JSVAL_TO_STRING(v.value());
CHECK(JSString::isStatic(str));
CHECK(JSString::isGCThingStatic(str) && str->isStaticAtom());
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(str), "a"));
EVAL("'bc';", v.addr());
str = JSVAL_TO_STRING(v.value());
CHECK(JSString::isStatic(str));
CHECK(JSString::isGCThingStatic(str) && str->isStaticAtom());
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(str), "bc"));
return true;

View File

@ -5284,7 +5284,7 @@ JS_NewStringCopyZ(JSContext *cx, const char *s)
JS_PUBLIC_API(JSBool)
JS_StringHasBeenInterned(JSString *str)
{
return str->isAtomized();
return str->isAtom();
}
JS_PUBLIC_API(JSString *)
@ -5385,14 +5385,14 @@ JS_GetStringCharsAndLength(JSContext *cx, JSString *str, size_t *plength)
JS_PUBLIC_API(const jschar *)
JS_GetInternedStringChars(JSString *str)
{
JS_ASSERT(str->isAtomized());
JS_ASSERT(str->isAtom());
return str->flatChars();
}
JS_PUBLIC_API(const jschar *)
JS_GetInternedStringCharsAndLength(JSString *str, size_t *plength)
{
JS_ASSERT(str->isAtomized());
JS_ASSERT(str->isAtom());
*plength = str->flatLength();
return str->flatChars();
}

View File

@ -462,7 +462,7 @@ js_AtomizeString(JSContext *cx, JSString *strArg, uintN flags)
JS_ASSERT(!(flags & ~(ATOM_PINNED|ATOM_INTERNED|ATOM_TMPSTR|ATOM_NOCOPY)));
JS_ASSERT_IF(flags & ATOM_NOCOPY, flags & ATOM_TMPSTR);
if (strArg->isAtomized())
if (strArg->isAtom())
return STRING_TO_ATOM(strArg);
JSLinearString *str = strArg->ensureLinear(cx);

View File

@ -58,7 +58,7 @@
#define ATOM_NOCOPY 0x4 /* don't copy atom string bytes */
#define ATOM_TMPSTR 0x8 /* internal, to avoid extra string */
#define STRING_TO_ATOM(str) (JS_ASSERT(str->isAtomized()), \
#define STRING_TO_ATOM(str) (JS_ASSERT(str->isAtom()), \
(JSAtom *)str)
#define ATOM_TO_STRING(atom) (atom)
#define ATOM_TO_JSVAL(atom) STRING_TO_JSVAL(ATOM_TO_STRING(atom))

View File

@ -61,7 +61,7 @@ js_ValueToAtom(JSContext *cx, const js::Value &v, JSAtom **atomp)
*/
if (v.isString()) {
str = v.toString();
if (str->isAtomized()) {
if (str->isAtom()) {
*atomp = STRING_TO_ATOM(str);
return true;
}

View File

@ -555,7 +555,7 @@ class CompartmentChecker
}
void check(JSString *str) {
if (!JSString::isStatic(str) && !str->isAtomized())
if (!str->isAtom())
check(str->asCell()->compartment());
}

View File

@ -200,8 +200,8 @@ JSCompartment::wrap(JSContext *cx, Value *vp)
if (vp->isString()) {
JSString *str = vp->toString();
/* Static strings do not have to be wrapped. */
if (JSString::isStatic(str))
/* Static atoms do not have to be wrapped. */
if (str->isStaticAtom())
return true;
/* If the string is already in this compartment, we are done. */
@ -209,7 +209,7 @@ JSCompartment::wrap(JSContext *cx, Value *vp)
return true;
/* If the string is an atom, we don't have to copy. */
if (str->isAtomized()) {
if (str->isAtom()) {
JS_ASSERT(str->asCell()->compartment() == cx->runtime->atomsCompartment);
return true;
}

View File

@ -496,7 +496,7 @@ AllocateArena(JSContext *cx, unsigned thingKind)
JS_FRIEND_API(bool)
IsAboutToBeFinalized(JSContext *cx, void *thing)
{
if (JSString::isStatic(thing))
if (JSString::isGCThingStatic(thing))
return false;
JS_ASSERT(cx);
@ -1436,7 +1436,7 @@ gc_root_traversal(JSTracer *trc, const RootEntry &entry)
}
if (ptr) {
if (!JSString::isStatic(ptr)) {
if (!JSString::isGCThingStatic(ptr)) {
bool root_points_to_gcArenaList = false;
JSCompartment **c = trc->context->runtime->compartments.begin();
for (; c != trc->context->runtime->compartments.end(); ++c) {
@ -1685,7 +1685,7 @@ MarkRuntime(JSTracer *trc)
}
}
if (JSString::isStatic(thing))
if (JSString::isGCThingStatic(thing))
continue;
if (!reinterpret_cast<Cell *>(thing)->isMarked()) {
@ -1854,7 +1854,7 @@ void
js_FinalizeStringRT(JSRuntime *rt, JSString *str)
{
JS_RUNTIME_UNMETER(rt, liveStrings);
JS_ASSERT(!JSString::isStatic(str));
JS_ASSERT(!str->isStaticAtom());
JS_ASSERT(!str->isRope());
if (str->isDependent()) {
@ -2322,7 +2322,7 @@ MarkAndSweepCompartment(JSContext *cx, JSCompartment *comp, JSGCInvocationKind g
* so that any attempt to allocate a GC-thing from a finalizer will fail,
* rather than nest badly and leave the unmarked newborn to be swept.
*
* We first sweep atom state so we can use js_IsAboutToBeFinalized on
* We first sweep atom state so we can use IsAboutToBeFinalized on
* JSString held in a hashtable to check if the hashtable entry can be
* freed. Note that even after the entry is freed, JSObject finalizers can
* continue to access the corresponding JSString* assuming that they are
@ -2367,7 +2367,7 @@ MarkAndSweepCompartment(JSContext *cx, JSCompartment *comp, JSGCInvocationKind g
/*
* Destroy arenas after we finished the sweeping so finalizers can safely
* use js_IsAboutToBeFinalized().
* use IsAboutToBeFinalized().
*/
ExpireGCChunks(rt);
TIMESTAMP(sweepDestroyEnd);
@ -2443,7 +2443,7 @@ MarkAndSweep(JSContext *cx, JSGCInvocationKind gckind GCTIMER_PARAM)
* so that any attempt to allocate a GC-thing from a finalizer will fail,
* rather than nest badly and leave the unmarked newborn to be swept.
*
* We first sweep atom state so we can use js_IsAboutToBeFinalized on
* We first sweep atom state so we can use IsAboutToBeFinalized on
* JSString held in a hashtable to check if the hashtable entry can be
* freed. Note that even after the entry is freed, JSObject finalizers can
* continue to access the corresponding JSString* assuming that they are
@ -2504,7 +2504,7 @@ MarkAndSweep(JSContext *cx, JSGCInvocationKind gckind GCTIMER_PARAM)
/*
* Destroy arenas after we finished the sweeping so finalizers can safely
* use js_IsAboutToBeFinalized().
* use IsAboutToBeFinalized().
*/
ExpireGCChunks(rt);
TIMESTAMP(sweepDestroyEnd);

View File

@ -536,7 +536,7 @@ static inline uint32
GetGCThingTraceKind(void *thing)
{
JS_ASSERT(thing);
if (JSString::isStatic(thing))
if (JSString::isGCThingStatic(thing))
return JSTRACE_STRING;
Cell *cell = reinterpret_cast<Cell *>(thing);
return GetFinalizableTraceKind(cell->arena()->header()->thingKind);

View File

@ -233,7 +233,7 @@ static inline void
MarkString(JSTracer *trc, JSString *str)
{
JS_ASSERT(str);
if (JSString::isStatic(str))
if (str->isStaticAtom())
return;
JS_ASSERT(GetArena<JSString>((Cell *)str)->assureThingIsAligned((JSString *)str));
Mark(trc, str);
@ -420,7 +420,7 @@ NonRopeTypedMarker(JSString *str)
/* N.B. The base of a dependent string is not necessarily flat. */
JS_ASSERT(!str->isRope());
while (!JSString::isStatic(str) &&
while (!str->isStaticAtom() &&
str->asCell()->markIfUnmarked() &&
str->isDependent()) {
str = str->dependentBase();
@ -436,7 +436,7 @@ TypedMarker(JSTracer *trc, JSString *str)
{
using namespace detail;
JS_ASSERT(!JSString::isStatic(str));
JS_ASSERT(!str->isStaticAtom());
if (!str->isRope()) {
NonRopeTypedMarker(str);
return;
@ -450,7 +450,7 @@ TypedMarker(JSTracer *trc, JSString *str)
*/
JSString *parent = NULL;
first_visit_node: {
JS_ASSERT(!JSString::isStatic(str));
JS_ASSERT(!str->isStaticAtom());
if (!str->asCell()->markIfUnmarked())
goto finish_node;
JSString *left = str->ropeLeft();
@ -501,7 +501,7 @@ MarkAtomRange(JSTracer *trc, size_t len, JSAtom **vec, const char *name)
if (JSAtom *atom = vec[i]) {
JS_SET_TRACING_INDEX(trc, name, i);
JSString *str = ATOM_TO_STRING(atom);
if (!JSString::isStatic(str))
if (!str->isStaticAtom())
Mark(trc, str);
}
}
@ -523,7 +523,7 @@ MarkId(JSTracer *trc, jsid id)
{
if (JSID_IS_STRING(id)) {
JSString *str = JSID_TO_STRING(id);
if (!JSString::isStatic(str))
if (!str->isStaticAtom())
Mark(trc, str);
}
else if (JS_UNLIKELY(JSID_IS_OBJECT(id)))

View File

@ -243,9 +243,9 @@ JS_DEFINE_CALLINFO_2(extern, BOOL, js_Flatten, CONTEXT, STRING, 0, nanojit::ACCS
JSString * JS_FASTCALL
js_ConcatStrings(JSContext *cx, JSString *left, JSString *right)
{
JS_ASSERT_IF(!JSString::isStatic(left) && !left->isAtomized(),
JS_ASSERT_IF(!left->isStaticAtom() && !left->isAtom(),
left->asCell()->compartment() == cx->compartment);
JS_ASSERT_IF(!JSString::isStatic(right) && !right->isAtomized(),
JS_ASSERT_IF(!right->isStaticAtom() && !right->isAtom(),
right->asCell()->compartment() == cx->compartment);
size_t leftLen = left->length();
@ -2025,7 +2025,7 @@ FindReplaceLength(JSContext *cx, RegExpStatics *res, ReplaceData &rdata, size_t
JSString *str = match.toString();
JSAtom *atom;
if (str->isAtomized()) {
if (str->isAtom()) {
atom = STRING_TO_ATOM(str);
} else {
atom = js_AtomizeString(cx, str, 0);
@ -3229,7 +3229,7 @@ static JSFunctionSpec string_methods[] = {
* place in the header.
*/
#define R(c) { \
BUILD_LENGTH_AND_FLAGS(1, JSString::FLAT | JSString::ATOMIZED), \
BUILD_LENGTH_AND_FLAGS(1, JSString::STATIC_ATOM_FLAGS), \
{ (jschar *)(((char *)(unitStringTable + (c))) + \
offsetof(JSString, inlineStorage)) }, \
{ {(c), 0x00} } }
@ -3289,7 +3289,7 @@ const jschar JSString::fromSmallChar[] = { R6(0) };
* second character.
*/
#define R(c) { \
BUILD_LENGTH_AND_FLAGS(2, JSString::FLAT | JSString::ATOMIZED), \
BUILD_LENGTH_AND_FLAGS(2, JSString::STATIC_ATOM_FLAGS), \
{ (jschar *)(((char *)(length2StringTable + (c))) + \
offsetof(JSString, inlineStorage)) }, \
{ {FROM_SMALL_CHAR((c) >> 6), FROM_SMALL_CHAR((c) & 0x3F), 0x00} } }
@ -3322,7 +3322,7 @@ __attribute__ ((aligned (8)))
* correct location of the int string.
*/
#define R(c) { \
BUILD_LENGTH_AND_FLAGS(3, JSString::FLAT | JSString::ATOMIZED), \
BUILD_LENGTH_AND_FLAGS(3, JSString::STATIC_ATOM_FLAGS), \
{ (jschar *)(((char *)(hundredStringTable + ((c) - 100))) + \
offsetof(JSString, inlineStorage)) }, \
{ {((c) / 100) + '0', ((c) / 10 % 10) + '0', ((c) % 10) + '0', 0x00} } }

View File

@ -128,7 +128,7 @@ struct JSString
* Not private because we want to be able to use static initializers for
* them. Don't use these directly! FIXME bug 614459.
*/
size_t lengthAndFlags; /* in all strings */
uint32 lengthAndFlags; /* in all strings */
union {
const jschar *chars; /* in non-rope strings */
JSString *left; /* in rope strings */
@ -149,33 +149,33 @@ struct JSString
size_t externalStringType; /* in external strings */
};
/* FIXME: document proper in bug 613457. */
/*
* The lengthAndFlags field in string headers has data arranged in the
* following way:
*
* [ length (bits 4-31) ][ flags (bits 2-3) ][ type (bits 0-1) ]
*
* The length is packed in lengthAndFlags, even in string types that don't
* need 3 other fields, to make the length check simpler.
*
* When the string type is FLAT, the flags can contain ATOMIZED or
* EXTENSIBLE.
* Generous but sane length bound; the "-1" is there for comptibility with
* OOM tests.
*/
static const size_t TYPE_FLAGS_MASK = JS_BITMASK(4);
static const size_t LENGTH_SHIFT = 4;
static const size_t LENGTH_SHIFT = 4;
static const size_t FLAGS_MASK = JS_BITMASK(LENGTH_SHIFT);
static const size_t MAX_LENGTH = JS_BIT(32 - LENGTH_SHIFT) - 1;
static const size_t TYPE_MASK = JS_BITMASK(2);
static const size_t FLAT = 0x0;
static const size_t DEPENDENT = 0x1;
static const size_t ROPE = 0x2;
static const size_t LINEAR_MASK = JS_BITMASK(1);
static const size_t LINEAR_FLAGS = 0x0;
/* Allow checking 1 bit for dependent/rope strings. */
static const size_t DEPENDENT_BIT = JS_BIT(0);
static const size_t ROPE_BIT = JS_BIT(1);
static const size_t FLAT_MASK = JS_BITMASK(2);
static const size_t FLAT_FLAGS = 0x0;
static const size_t ATOMIZED = JS_BIT(2);
static const size_t EXTENSIBLE = JS_BIT(3);
static const size_t ATOM_MASK = JS_BITMASK(3);
static const size_t ATOM_FLAGS = 0x0;
static const size_t STATIC_ATOM_MASK = JS_BITMASK(4);
static const size_t STATIC_ATOM_FLAGS = 0x0;
static const size_t ROPE_BIT = JS_BIT(0);
static const size_t DEPENDENT_BIT = JS_BIT(1);
static const size_t PLAIN_FLAGS = JS_BIT(2);
static const size_t EXTENSIBLE_FLAGS = JS_BIT(2) | JS_BIT(3);
static const size_t NON_STATIC_ATOM = JS_BIT(3);
size_t buildLengthAndFlags(size_t length, size_t flags) {
return (length << LENGTH_SHIFT) | flags;
@ -189,32 +189,42 @@ struct JSString
return reinterpret_cast<js::gc::FreeCell *>(this);
}
/*
* Generous but sane length bound; the "-1" is there for comptibility with
* OOM tests.
*/
static const size_t MAX_LENGTH = (1 << 28) - 1;
JS_ALWAYS_INLINE bool isDependent() const {
return lengthAndFlags & DEPENDENT_BIT;
}
JS_ALWAYS_INLINE bool isFlat() const {
return (lengthAndFlags & TYPE_MASK) == FLAT;
}
JS_ALWAYS_INLINE bool isExtensible() const {
JS_ASSERT_IF(lengthAndFlags & EXTENSIBLE, isFlat());
return lengthAndFlags & EXTENSIBLE;
}
JS_ALWAYS_INLINE bool isAtomized() const {
JS_ASSERT_IF(lengthAndFlags & ATOMIZED, isFlat());
return lengthAndFlags & ATOMIZED;
JS_ALWAYS_INLINE bool isLinear() const {
return (lengthAndFlags & LINEAR_MASK) == LINEAR_FLAGS;
}
JS_ALWAYS_INLINE bool isRope() const {
return lengthAndFlags & ROPE_BIT;
bool rope = lengthAndFlags & ROPE_BIT;
JS_ASSERT_IF(rope, (lengthAndFlags & FLAGS_MASK) == ROPE_BIT);
return rope;
}
JS_ALWAYS_INLINE bool isFlat() const {
return (lengthAndFlags & FLAT_MASK) == FLAT_FLAGS;
}
JS_ALWAYS_INLINE bool isDependent() const {
bool dependent = lengthAndFlags & DEPENDENT_BIT;
JS_ASSERT_IF(dependent, (lengthAndFlags & FLAGS_MASK) == DEPENDENT_BIT);
return dependent;
}
JS_ALWAYS_INLINE bool isAtom() const {
bool atomized = (lengthAndFlags & ATOM_MASK) == ATOM_FLAGS;
JS_ASSERT_IF(atomized, isFlat());
return atomized;
}
JS_ALWAYS_INLINE bool isStaticAtom() const {
return (lengthAndFlags & FLAGS_MASK) == STATIC_ATOM_FLAGS;
}
JS_ALWAYS_INLINE bool isPlain() const {
return (lengthAndFlags & FLAGS_MASK) == PLAIN_FLAGS;
}
JS_ALWAYS_INLINE bool isExtensible() const {
return (lengthAndFlags & FLAGS_MASK) == EXTENSIBLE_FLAGS;
}
JS_ALWAYS_INLINE size_t length() const {
@ -222,7 +232,7 @@ struct JSString
}
JS_ALWAYS_INLINE bool empty() const {
return lengthAndFlags <= TYPE_FLAGS_MASK;
return lengthAndFlags <= FLAGS_MASK;
}
/* This can fail by returning null and reporting an error on cx. */
@ -241,8 +251,8 @@ struct JSString
JS_ALWAYS_INLINE void initFlatNotTerminated(jschar *chars, size_t length) {
JS_ASSERT(length <= MAX_LENGTH);
JS_ASSERT(!isStatic(this));
lengthAndFlags = buildLengthAndFlags(length, FLAT);
JS_ASSERT(!isGCThingStatic(this));
lengthAndFlags = buildLengthAndFlags(length, PLAIN_FLAGS);
u.chars = chars;
}
@ -255,16 +265,16 @@ struct JSString
JS_ALWAYS_INLINE void initShortString(const jschar *chars, size_t length) {
JS_ASSERT(length <= MAX_LENGTH);
JS_ASSERT(chars >= inlineStorage && chars < (jschar *)(this + 2));
JS_ASSERT(!isStatic(this));
lengthAndFlags = buildLengthAndFlags(length, FLAT);
JS_ASSERT(!isGCThingStatic(this));
lengthAndFlags = buildLengthAndFlags(length, PLAIN_FLAGS);
u.chars = chars;
}
JS_ALWAYS_INLINE void initFlatExtensible(jschar *chars, size_t length, size_t cap) {
JS_ASSERT(length <= MAX_LENGTH);
JS_ASSERT(chars[length] == jschar(0));
JS_ASSERT(!isStatic(this));
lengthAndFlags = buildLengthAndFlags(length, FLAT | EXTENSIBLE);
JS_ASSERT(!isGCThingStatic(this));
lengthAndFlags = buildLengthAndFlags(length, EXTENSIBLE_FLAGS);
u.chars = chars;
s.capacity = cap;
}
@ -285,9 +295,8 @@ struct JSString
}
inline void flatSetAtomized() {
JS_ASSERT(isFlat());
JS_ASSERT(!isStatic(this));
lengthAndFlags |= ATOMIZED;
JS_ASSERT(isFlat() && !isExtensible() && !isGCThingStatic(this));
lengthAndFlags = buildLengthAndFlags(length(), NON_STATIC_ATOM);
}
inline void flatClearExtensible() {
@ -296,8 +305,10 @@ struct JSString
* memory, so we cannot unconditionally apply the mask.
*/
JS_ASSERT(isFlat());
if (lengthAndFlags & EXTENSIBLE)
lengthAndFlags &= ~EXTENSIBLE;
if (isExtensible()) {
JS_ASSERT(!isAtom());
lengthAndFlags = buildLengthAndFlags(length(), PLAIN_FLAGS);
}
}
/*
@ -305,11 +316,11 @@ struct JSString
* The caller still needs to pass base for GC purposes.
*/
inline void initDependent(JSString *base, const jschar *chars, size_t length) {
JS_ASSERT(!isStatic(this));
JS_ASSERT(!isGCThingStatic(this));
JS_ASSERT(base->isFlat());
JS_ASSERT(chars >= base->flatChars() && chars < base->flatChars() + base->length());
JS_ASSERT(length <= base->length() - (chars - base->flatChars()));
lengthAndFlags = buildLengthAndFlags(length, DEPENDENT);
lengthAndFlags = buildLengthAndFlags(length, DEPENDENT_BIT);
u.chars = chars;
s.base = base;
}
@ -339,7 +350,7 @@ struct JSString
/* Rope-related initializers and accessors. */
inline void initRopeNode(JSString *left, JSString *right, size_t length) {
JS_ASSERT(left->length() + right->length() == length);
lengthAndFlags = buildLengthAndFlags(length, ROPE);
lengthAndFlags = buildLengthAndFlags(length, ROPE_BIT);
u.left = left;
s.right = right;
}
@ -356,7 +367,7 @@ struct JSString
inline void finishTraversalConversion(JSString *base, const jschar *baseBegin, const jschar *end) {
JS_ASSERT(baseBegin <= u.chars && u.chars <= end);
lengthAndFlags = buildLengthAndFlags(end - u.chars, DEPENDENT);
lengthAndFlags = buildLengthAndFlags(end - u.chars, DEPENDENT_BIT);
s.base = base;
}
@ -368,10 +379,6 @@ struct JSString
return reinterpret_cast<JSLinearString *>(this);
}
bool isLinear() const {
return !isRope();
}
JSLinearString *assertIsLinear() {
JS_ASSERT(isLinear());
return reinterpret_cast<JSLinearString *>(this);
@ -416,7 +423,7 @@ struct JSString
return true;
}
static inline bool isStatic(void *ptr) {
static inline bool isGCThingStatic(void *ptr) {
return isUnitString(ptr) || isLength2String(ptr) || isHundredString(ptr);
}

View File

@ -311,7 +311,7 @@ JSString::lookupStaticString(const jschar *chars, size_t length)
inline void
JSString::finalize(JSContext *cx) {
JS_ASSERT(!JSString::isStatic(this));
JS_ASSERT(!isStaticAtom());
JS_RUNTIME_UNMETER(cx->runtime, liveStrings);
if (isDependent()) {
JS_RUNTIME_UNMETER(cx->runtime, liveDependentStrings);
@ -328,7 +328,7 @@ JSString::finalize(JSContext *cx) {
inline void
JSShortString::finalize(JSContext *cx)
{
JS_ASSERT(!JSString::isStatic(&mHeader));
JS_ASSERT(!mHeader.isStaticAtom());
JS_ASSERT(mHeader.isFlat());
JS_RUNTIME_UNMETER(cx->runtime, liveStrings);
}
@ -337,7 +337,7 @@ inline void
JSExternalString::finalize(JSContext *cx)
{
JS_ASSERT(unsigned(externalStringType) < JS_ARRAY_LENGTH(str_finalizers));
JS_ASSERT(!isStatic(this));
JS_ASSERT(!isStaticAtom());
JS_ASSERT(isFlat());
JS_RUNTIME_UNMETER(cx->runtime, liveStrings);

View File

@ -12515,7 +12515,7 @@ static inline bool
RootedStringToId(JSContext* cx, JSString** namep, jsid* idp)
{
JSString* name = *namep;
if (name->isAtomized()) {
if (name->isAtom()) {
*idp = INTERNED_STRING_TO_JSID(name);
return true;
}

View File

@ -404,24 +404,23 @@ class EqualityCompiler : public BaseCompiler
RegisterID tmp = ic.tempReg;
/* Test if lhs/rhs are atomized. */
Imm32 atomizedFlags(JSString::FLAT | JSString::ATOMIZED);
/* JSString::isAtom === (lengthAndFlags & ATOM_MASK == 0) */
JS_STATIC_ASSERT(JSString::ATOM_FLAGS == 0);
Imm32 atomMask(JSString::ATOM_MASK);
masm.load32(Address(lvr.dataReg(), JSString::offsetOfLengthAndFlags()), tmp);
masm.and32(Imm32(JSString::TYPE_FLAGS_MASK), tmp);
Jump lhsNotAtomized = masm.branch32(Assembler::NotEqual, tmp, atomizedFlags);
Jump lhsNotAtomized = masm.branchTest32(Assembler::NonZero, tmp, atomMask);
linkToStub(lhsNotAtomized);
if (!rvr.isConstant()) {
masm.load32(Address(rvr.dataReg(), JSString::offsetOfLengthAndFlags()), tmp);
masm.and32(Imm32(JSString::TYPE_FLAGS_MASK), tmp);
Jump rhsNotAtomized = masm.branch32(Assembler::NotEqual, tmp, atomizedFlags);
Jump rhsNotAtomized = masm.branchTest32(Assembler::NonZero, tmp, atomMask);
linkToStub(rhsNotAtomized);
}
if (rvr.isConstant()) {
JSString *str = rvr.value().toString();
JS_ASSERT(str->isAtomized());
JS_ASSERT(str->isAtom());
Jump test = masm.branchPtr(ic.cond, lvr.dataReg(), ImmPtr(str));
linkTrue(test);
} else {

View File

@ -1,44 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Terry Hayes <thayes@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
[scriptable, uuid(8de811f0-1dd2-11b2-8bf1-e9aa324984b2)]
interface nsISSLStatusProvider : nsISupports {
readonly attribute nsISupports SSLStatus;
};