Bug 1496378 part 2 - Move data pointer accessors from DataViewObject/TypedArrayObject to ArrayBufferViewObject. r=jwalden
authorJan de Mooij <jdemooij@mozilla.com>
Mon, 15 Oct 2018 11:51:46 +0000
changeset 489624 1f8af7db9d96ee0e9fd4f9d4949efe3921f99290
parent 489623 87071cf93bcc0f411b0fb267fa5872aad6abab53
child 489625 e6c5e6c15848b2df293dade2084ec9a585f21c2b
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersjwalden
bugs1496378
milestone64.0a1
Bug 1496378 part 2 - Move data pointer accessors from DataViewObject/TypedArrayObject to ArrayBufferViewObject. r=jwalden Note that DataViewObject had dataPointer* methods but TypedArrayObject used viewData* for this. I used dataPointer* for consistency with ArrayBufferObject (and I like it more). Depends on D7721 Differential Revision: https://phabricator.services.mozilla.com/D7722
js/src/builtin/AtomicsObject.cpp
js/src/builtin/DataViewObject.cpp
js/src/builtin/DataViewObject.h
js/src/builtin/TestingFunctions.cpp
js/src/jit/IonBuilder.cpp
js/src/shell/OSObject.cpp
js/src/vm/ArrayBufferObject.cpp
js/src/vm/ArrayBufferObject.h
js/src/vm/Debugger.cpp
js/src/vm/SelfHosting.cpp
js/src/vm/TypeInference.cpp
js/src/vm/TypedArrayObject-inl.h
js/src/vm/TypedArrayObject.cpp
js/src/vm/TypedArrayObject.h
js/src/wasm/WasmJS.cpp
js/src/wasm/WasmModule.cpp
--- a/js/src/builtin/AtomicsObject.cpp
+++ b/js/src/builtin/AtomicsObject.cpp
@@ -201,17 +201,17 @@ js::atomics_compareExchange(JSContext* c
     }
     int32_t newCandidate;
     if (!ToInt32(cx, newv, &newCandidate)) {
         return false;
     }
 
     bool badType = false;
     int32_t result = CompareExchange(view->type(), oldCandidate, newCandidate,
-                                     view->viewDataShared(), offset, &badType);
+                                     view->dataPointerShared(), offset, &badType);
 
     if (badType) {
         return ReportBadArrayType(cx);
     }
 
     if (view->type() == Scalar::Uint32) {
         r.setNumber((double)(uint32_t)result);
     } else {
@@ -232,17 +232,17 @@ js::atomics_load(JSContext* cx, unsigned
     if (!GetSharedTypedArray(cx, objv, &view)) {
         return false;
     }
     uint32_t offset;
     if (!GetTypedArrayIndex(cx, idxv, view, &offset)) {
         return false;
     }
 
-    SharedMem<void*> viewData = view->viewDataShared();
+    SharedMem<void*> viewData = view->dataPointerShared();
     switch (view->type()) {
       case Scalar::Uint8: {
         uint8_t v = jit::AtomicOperations::loadSeqCst(viewData.cast<uint8_t*>() + offset);
         r.setInt32(v);
         return true;
       }
       case Scalar::Int8: {
         int8_t v = jit::AtomicOperations::loadSeqCst(viewData.cast<uint8_t*>() + offset);
@@ -352,17 +352,17 @@ ExchangeOrStore(JSContext* cx, unsigned 
     }
     double integerValue;
     if (!ToInteger(cx, valv, &integerValue)) {
         return false;
     }
 
     bool badType = false;
     int32_t result = ExchangeOrStore<op>(view->type(), JS::ToInt32(integerValue),
-                                         view->viewDataShared(), offset, &badType);
+                                         view->dataPointerShared(), offset, &badType);
 
     if (badType) {
         return ReportBadArrayType(cx);
     }
 
     if (op == DoStore) {
         r.setNumber(integerValue);
     } else if (view->type() == Scalar::Uint32) {
@@ -398,17 +398,17 @@ AtomicsBinop(JSContext* cx, HandleValue 
     if (!GetTypedArrayIndex(cx, idxv, view, &offset)) {
         return false;
     }
     int32_t numberValue;
     if (!ToInt32(cx, valv, &numberValue)) {
         return false;
     }
 
-    SharedMem<void*> viewData = view->viewDataShared();
+    SharedMem<void*> viewData = view->dataPointerShared();
     switch (view->type()) {
       case Scalar::Int8: {
         int8_t v = (int8_t)numberValue;
         r.setInt32(T::operate(viewData.cast<int8_t*>() + offset, v));
         return true;
       }
       case Scalar::Uint8: {
         uint8_t v = (uint8_t)numberValue;
@@ -695,17 +695,17 @@ js::atomics_wait(JSContext* cx, unsigned
             }
         }
     }
 
     Rooted<SharedArrayBufferObject*> sab(cx, view->bufferShared());
     // The computation will not overflow because range checks have been
     // performed.
     uint32_t byteOffset = offset * sizeof(int32_t) +
-                          (view->viewDataShared().cast<uint8_t*>().unwrap(/* arithmetic */) -
+                          (view->dataPointerShared().cast<uint8_t*>().unwrap(/* arithmetic */) -
                            sab->dataPointerShared().unwrap(/* arithmetic */));
 
     switch (atomics_wait_impl(cx, sab->rawBufferObject(), byteOffset, value, timeout)) {
       case FutexThread::WaitResult::NotEqual:
         r.setString(cx->names().futexNotEqual);
         return true;
       case FutexThread::WaitResult::OK:
         r.setString(cx->names().futexOK);
@@ -789,17 +789,17 @@ js::atomics_notify(JSContext* cx, unsign
         }
         count = dcount > INT64_MAX ? -1 : int64_t(dcount);
     }
 
     Rooted<SharedArrayBufferObject*> sab(cx, view->bufferShared());
     // The computation will not overflow because range checks have been
     // performed.
     uint32_t byteOffset = offset * sizeof(int32_t) +
-                          (view->viewDataShared().cast<uint8_t*>().unwrap(/* arithmetic */) -
+                          (view->dataPointerShared().cast<uint8_t*>().unwrap(/* arithmetic */) -
                            sab->dataPointerShared().unwrap(/* arithmetic */));
 
     r.setNumber(double(atomics_notify_impl(sab->rawBufferObject(), byteOffset, count)));
 
     return true;
 }
 
 /* static */ bool
--- a/js/src/builtin/DataViewObject.cpp
+++ b/js/src/builtin/DataViewObject.cpp
@@ -71,20 +71,17 @@ DataViewObject::create(JSContext* cx, ui
         obj->setIsSharedMemory();
     }
 
     obj->setFixedSlot(BYTEOFFSET_SLOT, Int32Value(byteOffset));
     obj->setFixedSlot(LENGTH_SLOT, Int32Value(byteLength));
     obj->setFixedSlot(BUFFER_SLOT, ObjectValue(*arrayBuffer));
 
     SharedMem<uint8_t*> ptr = arrayBuffer->dataPointerEither();
-    // A pointer to raw shared memory is exposed through the private slot.  This
-    // is safe so long as getPrivate() is not used willy-nilly.  It is wrapped in
-    // other accessors in TypedArrayObject.h.
-    obj->initPrivate(ptr.unwrap(/*safe - see above*/) + byteOffset);
+    obj->initDataPointer(ptr + byteOffset);
 
     // Include a barrier if the data view's data pointer is in the nursery, as
     // is done for typed arrays.
     if (!IsInsideNursery(obj) && cx->nursery().isInside(ptr)) {
         // Shared buffer data should never be nursery-allocated, so we
         // need to fail here if isSharedMemory.  However, mmap() can
         // place a SharedArrayRawBuffer up against the bottom end of a
         // nursery chunk, and a zero-length buffer will erroneously be
--- a/js/src/builtin/DataViewObject.h
+++ b/js/src/builtin/DataViewObject.h
@@ -83,34 +83,16 @@ class DataViewObject : public ArrayBuffe
     uint32_t byteLength() const {
         return byteLengthValue(this).toInt32();
     }
 
     ArrayBufferObjectMaybeShared& arrayBufferEither() const {
         return bufferValue(this).toObject().as<ArrayBufferObjectMaybeShared>();
     }
 
-    SharedMem<void*> dataPointerEither() const {
-        void *p = getPrivate();
-        if (isSharedMemory()) {
-            return SharedMem<void*>::shared(p);
-        }
-        return SharedMem<void*>::unshared(p);
-    }
-
-    void* dataPointerUnshared() const {
-        MOZ_ASSERT(!isSharedMemory());
-        return getPrivate();
-    }
-
-    void* dataPointerShared() const {
-        MOZ_ASSERT(isSharedMemory());
-        return getPrivate();
-    }
-
     static bool construct(JSContext* cx, unsigned argc, Value* vp);
 
     static bool getInt8Impl(JSContext* cx, const CallArgs& args);
     static bool fun_getInt8(JSContext* cx, unsigned argc, Value* vp);
 
     static bool getUint8Impl(JSContext* cx, const CallArgs& args);
     static bool fun_getUint8(JSContext* cx, unsigned argc, Value* vp);
 
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -769,17 +769,17 @@ WasmTextToBinary(JSContext* cx, unsigned
         return false;
     }
 
     RootedObject binary(cx, JS_NewUint8Array(cx, bytes.length()));
     if (!binary) {
         return false;
     }
 
-    memcpy(binary->as<TypedArrayObject>().viewDataUnshared(), bytes.begin(), bytes.length());
+    memcpy(binary->as<TypedArrayObject>().dataPointerUnshared(), bytes.begin(), bytes.length());
 
     if (!withOffsets) {
         args.rval().setObject(*binary);
         return true;
     }
 
     RootedObject obj(cx, JS_NewPlainObject(cx));
     if (!obj) {
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -9170,17 +9170,17 @@ IonBuilder::addTypedArrayLengthAndData(M
         if (objConst->type() == MIRType::Object) {
             tarr = &objConst->toObject();
         }
     } else if (TemporaryTypeSet* types = obj->resultTypeSet()) {
         tarr = types->maybeSingleton();
     }
 
     if (tarr) {
-        SharedMem<void*> data = tarr->as<TypedArrayObject>().viewDataEither();
+        SharedMem<void*> data = tarr->as<TypedArrayObject>().dataPointerEither();
         // Bug 979449 - Optimistically embed the elements and use TI to
         //              invalidate if we move them.
         bool isTenured = !tarr->runtimeFromMainThread()->gc.nursery().isInside(data);
         if (isTenured && tarr->isSingleton()) {
             // The 'data' pointer of TypedArrayObject can change in rare circumstances
             // (ArrayBufferObject::changeContents).
             TypeSet::ObjectKey* tarrKey = TypeSet::ObjectKey::get(tarr);
             if (!tarrKey->unknownProperties()) {
--- a/js/src/shell/OSObject.cpp
+++ b/js/src/shell/OSObject.cpp
@@ -216,17 +216,17 @@ FileAsTypedArray(JSContext* cx, JS::Hand
                 // buffer.)
                 pathname = JS_EncodeStringToUTF8(cx, pathnameStr);
                 if (!pathname) {
                     return nullptr;
                 }
                 JS_ReportErrorUTF8(cx, "can't read %s: shared memory buffer", pathname.get());
                 return nullptr;
             }
-            char* buf = static_cast<char*>(ta.viewDataUnshared());
+            char* buf = static_cast<char*>(ta.dataPointerUnshared());
             size_t cc = fread(buf, 1, len, file);
             if (cc != len) {
                 if (ptrdiff_t(cc) < 0) {
                     /*
                      * Use Latin1 variant here because the encoding of the return
                      * value of strerror function can be non-UTF-8.
                      */
                     JS_ReportErrorLatin1(cx, "can't read %s: %s", pathname.get(), strerror(errno));
@@ -365,17 +365,17 @@ osfile_writeTypedArrayToFile(JSContext* 
         // See further comments in FileAsTypedArray, above.
         filename = JS_EncodeStringToUTF8(cx, str);
         if (!filename) {
             return false;
         }
         JS_ReportErrorUTF8(cx, "can't write %s: shared memory buffer", filename.get());
         return false;
     }
-    void* buf = obj->viewDataUnshared();
+    void* buf = obj->dataPointerUnshared();
     if (fwrite(buf, obj->bytesPerElement(), obj->length(), file) != obj->length() ||
         !autoClose.release())
     {
         filename = JS_EncodeStringToUTF8(cx, str);
         if (!filename) {
             return false;
         }
         JS_ReportErrorUTF8(cx, "can't write %s", filename.get());
--- a/js/src/vm/ArrayBufferObject.cpp
+++ b/js/src/vm/ArrayBufferObject.cpp
@@ -1748,25 +1748,17 @@ ArrayBufferViewObject::notifyBufferDetac
     } else {
         as<OutlineTypedObject>().notifyBufferDetached(newData);
     }
 }
 
 uint8_t*
 ArrayBufferViewObject::dataPointerUnshared(const JS::AutoRequireNoGC& nogc)
 {
-    if (is<DataViewObject>()) {
-        MOZ_ASSERT(!as<DataViewObject>().isSharedMemory());
-        return static_cast<uint8_t*>(as<DataViewObject>().dataPointerUnshared());
-    }
-    if (is<TypedArrayObject>()) {
-        MOZ_ASSERT(!as<TypedArrayObject>().isSharedMemory());
-        return static_cast<uint8_t*>(as<TypedArrayObject>().viewDataUnshared());
-    }
-    MOZ_CRASH("Unknown ArrayBufferViewObject");
+    return static_cast<uint8_t*>(dataPointerUnshared());
 }
 
 void
 ArrayBufferViewObject::setDataPointerUnshared(uint8_t* data)
 {
     MOZ_ASSERT(!isSharedMemory());
     setPrivate(data);
 }
@@ -2052,24 +2044,20 @@ JS_IsMappedArrayBufferObject(JSObject* o
 
 JS_FRIEND_API(void*)
 JS_GetArrayBufferViewData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj) {
         return nullptr;
     }
-    if (obj->is<DataViewObject>()) {
-        DataViewObject& dv = obj->as<DataViewObject>();
-        *isSharedMemory = dv.isSharedMemory();
-        return dv.dataPointerEither().unwrap(/*safe - caller sees isSharedMemory flag*/);
-    }
-    TypedArrayObject& ta = obj->as<TypedArrayObject>();
-    *isSharedMemory = ta.isSharedMemory();
-    return ta.viewDataEither().unwrap(/*safe - caller sees isSharedMemory flag*/);
+
+    ArrayBufferViewObject& view = obj->as<ArrayBufferViewObject>();
+    *isSharedMemory = view.isSharedMemory();
+    return view.dataPointerEither().unwrap(/*safe - caller sees isSharedMemory flag*/);
 }
 
 JS_FRIEND_API(JSObject*)
 JS_GetArrayBufferViewBuffer(JSContext* cx, HandleObject objArg, bool* isSharedMemory)
 {
     AssertHeapIsIdle();
     CHECK_THREAD(cx);
     cx->check(objArg);
@@ -2129,28 +2117,20 @@ js::GetArrayBufferViewLengthAndData(JSOb
                                     uint8_t** data)
 {
     MOZ_ASSERT(obj->is<ArrayBufferViewObject>());
 
     *length = obj->is<DataViewObject>()
               ? obj->as<DataViewObject>().byteLength()
               : obj->as<TypedArrayObject>().byteLength();
 
-    if (obj->is<DataViewObject>()) {
-        DataViewObject& dv = obj->as<DataViewObject>();
-        *isSharedMemory = dv.isSharedMemory();
-        *data = static_cast<uint8_t*>(
-            dv.dataPointerEither().unwrap(/*safe - caller sees isShared flag*/));
-    }
-    else {
-        TypedArrayObject& ta = obj->as<TypedArrayObject>();
-        *isSharedMemory = ta.isSharedMemory();
-        *data = static_cast<uint8_t*>(
-            ta.viewDataEither().unwrap(/*safe - caller sees isShared flag*/));
-    }
+    ArrayBufferViewObject& view = obj->as<ArrayBufferViewObject>();
+    *isSharedMemory = view.isSharedMemory();
+    *data = static_cast<uint8_t*>(
+            view.dataPointerEither().unwrap(/*safe - caller sees isShared flag*/));
 }
 
 JS_FRIEND_API(JSObject*)
 JS_GetObjectAsArrayBuffer(JSObject* obj, uint32_t* length, uint8_t** data)
 {
     if (!(obj = CheckedUnwrap(obj))) {
         return nullptr;
     }
--- a/js/src/vm/ArrayBufferObject.h
+++ b/js/src/vm/ArrayBufferObject.h
@@ -487,25 +487,58 @@ class ArrayBufferViewObject : public Nat
 #endif
 
     // The raw pointer to the buffer memory, the "private" value.
     //
     // This offset is exposed for performance reasons - so that it
     // need not be looked up on accesses.
     static constexpr size_t DATA_SLOT = 3;
 
+  private:
+    void* dataPointerEither_() const {
+        // Note, do not check whether shared or not
+        // Keep synced with js::Get<Type>ArrayLengthAndData in jsfriendapi.h!
+        return static_cast<void*>(getPrivate(DATA_SLOT));
+    }
+
+  public:
     static ArrayBufferObjectMaybeShared* bufferObject(JSContext* cx, Handle<ArrayBufferViewObject*> obj);
 
     void notifyBufferDetached(JSContext* cx, void* newData);
 
     // By construction we only need unshared variants here.  See
     // comments in ArrayBufferObject.cpp.
     uint8_t* dataPointerUnshared(const JS::AutoRequireNoGC&);
     void setDataPointerUnshared(uint8_t* data);
 
+    void initDataPointer(SharedMem<uint8_t*> viewData) {
+        // Install a pointer to the buffer location that corresponds
+        // to offset zero within the typed array.
+        //
+        // The following unwrap is safe because the DATA_SLOT is
+        // accessed only from jitted code and from the
+        // dataPointerEither_() accessor above; in neither case does the
+        // raw pointer escape untagged into C++ code.
+        initPrivate(viewData.unwrap(/*safe - see above*/));
+    }
+
+    SharedMem<void*> dataPointerShared() const {
+        return SharedMem<void*>::shared(dataPointerEither_());
+    }
+    SharedMem<void*> dataPointerEither() const {
+        if (isSharedMemory()) {
+            return SharedMem<void*>::shared(dataPointerEither_());
+        }
+        return SharedMem<void*>::unshared(dataPointerEither_());
+    }
+    void* dataPointerUnshared() const {
+        MOZ_ASSERT(!isSharedMemory());
+        return dataPointerEither_();
+    }
+
     static void trace(JSTracer* trc, JSObject* obj);
 };
 
 bool
 ToClampedIndex(JSContext* cx, HandleValue v, uint32_t length, uint32_t* out);
 
 /*
  * Tests for ArrayBufferObject, like obj->is<ArrayBufferObject>().
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -7893,17 +7893,17 @@ DebuggerSource_getBinary(JSContext* cx, 
     }
 
     const wasm::Bytes& bytecode = instance.debug().bytecode();
     RootedObject arr(cx, JS_NewUint8Array(cx, bytecode.length()));
     if (!arr) {
         return false;
     }
 
-    memcpy(arr->as<TypedArrayObject>().viewDataUnshared(), bytecode.begin(), bytecode.length());
+    memcpy(arr->as<TypedArrayObject>().dataPointerUnshared(), bytecode.begin(), bytecode.length());
 
     args.rval().setObject(*arr);
     return true;
 }
 
 class DebuggerSourceGetURLMatcher
 {
     JSContext* cx_;
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -1232,17 +1232,17 @@ intrinsic_MoveTypedArrayElements(JSConte
         MOZ_ASSERT(byteSize <= viewByteLength);
         MOZ_ASSERT(byteDest < viewByteLength);
         MOZ_ASSERT(byteSrc < viewByteLength);
         MOZ_ASSERT(byteDest <= viewByteLength - byteSize);
         MOZ_ASSERT(byteSrc <= viewByteLength - byteSize);
     }
 #endif
 
-    SharedMem<uint8_t*> data = tarray->viewDataEither().cast<uint8_t*>();
+    SharedMem<uint8_t*> data = tarray->dataPointerEither().cast<uint8_t*>();
     jit::AtomicOperations::memmoveSafeWhenRacy(data + byteDest, data + byteSrc, byteSize);
 
     args.rval().setUndefined();
     return true;
 }
 
 // Extract the TypedArrayObject* underlying |obj| and return it.  This method,
 // in a TOTALLY UNSAFE manner, completely violates the normal compartment
@@ -1335,20 +1335,20 @@ intrinsic_SetFromTypedArrayApproach(JSCo
     // The remaining steps are unobservable *except* through their effect on
     // which elements are copied and how.
 
     Scalar::Type targetType = target->type();
     Scalar::Type unsafeSrcTypeCrossCompartment = unsafeTypedArrayCrossCompartment->type();
 
     size_t targetElementSize = TypedArrayElemSize(targetType);
     SharedMem<uint8_t*> targetData =
-        target->viewDataEither().cast<uint8_t*>() + targetOffset * targetElementSize;
+        target->dataPointerEither().cast<uint8_t*>() + targetOffset * targetElementSize;
 
     SharedMem<uint8_t*> unsafeSrcDataCrossCompartment =
-        unsafeTypedArrayCrossCompartment->viewDataEither().cast<uint8_t*>();
+        unsafeTypedArrayCrossCompartment->dataPointerEither().cast<uint8_t*>();
 
     uint32_t unsafeSrcElementSizeCrossCompartment =
         TypedArrayElemSize(unsafeSrcTypeCrossCompartment);
     uint32_t unsafeSrcByteLengthCrossCompartment =
         unsafeSrcLengthCrossCompartment * unsafeSrcElementSizeCrossCompartment;
 
     // Step 29.
     //
@@ -1369,17 +1369,17 @@ intrinsic_SetFromTypedArrayApproach(JSCo
 
     // Every other bit of element-copying is handled by step 28.  Indicate
     // whether such copying must take care not to overlap, so that self-hosted
     // code may correctly perform the copying.
 
     SharedMem<uint8_t*> unsafeSrcDataLimitCrossCompartment =
         unsafeSrcDataCrossCompartment + unsafeSrcByteLengthCrossCompartment;
     SharedMem<uint8_t*> targetDataLimit =
-        target->viewDataEither().cast<uint8_t*>() + targetLength * targetElementSize;
+        target->dataPointerEither().cast<uint8_t*>() + targetLength * targetElementSize;
 
     // Step 24 test (but not steps 24a-d -- the caller handles those).
     bool overlap =
         IsInRange(targetData.unwrap(/*safe - used for ptr value*/),
                   unsafeSrcDataCrossCompartment.unwrap(/*safe - ditto*/),
                   unsafeSrcDataLimitCrossCompartment.unwrap(/*safe - ditto*/)) ||
         IsInRange(unsafeSrcDataCrossCompartment.unwrap(/*safe - ditto*/),
                   targetData.unwrap(/*safe - ditto*/),
@@ -1458,17 +1458,17 @@ struct DisjointElements
     }
 };
 
 static void
 CopyToDisjointArray(TypedArrayObject* target, uint32_t targetOffset, SharedMem<void*> src,
                     Scalar::Type srcType, uint32_t count)
 {
     Scalar::Type destType = target->type();
-    SharedMem<uint8_t*> dest = target->viewDataEither().cast<uint8_t*>() + targetOffset * TypedArrayElemSize(destType);
+    SharedMem<uint8_t*> dest = target->dataPointerEither().cast<uint8_t*>() + targetOffset * TypedArrayElemSize(destType);
 
     switch (destType) {
       case Scalar::Int8: {
         DisjointElements::copy(dest.cast<int8_t*>(), src, srcType, count);
         break;
       }
 
       case Scalar::Uint8: {
@@ -1521,17 +1521,17 @@ CopyToDisjointArray(TypedArrayObject* ta
 // |DangerouslyUnwrapTypedArray|, sigil this pointer and all variables derived
 // from it to counsel extreme caution here.
 void
 js::SetDisjointTypedElements(TypedArrayObject* target, uint32_t targetOffset,
                              TypedArrayObject* unsafeSrcCrossCompartment)
 {
     Scalar::Type unsafeSrcTypeCrossCompartment = unsafeSrcCrossCompartment->type();
 
-    SharedMem<void*> unsafeSrcDataCrossCompartment = unsafeSrcCrossCompartment->viewDataEither();
+    SharedMem<void*> unsafeSrcDataCrossCompartment = unsafeSrcCrossCompartment->dataPointerEither();
     uint32_t count = unsafeSrcCrossCompartment->length();
 
     CopyToDisjointArray(target, targetOffset,
                         unsafeSrcDataCrossCompartment,
                         unsafeSrcTypeCrossCompartment, count);
 }
 
 static bool
@@ -1592,17 +1592,17 @@ intrinsic_SetOverlappingTypedElements(JS
     size_t sourceByteLen = count * TypedArrayElemSize(unsafeSrcTypeCrossCompartment);
 
     auto copyOfSrcData = cx->make_pod_array<uint8_t>(sourceByteLen);
     if (!copyOfSrcData) {
         return false;
     }
 
     jit::AtomicOperations::memcpySafeWhenRacy(SharedMem<uint8_t*>::unshared(copyOfSrcData.get()),
-                                              unsafeSrcCrossCompartment->viewDataEither().cast<uint8_t*>(),
+                                              unsafeSrcCrossCompartment->dataPointerEither().cast<uint8_t*>(),
                                               sourceByteLen);
 
     CopyToDisjointArray(target, targetOffset, SharedMem<void*>::unshared(copyOfSrcData.get()),
                         unsafeSrcTypeCrossCompartment, count);
 
     args.rval().setUndefined();
     return true;
 }
@@ -1679,20 +1679,20 @@ intrinsic_TypedArrayBitwiseSlice(JSConte
     MOZ_ASSERT(count > 0 && count <= source->length());
     MOZ_ASSERT(sourceOffset <= source->length() - count);
     MOZ_ASSERT(count <= unsafeTypedArrayCrossCompartment->length());
 
     size_t elementSize = TypedArrayElemSize(sourceType);
     MOZ_ASSERT(elementSize == TypedArrayElemSize(unsafeTypedArrayCrossCompartment->type()));
 
     SharedMem<uint8_t*> sourceData =
-        source->viewDataEither().cast<uint8_t*>() + sourceOffset * elementSize;
+        source->dataPointerEither().cast<uint8_t*>() + sourceOffset * elementSize;
 
     SharedMem<uint8_t*> unsafeTargetDataCrossCompartment =
-        unsafeTypedArrayCrossCompartment->viewDataEither().cast<uint8_t*>();
+        unsafeTypedArrayCrossCompartment->dataPointerEither().cast<uint8_t*>();
 
     uint32_t byteLength = count * elementSize;
 
     // The same-type case requires exact copying preserving the bit-level
     // encoding of the source data, so use memcpy if possible. If source and
     // target are the same buffer, we can't use memcpy (or memmove), because
     // the specification requires sequential copying of the values. This case
     // is only possible if a @@species constructor created a specifically
--- a/js/src/vm/TypeInference.cpp
+++ b/js/src/vm/TypeInference.cpp
@@ -2089,30 +2089,30 @@ class ConstraintDataFreezeObjectForTyped
     NativeObject* obj;
 
     uintptr_t viewData;
     uint32_t length;
 
   public:
     explicit ConstraintDataFreezeObjectForTypedArrayData(TypedArrayObject& tarray)
       : obj(&tarray),
-        viewData(tarray.viewDataEither().unwrapValue()),
+        viewData(tarray.dataPointerEither().unwrapValue()),
         length(tarray.length())
     {
         MOZ_ASSERT(tarray.isSingleton());
     }
 
     const char* kind() { return "freezeObjectForTypedArrayData"; }
 
     bool invalidateOnNewType(TypeSet::Type type) { return false; }
     bool invalidateOnNewPropertyState(TypeSet* property) { return false; }
     bool invalidateOnNewObjectState(const AutoSweepObjectGroup& sweep, ObjectGroup* group) {
         MOZ_ASSERT(obj->group() == group);
         TypedArrayObject& tarr = obj->as<TypedArrayObject>();
-        return tarr.viewDataEither().unwrapValue() != viewData || tarr.length() != length;
+        return tarr.dataPointerEither().unwrapValue() != viewData || tarr.length() != length;
     }
 
     bool constraintHolds(const AutoSweepObjectGroup& sweep, JSContext* cx,
                          const HeapTypeSetKey& property, TemporaryTypeSet* expected)
     {
         return !invalidateOnNewObjectState(sweep, property.object()->maybeGroup());
     }
 
--- a/js/src/vm/TypedArrayObject-inl.h
+++ b/js/src/vm/TypedArrayObject-inl.h
@@ -184,17 +184,17 @@ class SharedOps
     }
 
     template<typename T>
     static void podMove(SharedMem<T*> dest, SharedMem<T*> src, size_t nelem) {
         js::jit::AtomicOperations::podMoveSafeWhenRacy(dest, src, nelem);
     }
 
     static SharedMem<void*> extract(TypedArrayObject* obj) {
-        return obj->viewDataEither();
+        return obj->dataPointerEither();
     }
 };
 
 class UnsharedOps
 {
   public:
     template<typename T>
     static T load(SharedMem<T*> addr) {
@@ -234,17 +234,17 @@ class UnsharedOps
         // input/output ranges *may* permissibly overlap, as this function
         // allows.
         const auto* start = src.unwrapUnshared();
         auto* result = dest.unwrapUnshared();
         std::copy_n(start, n, result);
     }
 
     static SharedMem<void*> extract(TypedArrayObject* obj) {
-        return SharedMem<void*>::unshared(obj->viewDataUnshared());
+        return SharedMem<void*>::unshared(obj->dataPointerUnshared());
     }
 };
 
 template<typename T, typename Ops>
 class ElementSpecific
 {
   public:
     /*
@@ -266,21 +266,21 @@ class ElementSpecific
 
         MOZ_ASSERT(offset <= target->length());
         MOZ_ASSERT(source->length() <= target->length() - offset);
 
         if (TypedArrayObject::sameBuffer(target, source)) {
             return setFromOverlappingTypedArray(target, source, offset);
         }
 
-        SharedMem<T*> dest = target->viewDataEither().template cast<T*>() + offset;
+        SharedMem<T*> dest = target->dataPointerEither().template cast<T*>() + offset;
         uint32_t count = source->length();
 
         if (source->type() == target->type()) {
-            Ops::podCopy(dest, source->viewDataEither().template cast<T*>(), count);
+            Ops::podCopy(dest, source->dataPointerEither().template cast<T*>(), count);
             return true;
         }
 
         // Inhibit unaligned accesses on ARM (bug 1097253, a compiler bug).
 #if defined(__arm__) && MOZ_IS_GCC
 #  define JS_VOLATILE_ARM volatile
 #else
 #  define JS_VOLATILE_ARM
@@ -370,17 +370,17 @@ class ElementSpecific
                    "use setFromTypedArray instead of this method");
 
         uint32_t i = 0;
         if (source->isNative()) {
             // Attempt fast-path infallible conversion of dense elements up to
             // the first potentially side-effectful lookup or conversion.
             uint32_t bound = Min(source->as<NativeObject>().getDenseInitializedLength(), len);
 
-            SharedMem<T*> dest = target->viewDataEither().template cast<T*>() + offset;
+            SharedMem<T*> dest = target->dataPointerEither().template cast<T*>() + offset;
 
             MOZ_ASSERT(!canConvertInfallibly(MagicValue(JS_ELEMENTS_HOLE)),
                        "the following loop must abort on holes");
 
             const Value* srcValues = source->as<NativeObject>().getDenseElements();
             for (; i < bound; i++) {
                 if (!canConvertInfallibly(srcValues[i])) {
                     break;
@@ -406,17 +406,17 @@ class ElementSpecific
 
             len = Min(len, target->length());
             if (i >= len) {
                 break;
             }
 
             // Compute every iteration in case getElement/valueToNative
             // detaches the underlying array buffer or GC moves the data.
-            SharedMem<T*> dest = target->viewDataEither().template cast<T*>() + offset + i;
+            SharedMem<T*> dest = target->dataPointerEither().template cast<T*>() + offset + i;
             Ops::store(dest, n);
         }
 
         return true;
     }
 
     /*
      * Copy |source| into the typed array |target|.
@@ -432,17 +432,17 @@ class ElementSpecific
         MOZ_ASSERT(source->getDenseInitializedLength() <= target->length());
 
         uint32_t len = source->getDenseInitializedLength();
         uint32_t i = 0;
 
         // Attempt fast-path infallible conversion of dense elements up to the
         // first potentially side-effectful conversion.
 
-        SharedMem<T*> dest = target->viewDataEither().template cast<T*>();
+        SharedMem<T*> dest = target->dataPointerEither().template cast<T*>();
 
         const Value* srcValues = source->getDenseElements();
         for (; i < len; i++) {
             if (!canConvertInfallibly(srcValues[i])) {
                 break;
             }
             Ops::store(dest + i, infallibleValueToNative(srcValues[i]));
         }
@@ -467,17 +467,17 @@ class ElementSpecific
             }
 
             // |target| is a newly allocated typed array and not yet visible to
             // content script, so valueToNative can't detach the underlying
             // buffer.
             MOZ_ASSERT(i < target->length());
 
             // Compute every iteration in case GC moves the data.
-            SharedMem<T*> newDest = target->viewDataEither().template cast<T*>();
+            SharedMem<T*> newDest = target->dataPointerEither().template cast<T*>();
             Ops::store(newDest + i, n);
         }
 
         return true;
     }
 
   private:
     static bool
@@ -494,33 +494,33 @@ class ElementSpecific
         MOZ_ASSERT(!source->hasDetachedBuffer(), "source isn't detached");
         MOZ_ASSERT(TypedArrayObject::sameBuffer(target, source),
                    "the provided arrays don't actually overlap, so it's "
                    "undesirable to use this method");
 
         MOZ_ASSERT(offset <= target->length());
         MOZ_ASSERT(source->length() <= target->length() - offset);
 
-        SharedMem<T*> dest = target->viewDataEither().template cast<T*>() + offset;
+        SharedMem<T*> dest = target->dataPointerEither().template cast<T*>() + offset;
         uint32_t len = source->length();
 
         if (source->type() == target->type()) {
-            SharedMem<T*> src = source->viewDataEither().template cast<T*>();
+            SharedMem<T*> src = source->dataPointerEither().template cast<T*>();
             Ops::podMove(dest, src, len);
             return true;
         }
 
         // Copy |source| in case it overlaps the target elements being set.
         size_t sourceByteLen = len * source->bytesPerElement();
         void* data = target->zone()->template pod_malloc<uint8_t>(sourceByteLen);
         if (!data) {
             return false;
         }
         Ops::memcpy(SharedMem<void*>::unshared(data),
-                    source->viewDataEither(),
+                    source->dataPointerEither(),
                     sourceByteLen);
 
         switch (source->type()) {
           case Scalar::Int8: {
             int8_t* src = static_cast<int8_t*>(data);
             for (uint32_t i = 0; i < len; ++i) {
                 Ops::store(dest++, ConvertNumber<T>(*src++));
             }
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -115,17 +115,17 @@ TypedArrayObject::ensureHasBuffer(JSCont
         return false;
     }
 
     if (!buffer->addView(cx, tarray)) {
         return false;
     }
 
     // tarray is not shared, because if it were it would have a buffer.
-    memcpy(buffer->dataPointer(), tarray->viewDataUnshared(), tarray->byteLength());
+    memcpy(buffer->dataPointer(), tarray->dataPointerUnshared(), tarray->byteLength());
 
     // If the object is in the nursery, the buffer will be freed by the next
     // nursery GC. Free the data slot pointer if the object has no inline data.
     Nursery& nursery = cx->nursery();
     if (tarray->isTenured() && !tarray->hasInlineElements() &&
         !nursery.isInside(tarray->elements()))
     {
         js_free(tarray->elements());
@@ -496,17 +496,17 @@ class TypedArrayObjectTemplate : public 
         obj->setFixedSlot(TypedArrayObject::BUFFER_SLOT, ObjectOrNullValue(buffer));
         // This is invariant.  Self-hosting code that sets BUFFER_SLOT
         // (if it does) must maintain it, should it need to.
         if (isSharedMemory) {
             obj->setIsSharedMemory();
         }
 
         if (buffer) {
-            obj->initViewData(buffer->dataPointerEither() + byteOffset);
+            obj->initDataPointer(buffer->dataPointerEither() + byteOffset);
 
             // If the buffer is for an inline typed object, the data pointer
             // may be in the nursery, so include a barrier to make sure this
             // object is updated if that typed object moves.
             auto ptr = buffer->dataPointerEither();
             if (!IsInsideNursery(obj) && cx->nursery().isInside(ptr)) {
                 // Shared buffer data should never be nursery-allocated, so we
                 // need to fail here if isSharedMemory.  However, mmap() can
@@ -538,17 +538,17 @@ class TypedArrayObjectTemplate : public 
 #ifdef DEBUG
         if (buffer) {
             uint32_t arrayByteLength = obj->byteLength();
             uint32_t arrayByteOffset = obj->byteOffset();
             uint32_t bufferByteLength = buffer->byteLength();
             // Unwraps are safe: both are for the pointer value.
             if (IsArrayBuffer(buffer.get())) {
                 MOZ_ASSERT_IF(!AsArrayBuffer(buffer.get()).isDetached(),
-                              buffer->dataPointerEither().unwrap(/*safe*/) <= obj->viewDataEither().unwrap(/*safe*/));
+                              buffer->dataPointerEither().unwrap(/*safe*/) <= obj->dataPointerEither().unwrap(/*safe*/));
             }
             MOZ_ASSERT(bufferByteLength - arrayByteOffset >= arrayByteLength);
             MOZ_ASSERT(arrayByteOffset <= bufferByteLength);
         }
 
         // Verify that the private slot is at the expected place
         MOZ_ASSERT(obj->numFixedSlots() == TypedArrayObject::DATA_SLOT);
 #endif
@@ -1034,24 +1034,24 @@ class TypedArrayObjectTemplate : public 
 
     static JSObject*
     fromObject(JSContext* cx, HandleObject other, HandleObject proto);
 
     static const NativeType
     getIndex(TypedArrayObject* tarray, uint32_t index)
     {
         MOZ_ASSERT(index < tarray->length());
-        return jit::AtomicOperations::loadSafeWhenRacy(tarray->viewDataEither().cast<NativeType*>() + index);
+        return jit::AtomicOperations::loadSafeWhenRacy(tarray->dataPointerEither().cast<NativeType*>() + index);
     }
 
     static void
     setIndex(TypedArrayObject& tarray, uint32_t index, NativeType val)
     {
         MOZ_ASSERT(index < tarray.length());
-        jit::AtomicOperations::storeSafeWhenRacy(tarray.viewDataEither().cast<NativeType*>() + index, val);
+        jit::AtomicOperations::storeSafeWhenRacy(tarray.dataPointerEither().cast<NativeType*>() + index, val);
     }
 
     static Value getIndexValue(TypedArrayObject* tarray, uint32_t index);
 };
 
 #define CREATE_TYPE_FOR_TYPED_ARRAY(T, N) \
     typedef TypedArrayObjectTemplate<T> N##Array;
 JS_FOR_EACH_TYPED_ARRAY(CREATE_TYPE_FOR_TYPED_ARRAY)
@@ -2023,17 +2023,17 @@ IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Floa
                                                                                             \
       const Class* clasp = obj->getClass();                                                 \
       if (clasp != TypedArrayObjectTemplate<InternalType>::instanceClass())                 \
           return nullptr;                                                                   \
                                                                                             \
       TypedArrayObject* tarr = &obj->as<TypedArrayObject>();                                \
       *length = tarr->length();                                                             \
       *isShared = tarr->isSharedMemory();                                                         \
-      *data = static_cast<ExternalType*>(tarr->viewDataEither().unwrap(/*safe - caller sees isShared flag*/)); \
+      *data = static_cast<ExternalType*>(tarr->dataPointerEither().unwrap(/*safe - caller sees isShared flag*/)); \
                                                                                             \
       return obj;                                                                           \
   }
 
 IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Int8, int8_t, int8_t)
 IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Uint8, uint8_t, uint8_t)
 IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Uint8Clamped, uint8_t, uint8_clamped)
 IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Int16, int16_t, int16_t)
@@ -2199,17 +2199,17 @@ js::IsTypedArrayConstructor(HandleValue 
     MOZ_CRASH("unexpected typed array type");
 }
 
 bool
 js::IsBufferSource(JSObject* object, SharedMem<uint8_t*>* dataPointer, size_t* byteLength)
 {
     if (object->is<TypedArrayObject>()) {
         TypedArrayObject& view = object->as<TypedArrayObject>();
-        *dataPointer = view.viewDataEither().cast<uint8_t*>();
+        *dataPointer = view.dataPointerEither().cast<uint8_t*>();
         *byteLength = view.byteLength();
         return true;
     }
 
     if (object->is<DataViewObject>()) {
         DataViewObject& view = object->as<DataViewObject>();
         *dataPointer = view.dataPointerEither().cast<uint8_t*>();
         *byteLength = view.byteLength();
@@ -2432,114 +2432,114 @@ JS_GetInt8ArrayData(JSObject* obj, bool*
 {
     obj = CheckedUnwrap(obj);
     if (!obj) {
         return nullptr;
     }
     TypedArrayObject* tarr = &obj->as<TypedArrayObject>();
     MOZ_ASSERT((int32_t) tarr->type() == Scalar::Int8);
     *isSharedMemory = tarr->isSharedMemory();
-    return static_cast<int8_t*>(tarr->viewDataEither().unwrap(/*safe - caller sees isShared*/));
+    return static_cast<int8_t*>(tarr->dataPointerEither().unwrap(/*safe - caller sees isShared*/));
 }
 
 JS_FRIEND_API(uint8_t*)
 JS_GetUint8ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj) {
         return nullptr;
     }
     TypedArrayObject* tarr = &obj->as<TypedArrayObject>();
     MOZ_ASSERT((int32_t) tarr->type() == Scalar::Uint8);
     *isSharedMemory = tarr->isSharedMemory();
-    return static_cast<uint8_t*>(tarr->viewDataEither().unwrap(/*safe - caller sees isSharedMemory*/));
+    return static_cast<uint8_t*>(tarr->dataPointerEither().unwrap(/*safe - caller sees isSharedMemory*/));
 }
 
 JS_FRIEND_API(uint8_t*)
 JS_GetUint8ClampedArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj) {
         return nullptr;
     }
     TypedArrayObject* tarr = &obj->as<TypedArrayObject>();
     MOZ_ASSERT((int32_t) tarr->type() == Scalar::Uint8Clamped);
     *isSharedMemory = tarr->isSharedMemory();
-    return static_cast<uint8_t*>(tarr->viewDataEither().unwrap(/*safe - caller sees isSharedMemory*/));
+    return static_cast<uint8_t*>(tarr->dataPointerEither().unwrap(/*safe - caller sees isSharedMemory*/));
 }
 
 JS_FRIEND_API(int16_t*)
 JS_GetInt16ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj) {
         return nullptr;
     }
     TypedArrayObject* tarr = &obj->as<TypedArrayObject>();
     MOZ_ASSERT((int32_t) tarr->type() == Scalar::Int16);
     *isSharedMemory = tarr->isSharedMemory();
