Bug 1520366 - Prepend LifoAlloc chunks when transferring them. r=nbp
authorTed Campbell <tcampbell@mozilla.com>
Tue, 22 Jan 2019 00:55:09 -0500
changeset 514900 13e451a690836e7b38a6bdb7677e9247fdbb6fc3
parent 514899 2e1923054d3b5103f13e257cd9d416d6679c1460
child 514901 acd0dadf80139d92223cf7506618621919418797
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1520366
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 1520366 - Prepend LifoAlloc chunks when transferring them. r=nbp When using LifoAlloc::transferFrom to merge allocators (such as for types), prepend the chunks to avoid wasted space at end of current last chunk. This helps usecases such as TypeInference to behave more predictably when merging small allocators. (Original implementation by :nbp)
js/src/ds/LifoAlloc.cpp
js/src/ds/LifoAlloc.h
--- a/js/src/ds/LifoAlloc.cpp
+++ b/js/src/ds/LifoAlloc.cpp
@@ -363,18 +363,18 @@ void LifoAlloc::steal(LifoAlloc* other) 
 
 void LifoAlloc::transferFrom(LifoAlloc* other) {
   MOZ_ASSERT(!markCount);
   MOZ_ASSERT(!other->markCount);
 
   incrementCurSize(other->curSize_);
   oversizeSize_ += other->oversizeSize_;
   appendUnused(std::move(other->unused_));
-  appendUsed(std::move(other->chunks_));
-  oversize_.appendAll(std::move(other->oversize_));
+  chunks_.prependAll(std::move(other->chunks_));
+  oversize_.prependAll(std::move(other->oversize_));
   other->curSize_ = 0;
   other->oversizeSize_ = 0;
 }
 
 void LifoAlloc::transferUnusedFrom(LifoAlloc* other) {
   MOZ_ASSERT(!markCount);
 
   size_t size = 0;
--- a/js/src/ds/LifoAlloc.h
+++ b/js/src/ds/LifoAlloc.h
@@ -169,16 +169,27 @@ class SingleLinkedList {
     } else {
       head_ = std::move(list.head_);
     }
     last_ = list.last_;
     list.last_ = nullptr;
     assertInvariants();
     list.assertInvariants();
   }
+  void steal(SingleLinkedList&& list) {
+    head_ = std::move(list.head_);
+    last_ = list.last_;
+    list.last_ = nullptr;
+    assertInvariants();
+    list.assertInvariants();
+  }
+  void prependAll(SingleLinkedList&& list) {
+    list.appendAll(std::move(*this));
+    steal(std::move(list));
+  }
   UniquePtr<T, D> popFirst() {
     MOZ_ASSERT(head_);
     UniquePtr<T, D> result = std::move(head_);
     head_ = std::move(result->next_);
     if (!head_) {
       last_ = nullptr;
     }
     assertInvariants();