Bug 1462540 - Remove NativeIterator::guard_array: its numeric value is identical to NativeIterator::props_end. r=jandem
authorJeff Walden <jwalden@mit.edu>
Wed, 16 May 2018 23:24:28 -0700
changeset 418921 7d83c7de9404
parent 418920 6ae525ee499f
child 418922 7491ab23247f
push id103419
push userjwalden@mit.edu
push date2018-05-18 19:33 +0000
treeherdermozilla-inbound@7658d2d1e0d7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1462540
milestone62.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 1462540 - Remove NativeIterator::guard_array: its numeric value is identical to NativeIterator::props_end. r=jandem
js/src/vm/Iteration.cpp
js/src/vm/Iteration.h
--- a/js/src/vm/Iteration.cpp
+++ b/js/src/vm/Iteration.cpp
@@ -54,18 +54,19 @@ static const gc::AllocKind ITERATOR_FINA
 
 void
 NativeIterator::trace(JSTracer* trc)
 {
     for (GCPtrFlatString* str = begin(); str < end(); str++)
         TraceNullableEdge(trc, str, "prop");
     TraceNullableEdge(trc, &obj, "obj");
 
+    HeapReceiverGuard* guards = guardArray();
     for (size_t i = 0; i < guard_length; i++)
-        guard_array[i].trace(trc);
+        guards[i].trace(trc);
 
     // The SuppressDeletedPropertyHelper loop can GC, so make sure that if the
     // GC removes any elements from the list, it won't remove this one.
     if (iterObj_)
         TraceManuallyBarrieredEdge(trc, &iterObj_, "iterObj");
 }
 
 typedef HashSet<jsid, DefaultHasher<jsid>> IdSet;