-    return static_cast<int16_t*>(tarr->viewDataEither().unwrap(/*safe - caller sees isSharedMemory*/));
+    return static_cast<int16_t*>(tarr->dataPointerEither().unwrap(/*safe - caller sees isSharedMemory*/));
 }
 
 JS_FRIEND_API(uint16_t*)
 JS_GetUint16ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj) {
         return nullptr;
     }
     TypedArrayObject* tarr = &obj->as<TypedArrayObject>();
     MOZ_ASSERT((int32_t) tarr->type() == Scalar::Uint16);
     *isSharedMemory = tarr->isSharedMemory();
-    return static_cast<uint16_t*>(tarr->viewDataEither().unwrap(/*safe - caller sees isSharedMemory*/));
+    return static_cast<uint16_t*>(tarr->dataPointerEither().unwrap(/*safe - caller sees isSharedMemory*/));
 }
 
 JS_FRIEND_API(int32_t*)
 JS_GetInt32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj) {
         return nullptr;
     }
     TypedArrayObject* tarr = &obj->as<TypedArrayObject>();
     MOZ_ASSERT((int32_t) tarr->type() == Scalar::Int32);
     *isSharedMemory = tarr->isSharedMemory();
-    return static_cast<int32_t*>(tarr->viewDataEither().unwrap(/*safe - caller sees isSharedMemory*/));
+    return static_cast<int32_t*>(tarr->dataPointerEither().unwrap(/*safe - caller sees isSharedMemory*/));
 }
 
 JS_FRIEND_API(uint32_t*)
 JS_GetUint32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj) {
         return nullptr;
     }
     TypedArrayObject* tarr = &obj->as<TypedArrayObject>();
     MOZ_ASSERT((int32_t) tarr->type() == Scalar::Uint32);
     *isSharedMemory = tarr->isSharedMemory();
