Bug 1032726 part 2 - Make GetArrayIndexFromId work with Latin1 strings. r=bz,terrence
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 02 Jul 2014 15:45:02 +0200
changeset 191906 60e70f9d98cbfab0ffd04576261b1193e02a0c1c
parent 191905 487f6944bbdfae677dc09f6ffe1b2b311791382e
child 191907 219b6b2a4a29298988a0eeecb2eba9734c1917d4
push id45687
push userjandemooij@gmail.com
push dateWed, 02 Jul 2014 13:51:46 +0000
treeherdermozilla-inbound@219b6b2a4a29 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz, terrence
bugs1032726
milestone33.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
Bug 1032726 part 2 - Make GetArrayIndexFromId work with Latin1 strings. r=bz,terrence
dom/bindings/Codegen.py
dom/bindings/DOMJSProxyHandler.h
js/src/jsfriendapi.h
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -9370,17 +9370,19 @@ class CGProxyNamedOperation(CGProxySpeci
             """,
             argName=argName)
         if self.value is None:
             # We're just using 'id', and if it's an atom we can take a
             # fast path here.
             unwrapString = fill(
                 """
                 if (MOZ_LIKELY(JSID_IS_ATOM(${idName}))) {
-                  ${argName}.Rebind(js::GetAtomChars(JSID_TO_ATOM(${idName})), js::GetAtomLength(JSID_TO_ATOM(${idName})));
+                  JS::AutoCheckCannotGC nogc;
+                  JSAtom* atom = JSID_TO_ATOM(${idName});
+                  ${argName}.Rebind(js::GetTwoByteAtomChars(nogc, atom), js::GetAtomLength(atom));
                 } else {
                   nameVal = js::IdToValue(${idName});
                   $*{unwrapString}
                 }
                 """,
                 idName=idName,
                 argName=argName,
                 unwrapString=unwrapString)
--- a/dom/bindings/DOMJSProxyHandler.h
+++ b/dom/bindings/DOMJSProxyHandler.h
@@ -150,17 +150,25 @@ GetArrayIndexFromId(JSContext* cx, JS::H
   if (MOZ_LIKELY(JSID_IS_INT(id))) {
     return JSID_TO_INT(id);
   }
   if (MOZ_LIKELY(id == s_length_id)) {
     return -1;
   }
   if (MOZ_LIKELY(JSID_IS_ATOM(id))) {
     JSAtom* atom = JSID_TO_ATOM(id);
-    jschar s = *js::GetAtomChars(atom);
+    jschar s;
+    {
+      JS::AutoCheckCannotGC nogc;
+      if (js::AtomHasLatin1Chars(atom)) {
+        s = *js::GetLatin1AtomChars(nogc, atom);
+      } else {
+        s = *js::GetTwoByteAtomChars(nogc, atom);
+      }
+    }
     if (MOZ_LIKELY((unsigned)s >= 'a' && (unsigned)s <= 'z'))
       return -1;
 
     uint32_t i;
     JSLinearString* str = js::AtomToLinearString(JSID_TO_ATOM(id));
     return js::StringIsArrayIndex(str, &i) ? i : -1;
   }
   return IdToInt32(cx, id);
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -756,35 +756,52 @@ GetObjectSlotSpan(JSObject *obj);
 
 inline const JS::Value &
 GetObjectSlot(JSObject *obj, size_t slot)
 {
     JS_ASSERT(slot < GetObjectSlotSpan(obj));
     return reinterpret_cast<const shadow::Object *>(obj)->slotRef(slot);
 }
 
-inline const jschar *
-GetAtomChars(JSAtom *atom)
-{
-    using shadow::Atom;
-    Atom *atom_ = reinterpret_cast<Atom *>(atom);
-    JS_ASSERT(!(atom_->flags & Atom::LATIN1_CHARS_BIT));
-    if (atom_->flags & Atom::INLINE_CHARS_BIT) {
-        char *p = reinterpret_cast<char *>(atom);
-        return reinterpret_cast<const jschar *>(p + offsetof(Atom, inlineStorageTwoByte));
-    }
-    return atom_->nonInlineCharsTwoByte;
-}
-
 inline size_t
 GetAtomLength(JSAtom *atom)
 {
     return reinterpret_cast<shadow::Atom*>(atom)->length;
 }
 
+inline bool
+AtomHasLatin1Chars(JSAtom *atom)
+{
+    return reinterpret_cast<shadow::Atom *>(atom)->flags & shadow::Atom::LATIN1_CHARS_BIT;
+}
+
+inline const JS::Latin1Char *
+GetLatin1AtomChars(const JS::AutoCheckCannotGC &nogc, JSAtom *atom)
+{
+    MOZ_ASSERT(AtomHasLatin1Chars(atom));
+
+    using shadow::Atom;
+    Atom *atom_ = reinterpret_cast<Atom *>(atom);
+    if (atom_->flags & Atom::INLINE_CHARS_BIT)
+        return atom_->inlineStorageLatin1;
+    return atom_->nonInlineCharsLatin1;
+}
+
+inline const jschar *
+GetTwoByteAtomChars(const JS::AutoCheckCannotGC &nogc, JSAtom *atom)
+{
+    MOZ_ASSERT(!AtomHasLatin1Chars(atom));
+
+    using shadow::Atom;
+    Atom *atom_ = reinterpret_cast<Atom *>(atom);
+    if (atom_->flags & Atom::INLINE_CHARS_BIT)
+        return atom_->inlineStorageTwoByte;
+    return atom_->nonInlineCharsTwoByte;
+}
+
 inline JSLinearString *
 AtomToLinearString(JSAtom *atom)
 {
     return reinterpret_cast<JSLinearString *>(atom);
 }
 
 JS_FRIEND_API(bool)
 GetPropertyNames(JSContext *cx, JSObject *obj, unsigned flags, JS::AutoIdVector *props);