@@ -567,20 +568,16 @@ NativeIterator::allocateIterator(JSConte
 {
     static_assert(sizeof(ReceiverGuard) == 2 * sizeof(GCPtrFlatString),
                   "NativeIterators are allocated in space for 1) themselves, "
                   "2) the properties a NativeIterator iterates (as "
                   "GCPtrFlatStrings), and 3) |numGuards| ReceiverGuard "
                   "objects; the additional-length calculation below assumes "
                   "this size-relationship when determining the extra space to "
                   "allocate");
-    static_assert(alignof(ReceiverGuard) == alignof(GCPtrFlatString),
-                  "the end of all properties must be exactly aligned adequate "
-                  "to begin storing ReceiverGuards, else the tacked-on memory "
-                  "below will be inadequate to store all properties/guards");
 
     size_t extraLength = plength + numGuards * 2;
     NativeIterator* ni =
         cx->zone()->pod_malloc_with_extra<NativeIterator, GCPtrFlatString>(extraLength);
     if (!ni) {
         ReportOutOfMemory(cx);
         return nullptr;
     }
@@ -616,17 +613,16 @@ NativeIterator::allocateSentinel(JSConte
 }
 
 inline void
 NativeIterator::init(JSObject* obj, JSObject* iterObj, uint32_t numGuards, uint32_t key)
 {
     this->obj.init(obj);
     this->iterObj_ = iterObj;
     this->flags = 0;
-    this->guard_array = (HeapReceiverGuard*) this->props_end;
     this->guard_length = numGuards;
     this->guard_key = key;
 }
 
 bool
 NativeIterator::initProperties(JSContext* cx, Handle<PropertyIteratorObject*> obj,
                                const AutoIdVector& props)
 {
@@ -681,19 +677,20 @@ VectorToKeyIterator(JSContext* cx, Handl
     if (numGuards) {
         // Fill in the guard array from scratch. Also recompute the guard key
         // as we might have reshaped the object (see for instance the
         // setIteratedSingleton call above) or GC might have moved shapes and
         // groups in memory.
         JSObject* pobj = obj;
         size_t ind = 0;
         uint32_t key = 0;
+        HeapReceiverGuard* guards = ni->guardArray();
         do {
             ReceiverGuard guard(pobj);
-            ni->guard_array[ind++].init(guard);
+            guards[ind++].init(guard);
             key = mozilla::AddToHash(key, guard.hash());
 
             // The one caller of this method that passes |numGuards > 0|, does
             // so only if the entire chain consists of cacheable objects (that
             // necessarily have static prototypes).
             pobj = pobj->staticPrototype();
         } while (pobj);
         ni->guard_key = key;
@@ -735,17 +732,17 @@ js::NewEmptyPropertyIterator(JSContext* 
 
 /* static */ bool
 IteratorHashPolicy::match(PropertyIteratorObject* obj, const Lookup& lookup)
 {
     NativeIterator* ni = obj->getNativeIterator();
     if (ni->guard_key != lookup.key || ni->guard_length != lookup.numGuards)
         return false;
 
-    return PodEqual(reinterpret_cast<ReceiverGuard*>(ni->guard_array), lookup.guards,
+    return PodEqual(reinterpret_cast<ReceiverGuard*>(ni->guardArray()), lookup.guards,
                     ni->guard_length);
 }
 
 static inline void
 UpdateNativeIterator(NativeIterator* ni, JSObject* obj)
 {
     // Update the object for which the native iterator is associated, so
     // SuppressDeletedPropertyHelper will recognize the iterator as a match.
@@ -835,18 +832,19 @@ CanStoreInIteratorCache(JSObject* obj)
 static MOZ_MUST_USE bool
 StoreInIteratorCache(JSContext* cx, JSObject* obj, PropertyIteratorObject* iterobj)
 {
     MOZ_ASSERT(CanStoreInIteratorCache(obj));
 
     NativeIterator* ni = iterobj->getNativeIterator();
     MOZ_ASSERT(ni->guard_length > 0);
 
-    IteratorHashPolicy::Lookup lookup(reinterpret_cast<ReceiverGuard*>(ni->guard_array),
-                                      ni->guard_length, ni->guard_key);
+    IteratorHashPolicy::Lookup lookup(reinterpret_cast<ReceiverGuard*>(ni->guardArray()),
+                                      ni->guard_length,
+                                      ni->guard_key);
 
     JSCompartment::IteratorCache& cache = cx->compartment()->iteratorCache;
     bool ok;
     auto p = cache.lookupForAdd(lookup);
     if (MOZ_LIKELY(!p)) {
         ok = cache.add(p, iterobj);
     } else {
         // If we weren't able to use an existing cached iterator, just
--- a/js/src/vm/Iteration.h
+++ b/js/src/vm/Iteration.h
@@ -29,18 +29,17 @@ namespace js {
 
 class PropertyIteratorObject;
 
 struct NativeIterator
 {
     GCPtrObject obj;    // Object being iterated.
     JSObject* iterObj_; // Internal iterator object.
     GCPtrFlatString* props_cursor;
-    GCPtrFlatString* props_end;
-    HeapReceiverGuard* guard_array;
+    GCPtrFlatString* props_end; // also the start of HeapReceiverGuards
     uint32_t guard_length;
     uint32_t guard_key;
     uint32_t flags;
 
   private:
     /* While in compartment->enumerators, these form a doubly linked list. */
     NativeIterator* next_;
     NativeIterator* prev_;
@@ -67,16 +66,25 @@ struct NativeIterator
         auto* afterNonConst = const_cast<NativeIterator*>(immediatelyAfter);
         return reinterpret_cast<GCPtrFlatString*>(afterNonConst);
     }
 
     GCPtrFlatString* end() const {
         return props_end;
     }
 
+    HeapReceiverGuard* guardArray() const {
+        static_assert(alignof(ReceiverGuard) == alignof(GCPtrFlatString),
+                      "the end of all properties must be exactly aligned "
+                      "adequate to begin storing ReceiverGuards, else the "
+                      "full tacked-on memory won't be enough to store all "
+                      "properties/guards");
+        return reinterpret_cast<HeapReceiverGuard*>(props_end);
+    }
+
     size_t numKeys() const {
         return end() - begin();
     }
 
     JSObject* iterObj() const {
         return iterObj_;
     }
     GCPtrFlatString* current() const {