| Index: src/heap/spaces.h
 | 
| diff --git a/src/heap/spaces.h b/src/heap/spaces.h
 | 
| index 59d8cfb6d9ed6d9d7c06d8e9d58689cb2950437e..f9b473d0de854520950cff14ef6fc49571d30adc 100644
 | 
| --- a/src/heap/spaces.h
 | 
| +++ b/src/heap/spaces.h
 | 
| @@ -14,6 +14,7 @@
 | 
|  #include "src/base/platform/mutex.h"
 | 
|  #include "src/flags.h"
 | 
|  #include "src/hashmap.h"
 | 
| +#include "src/heap/array-buffer-tracker.h"
 | 
|  #include "src/list.h"
 | 
|  #include "src/objects.h"
 | 
|  #include "src/utils.h"
 | 
| @@ -468,6 +469,8 @@ class MemoryChunk {
 | 
|      kSweepingInProgress,
 | 
|    };
 | 
|  
 | 
| +  enum ArrayBufferTrackerAccessMode { kDontCreate, kCreateIfNotPresent };
 | 
| +
 | 
|    // Every n write barrier invocations we go to runtime even though
 | 
|    // we could have handled it in generated code.  This lets us check
 | 
|    // whether we have hit the limit and should do some more marking.
 | 
| @@ -523,7 +526,8 @@ class MemoryChunk {
 | 
|        + kPointerSize      // AtomicValue next_chunk_
 | 
|        + kPointerSize      // AtomicValue prev_chunk_
 | 
|        // FreeListCategory categories_[kNumberOfCategories]
 | 
| -      + FreeListCategory::kSize * kNumberOfCategories;
 | 
| +      + FreeListCategory::kSize * kNumberOfCategories +
 | 
| +      kPointerSize;  // LocalArrayBufferTracker tracker_
 | 
|  
 | 
|    // We add some more space to the computed header size to amount for missing
 | 
|    // alignment requirements in our computation.
 | 
| @@ -642,6 +646,21 @@ class MemoryChunk {
 | 
|    void AllocateTypedOldToOldSlots();
 | 
|    void ReleaseTypedOldToOldSlots();
 | 
|  
 | 
| +  template <ArrayBufferTrackerAccessMode tracker_access>
 | 
| +  inline LocalArrayBufferTracker* local_tracker() {
 | 
| +    LocalArrayBufferTracker* tracker = local_tracker_.Value();
 | 
| +    if (tracker == nullptr && tracker_access == kCreateIfNotPresent) {
 | 
| +      tracker = new LocalArrayBufferTracker(heap_);
 | 
| +      if (!local_tracker_.TrySetValue(nullptr, tracker)) {
 | 
| +        tracker = local_tracker_.Value();
 | 
| +      }
 | 
| +      DCHECK_NOT_NULL(tracker);
 | 
| +    }
 | 
| +    return tracker;
 | 
| +  }
 | 
| +
 | 
| +  void ReleaseLocalTracker();
 | 
| +
 | 
|    Address area_start() { return area_start_; }
 | 
|    Address area_end() { return area_end_; }
 | 
|    int area_size() { return static_cast<int>(area_end() - area_start()); }
 | 
| @@ -824,6 +843,8 @@ class MemoryChunk {
 | 
|  
 | 
|    FreeListCategory categories_[kNumberOfCategories];
 | 
|  
 | 
| +  base::AtomicValue<LocalArrayBufferTracker*> local_tracker_;
 | 
| +
 | 
|   private:
 | 
|    void InitializeReservedMemory() { reservation_.Reset(); }
 | 
|  
 | 
| @@ -2300,6 +2321,16 @@ class PagedSpace : public Space {
 | 
|    inline void UnlinkFreeListCategories(Page* page);
 | 
|    inline intptr_t RelinkFreeListCategories(Page* page);
 | 
|  
 | 
| +  // Callback signature:
 | 
| +  //   void Callback(Page*);
 | 
| +  template <typename Callback>
 | 
| +  void ForAllPages(Callback callback) {
 | 
| +    PageIterator it(this);
 | 
| +    while (it.has_next()) {
 | 
| +      callback(it.next());
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
|   protected:
 | 
|    // PagedSpaces that should be included in snapshots have different, i.e.,
 | 
|    // smaller, initial pages.
 | 
| 
 |