-    return static_cast<uint32_t*>(tarr->viewDataEither().unwrap(/*safe - caller sees isSharedMemory*/));
+    return static_cast<uint32_t*>(tarr->dataPointerEither().unwrap(/*safe - caller sees isSharedMemory*/));
 }
 
 JS_FRIEND_API(float*)
 JS_GetFloat32ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj) {
         return nullptr;
     }
     TypedArrayObject* tarr = &obj->as<TypedArrayObject>();
     MOZ_ASSERT((int32_t) tarr->type() == Scalar::Float32);
     *isSharedMemory = tarr->isSharedMemory();
-    return static_cast<float*>(tarr->viewDataEither().unwrap(/*safe - caller sees isSharedMemory*/));
+    return static_cast<float*>(tarr->dataPointerEither().unwrap(/*safe - caller sees isSharedMemory*/));
 }
 
 JS_FRIEND_API(double*)
 JS_GetFloat64ArrayData(JSObject* obj, bool* isSharedMemory, const JS::AutoRequireNoGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj) {
         return nullptr;
     }
     TypedArrayObject* tarr = &obj->as<TypedArrayObject>();
     MOZ_ASSERT((int32_t) tarr->type() == Scalar::Float64);
     *isSharedMemory = tarr->isSharedMemory();
-    return static_cast<double*>(tarr->viewDataEither().unwrap(/*safe - caller sees isSharedMemory*/));
+    return static_cast<double*>(tarr->dataPointerEither().unwrap(/*safe - caller sees isSharedMemory*/));
 }
