author | Jeff Walden <jwalden@mit.edu> |
Wed, 16 May 2018 23:24:28 -0700 (2018-05-17) | |
changeset 418921 | 7d83c7de94049fd53fec35e5e7eebf8134c52cc0 |
parent 418920 | 6ae525ee499f45683e3f5ee302652c3782467034 |
child 418922 | 7491ab23247fc11cca02bd0a4f54ed92f15b40f4 |
push id | 103419 |
push user | jwalden@mit.edu |
push date | Fri, 18 May 2018 19:33:51 +0000 (2018-05-18) |
treeherder | mozilla-inbound@7658d2d1e0d7 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jandem |
bugs | 1462540 |
milestone | 62.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
|
js/src/vm/Iteration.cpp | file | annotate | diff | comparison | revisions | |
js/src/vm/Iteration.h | file | annotate | diff | comparison | revisions |
--- 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 {