Bug 1517259 - Part 3: Sprinkle a few constexpr throughout TypedArray code. r=tcampbell
authorAndré Bargull <andre.bargull@gmail.com>
Thu, 03 Jan 2019 02:46:46 -0800
changeset 509944 8f35396665f570d44b59fd968ceccc5dd62dddcc
parent 509943 9ee71cbdb6ab65bd05c2c33edded8b5fa9faebde
child 509945 b4b4151af7978699b3e5fb15af1fed6cb787db6e
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstcampbell
bugs1517259
milestone66.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 1517259 - Part 3: Sprinkle a few constexpr throughout TypedArray code. r=tcampbell
js/src/jit/MacroAssembler.cpp
js/src/vm/ArrayBufferObject.h
js/src/vm/NativeObject.h
js/src/vm/TypedArrayObject.cpp
js/src/vm/TypedArrayObject.h
--- a/js/src/jit/MacroAssembler.cpp
+++ b/js/src/jit/MacroAssembler.cpp
@@ -1201,29 +1201,34 @@ static void AllocateObjectBufferWithInit
 void MacroAssembler::initTypedArraySlots(Register obj, Register temp,
                                          Register lengthReg,
                                          LiveRegisterSet liveRegs, Label* fail,
                                          TypedArrayObject* templateObj,
                                          TypedArrayLength lengthKind) {
   MOZ_ASSERT(templateObj->hasPrivate());
   MOZ_ASSERT(!templateObj->hasBuffer());
 
-  size_t dataSlotOffset = TypedArrayObject::dataOffset();
-  size_t dataOffset = TypedArrayObject::dataOffset() + sizeof(HeapSlot);
+  constexpr size_t dataSlotOffset = TypedArrayObject::dataOffset();
+  constexpr size_t dataOffset = dataSlotOffset + sizeof(HeapSlot);
 
   static_assert(
       TypedArrayObject::FIXED_DATA_START == TypedArrayObject::DATA_SLOT + 1,
       "fixed inline element data assumed to begin after the data slot");
 
+  static_assert(
+      TypedArrayObject::INLINE_BUFFER_LIMIT ==
+          JSObject::MAX_BYTE_SIZE - dataOffset,
+      "typed array inline buffer is limited by the maximum object byte size");
+
   // Initialise data elements to zero.
   int32_t length = templateObj->length();
   size_t nbytes = length * templateObj->bytesPerElement();
 
   if (lengthKind == TypedArrayLength::Fixed &&
-      dataOffset + nbytes <= JSObject::MAX_BYTE_SIZE) {
+      nbytes <= TypedArrayObject::INLINE_BUFFER_LIMIT) {
     MOZ_ASSERT(dataOffset + nbytes <= templateObj->tenuredSizeOfThis());
 
     // Store data elements inside the remaining JSObject slots.
     computeEffectiveAddress(Address(obj, dataOffset), temp);
     storePtr(temp, Address(obj, dataSlotOffset));
 
     // Write enough zero pointers into fixed data to zero every
     // element.  (This zeroes past the end of a byte count that's
--- a/js/src/vm/ArrayBufferObject.h
+++ b/js/src/vm/ArrayBufferObject.h
@@ -531,42 +531,42 @@ struct uint8_clamped {
   void staticAsserts() {
     static_assert(sizeof(uint8_clamped) == 1,
                   "uint8_clamped must be layout-compatible with uint8_t");
   }
 };
 
 /* Note that we can't use std::numeric_limits here due to uint8_clamped. */
 template <typename T>
-inline bool TypeIsFloatingPoint() {
+inline constexpr bool TypeIsFloatingPoint() {
   return false;
 }
 template <>
-inline bool TypeIsFloatingPoint<float>() {
+inline constexpr bool TypeIsFloatingPoint<float>() {
   return true;
 }
 template <>
-inline bool TypeIsFloatingPoint<double>() {
+inline constexpr bool TypeIsFloatingPoint<double>() {
   return true;
 }
 
 template <typename T>
-inline bool TypeIsUnsigned() {
+inline constexpr bool TypeIsUnsigned() {
   return false;
 }
 template <>
-inline bool TypeIsUnsigned<uint8_t>() {
+inline constexpr bool TypeIsUnsigned<uint8_t>() {
   return true;
 }
 template <>
-inline bool TypeIsUnsigned<uint16_t>() {
+inline constexpr bool TypeIsUnsigned<uint16_t>() {
   return true;
 }
 template <>
-inline bool TypeIsUnsigned<uint32_t>() {
+inline constexpr bool TypeIsUnsigned<uint32_t>() {
   return true;
 }
 
 // Per-compartment table that manages the relationship between array buffers
 // and the views that use their storage.
 class InnerViewTable {
  public:
   typedef Vector<JSObject*, 1, SystemAllocPolicy> ViewVector;
--- a/js/src/vm/NativeObject.h
+++ b/js/src/vm/NativeObject.h
@@ -1506,20 +1506,20 @@ class NativeObject : public ShapedObject
   inline js::GlobalObject& global() const;
 
   /* JIT Accessors */
   static size_t offsetOfElements() { return offsetof(NativeObject, elements_); }
   static size_t offsetOfFixedElements() {
     return sizeof(NativeObject) + sizeof(ObjectElements);
   }
 
-  static size_t getFixedSlotOffset(size_t slot) {
+  static constexpr size_t getFixedSlotOffset(size_t slot) {
     return sizeof(NativeObject) + slot * sizeof(Value);
   }
-  static size_t getPrivateDataOffset(size_t nfixed) {
+  static constexpr size_t getPrivateDataOffset(size_t nfixed) {
     return getFixedSlotOffset(nfixed);
   }
   static size_t offsetOfSlots() { return offsetof(NativeObject, slots_); }
 };
 
 // Object class for plain native objects created using '{}' object literals,
 // 'new Object()', 'Object.create', etc.
 class PlainObject : public NativeObject {
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -60,24 +60,16 @@ using mozilla::IsAsciiDigit;
 /*
  * TypedArrayObject
  *
  * The non-templated base class for the specific typed implementations.
  * This class holds all the member variables that are used by
  * the subclasses.
  */
 
-/* static */ int TypedArrayObject::lengthOffset() {
-  return NativeObject::getFixedSlotOffset(LENGTH_SLOT);
-}
-
-/* static */ int TypedArrayObject::dataOffset() {
-  return NativeObject::getPrivateDataOffset(DATA_SLOT);
-}
-
 /* static */ bool TypedArrayObject::is(HandleValue v) {
   return v.isObject() && v.toObject().is<TypedArrayObject>();
 }
 
 /* static */ bool TypedArrayObject::ensureHasBuffer(
     JSContext* cx, Handle<TypedArrayObject*> tarray) {
   if (tarray->hasBuffer()) {
     return true;
@@ -286,22 +278,24 @@ enum class CreateSingleton { Yes, No };
 template <typename NativeType>
 class TypedArrayObjectTemplate : public TypedArrayObject {
   friend class TypedArrayObject;
 
  public:
   static constexpr Scalar::Type ArrayTypeID() {
     return TypeIDOfType<NativeType>::id;
   }
-  static bool ArrayTypeIsUnsigned() { return TypeIsUnsigned<NativeType>(); }
-  static bool ArrayTypeIsFloatingPoint() {
+  static constexpr bool ArrayTypeIsUnsigned() {
+    return TypeIsUnsigned<NativeType>();
+  }
+  static constexpr bool ArrayTypeIsFloatingPoint() {
     return TypeIsFloatingPoint<NativeType>();
   }
 
-  static const size_t BYTES_PER_ELEMENT = sizeof(NativeType);
+  static constexpr size_t BYTES_PER_ELEMENT = sizeof(NativeType);
 
   static JSObject* createPrototype(JSContext* cx, JSProtoKey key) {
     Handle<GlobalObject*> global = cx->global();
     RootedObject typedArrayProto(
         cx, GlobalObject::getOrCreateTypedArrayPrototype(cx, global));
     if (!typedArrayProto) {
       return nullptr;
     }
--- a/js/src/vm/TypedArrayObject.h
+++ b/js/src/vm/TypedArrayObject.h
@@ -30,18 +30,22 @@ namespace js {
  *
  * The non-templated base class for the specific typed implementations.
  * This class holds all the member variables that are used by
  * the subclasses.
  */
 
 class TypedArrayObject : public ArrayBufferViewObject {
  public:
-  static int lengthOffset();
-  static int dataOffset();
+  static constexpr int lengthOffset() {
+    return NativeObject::getFixedSlotOffset(LENGTH_SLOT);
+  }
+  static constexpr int dataOffset() {
+    return NativeObject::getPrivateDataOffset(DATA_SLOT);
+  }
 
   static_assert(js::detail::TypedArrayLengthSlot == LENGTH_SLOT,
                 "bad inlined constant in jsfriendapi.h");
 
   static bool sameBuffer(Handle<TypedArrayObject*> a,
                          Handle<TypedArrayObject*> b) {
     // Inline buffers.
     if (!a->hasBuffer() || !b->hasBuffer()) {
@@ -65,21 +69,21 @@ class TypedArrayObject : public ArrayBuf
     return &classes[type];
   }
 
   static const Class* protoClassForType(Scalar::Type type) {
     MOZ_ASSERT(type < Scalar::MaxTypedArrayViewType);
     return &protoClasses[type];
   }
 
-  static const size_t FIXED_DATA_START = DATA_SLOT + 1;
+  static constexpr size_t FIXED_DATA_START = DATA_SLOT + 1;
 
   // For typed arrays which can store their data inline, the array buffer
   // object is created lazily.
-  static const uint32_t INLINE_BUFFER_LIMIT =
+  static constexpr uint32_t INLINE_BUFFER_LIMIT =
       (NativeObject::MAX_FIXED_SLOTS - FIXED_DATA_START) * sizeof(Value);
 
   static inline gc::AllocKind AllocKindForLazyBuffer(size_t nbytes);
 
   inline Scalar::Type type() const;
   inline size_t bytesPerElement() const;
 
   static Value byteOffsetValue(const TypedArrayObject* tarr) {
@@ -129,17 +133,17 @@ class TypedArrayObject : public ArrayBuf
   static bool GetTemplateObjectForNative(JSContext* cx, Native native,
                                          uint32_t len, MutableHandleObject res);
 
   /*
    * Byte length above which created typed arrays will have singleton types
    * regardless of the context in which they are created. This only applies to
    * typed arrays created with an existing ArrayBuffer.
    */
-  static const uint32_t SINGLETON_BYTE_LENGTH = 1024 * 1024 * 10;
+  static constexpr uint32_t SINGLETON_BYTE_LENGTH = 1024 * 1024 * 10;
 
   static bool isOriginalLengthGetter(Native native);
 
   static void finalize(FreeOp* fop, JSObject* obj);
   static size_t objectMoved(JSObject* obj, JSObject* old);
 
   /* Initialization bits */