--- a/js/src/vm/TypedArrayObject.h
+++ b/js/src/vm/TypedArrayObject.h
@@ -183,64 +183,32 @@ class TypedArrayObject : public ArrayBuf
             return nullptr;
         }
         if (isSharedMemory()) {
             return &obj->as<SharedArrayBufferObject>();
         }
         return &obj->as<ArrayBufferObject>();
     }
 
-    SharedMem<void*> viewDataShared() const {
-        return SharedMem<void*>::shared(viewDataEither_());
-    }
-    SharedMem<void*> viewDataEither() const {
-        if (isSharedMemory()) {
-            return SharedMem<void*>::shared(viewDataEither_());
-        }
-        return SharedMem<void*>::unshared(viewDataEither_());
-    }
-    void initViewData(SharedMem<uint8_t*> viewData) {
-        // Install a pointer to the buffer location that corresponds
-        // to offset zero within the typed array.
-        //
-        // The following unwrap is safe because the DATA_SLOT is
-        // accessed only from jitted code and from the
-        // viewDataEither_() accessor below; in neither case does the
-        // raw pointer escape untagged into C++ code.
-        initPrivate(viewData.unwrap(/*safe - see above*/));
-    }
-    void* viewDataUnshared() const {
-        MOZ_ASSERT(!isSharedMemory());
-        return viewDataEither_();
-    }
-
     bool hasDetachedBuffer() const {
         // Shared buffers can't be detached.
         if (isSharedMemory()) {
             return false;
         }
 
         // A typed array with a null buffer has never had its buffer exposed to
         // become detached.
         ArrayBufferObject* buffer = bufferUnshared();
         if (!buffer) {
             return false;
         }
 
         return buffer->isDetached();
     }
 
