Bug 1493441 - Make XDRState::codeChars(char16_t*, size_t) perform buffer-alignment before acting so that its callers don't have to do so manually. r=tcampbell
authorJeff Walden <jwalden@mit.edu>
Tue, 25 Sep 2018 16:35:43 -0400
changeset 496834 acd510f0152a9c4624fafa7eceda552be1a6c376
parent 496833 d912f4d60ea470d68383eb2f011993700bf4f7bf
child 496835 f7c32e7abf7293b99c6d1941af6e15ebc3119d5c
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstcampbell
bugs1493441
milestone64.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 1493441 - Make XDRState::codeChars(char16_t*, size_t) perform buffer-alignment before acting so that its callers don't have to do so manually. r=tcampbell
js/src/vm/JSAtom.cpp
js/src/vm/Xdr.cpp
js/src/vm/Xdr.h
--- a/js/src/vm/JSAtom.cpp
+++ b/js/src/vm/JSAtom.cpp
@@ -1062,22 +1062,16 @@ js::XDRAtom(XDRState<mode>* xdr, Mutable
 
     MOZ_TRY(xdr->codeUint32(&lengthAndEncoding));
 
     if (mode == XDR_DECODE) {
         length = lengthAndEncoding >> 1;
         latin1 = lengthAndEncoding & 0x1;
     }
 
-    // We need to align the string in the XDR buffer such that we can avoid
-    // non-align loads of 16bits characters.
-    if (!latin1) {
-        MOZ_TRY(xdr->codeAlign(sizeof(char16_t)));
-    }
-
     if (mode == XDR_ENCODE) {
         JS::AutoCheckCannotGC nogc;
         if (latin1) {
             return xdr->codeChars(const_cast<JS::Latin1Char*>(atomp->latin1Chars(nogc)),
                                   length);
         }
         return xdr->codeChars(const_cast<char16_t*>(atomp->twoByteChars(nogc)), length);
     }
@@ -1095,17 +1089,23 @@ js::XDRAtom(XDRState<mode>* xdr, Mutable
             chars = reinterpret_cast<const Latin1Char*>(ptr);
         }
         atom = AtomizeChars(cx, chars, length);
     } else {
 #if MOZ_LITTLE_ENDIAN
         /* Directly access the little endian chars in the XDR buffer. */
         const char16_t* chars = nullptr;
         if (length) {
-            const uint8_t *ptr;
+            // In the |mode == XDR_ENCODE| case above, when |nchars > 0|,
+            // |XDRState::codeChars(char16_t*, size_t nchars)| will align the
+            // buffer.  This code never calls that function, but it must act
+            // *as if* it had, so we must align manually here.
+            MOZ_TRY(xdr->codeAlign(sizeof(char16_t)));
+
+            const uint8_t* ptr;
             size_t nbyte = length * sizeof(char16_t);
             MOZ_TRY(xdr->peekData(&ptr, nbyte));
             MOZ_ASSERT(reinterpret_cast<uintptr_t>(ptr) % sizeof(char16_t) == 0,
                        "non-aligned buffer during JSAtom decoding");
             chars = reinterpret_cast<const char16_t*>(ptr);
         }
         atom = AtomizeChars(cx, chars, length);
 #else
--- a/js/src/vm/Xdr.cpp
+++ b/js/src/vm/Xdr.cpp
@@ -93,16 +93,20 @@ XDRState<mode>::codeChars(Utf8Unit* unit
 
 template<XDRMode mode>
 XDRResult
 XDRState<mode>::codeChars(char16_t* chars, size_t nchars)
 {
     if (nchars == 0) {
         return Ok();
     }
+
+    // Align the buffer to avoid unaligned loads.
+    MOZ_TRY(codeAlign(sizeof(char16_t)));
+
     size_t nbytes = nchars * sizeof(char16_t);
     if (mode == XDR_ENCODE) {
         uint8_t* ptr = buf.write(nbytes);
         if (!ptr) {
             return fail(JS::TranscodeResult_Throw);
         }
         mozilla::NativeEndian::copyAndSwapToLittleEndian(ptr, chars, nchars);
     } else {
--- a/js/src/vm/Xdr.h
+++ b/js/src/vm/Xdr.h
@@ -487,16 +487,18 @@ class XDRState : public XDRCoderBase
             *sp = reinterpret_cast<const char*>(ptr);
         }
         return Ok();
     }
 
     XDRResult codeChars(JS::Latin1Char* chars, size_t nchars);
     XDRResult codeChars(mozilla::Utf8Unit* units, size_t nchars);
 
+    // If |nchars > 0|, this calls |codeAlign(sizeof(char16_t))| so callers
+    // don't have to.
     XDRResult codeChars(char16_t* chars, size_t nchars);
 
     XDRResult codeFunction(JS::MutableHandleFunction objp,
                            HandleScriptSourceObject sourceObject = nullptr);
     XDRResult codeScript(MutableHandleScript scriptp);
 };
 
 using XDREncoder = XDRState<XDR_ENCODE>;