-  private:
-    void* viewDataEither_() const {
-        // Note, do not check whether shared or not
-        // Keep synced with js::Get<Type>ArrayLengthAndData in jsfriendapi.h!
-        return static_cast<void*>(getPrivate(DATA_SLOT));
-    }
-
-  public:
     static void trace(JSTracer* trc, JSObject* obj);
     static void finalize(FreeOp* fop, JSObject* obj);
     static size_t objectMoved(JSObject* obj, JSObject* old);
 
     /* Initialization bits */
 
     template<Value ValueGetter(const TypedArrayObject* tarr)>
     static bool
--- a/js/src/wasm/WasmJS.cpp
+++ b/js/src/wasm/WasmJS.cpp
@@ -395,17 +395,17 @@ wasm::Eval(JSContext* cx, Handle<TypedAr
         return false;
     }
 
     MutableBytes bytecode = cx->new_<ShareableBytes>();
     if (!bytecode) {
         return false;
     }
 
-    if (!bytecode->append((uint8_t*)code->viewDataEither().unwrap(), code->byteLength())) {
+    if (!bytecode->append((uint8_t*)code->dataPointerEither().unwrap(), code->byteLength())) {
         ReportOutOfMemory(cx);
         return false;
     }
 
     ScriptedCaller scriptedCaller;
     if (!DescribeScriptedCaller(cx, &scriptedCaller, "wasm_eval")) {
         return false;
     }
--- a/js/src/wasm/WasmModule.cpp
+++ b/js/src/wasm/WasmModule.cpp
@@ -495,17 +495,18 @@ Module::extractCode(JSContext* cx, Tier 
     }
 
     const ModuleSegment& moduleSegment = code_->segment(tier);
     RootedObject code(cx, JS_NewUint8Array(cx, moduleSegment.length()));
     if (!code) {
         return false;
     }
 
-    memcpy(code->as<TypedArrayObject>().viewDataUnshared(), moduleSegment.base(), moduleSegment.length());
+    memcpy(code->as<TypedArrayObject>().dataPointerUnshared(), moduleSegment.base(),
+           moduleSegment.length());
 
     RootedValue value(cx, ObjectValue(*code));
     if (!JS_DefineProperty(cx, result, "code", value, JSPROP_ENUMERATE)) {
         return false;
     }
 
     RootedObject segments(cx, NewDenseEmptyArray(cx));
     if (!segments) {