| OLD | NEW | 
|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #ifndef V8_HEAP_ARRAY_BUFFER_TRACKER_H_ | 5 #ifndef V8_HEAP_ARRAY_BUFFER_TRACKER_H_ | 
| 6 #define V8_HEAP_ARRAY_BUFFER_TRACKER_H_ | 6 #define V8_HEAP_ARRAY_BUFFER_TRACKER_H_ | 
| 7 | 7 | 
| 8 #include <map> | 8 #include <map> | 
| 9 | 9 | 
| 10 #include "src/base/platform/mutex.h" | 10 #include "src/base/platform/mutex.h" | 
| 11 #include "src/globals.h" | 11 #include "src/globals.h" | 
| 12 | 12 | 
| 13 namespace v8 { | 13 namespace v8 { | 
| 14 namespace internal { | 14 namespace internal { | 
| 15 | 15 | 
| 16 // Forward declarations. | 16 // Forward declarations. | 
| 17 class Heap; | 17 class Heap; | 
|  | 18 class Page; | 
| 18 class JSArrayBuffer; | 19 class JSArrayBuffer; | 
| 19 | 20 | 
|  | 21 // LocalArrayBufferTracker is tracker for live and dead JSArrayBuffer objects. | 
|  | 22 // | 
|  | 23 // It consists of two sets, a live, and a not yet discovered set of buffers. | 
|  | 24 // Upon registration (in the ArrayBufferTracker) the buffers are added to both | 
|  | 25 // sets. When a buffer is encountered as live (or added is live) it is removed | 
|  | 26 // from the not yet discovered set. Finally, after each round (sometime during | 
|  | 27 // GC) the left over not yet discovered buffers are cleaned up. Upon starting | 
|  | 28 // a new round the not yet discovered buffers are initialized from the live set. | 
|  | 29 // | 
|  | 30 // Caveats: | 
|  | 31 // - Between cleaning up the buffers using |Free| we always need a |Reset| and | 
|  | 32 //   thus another marking phase. | 
|  | 33 class LocalArrayBufferTracker { | 
|  | 34  public: | 
|  | 35   typedef std::pair<void*, size_t> Value; | 
|  | 36   typedef JSArrayBuffer* Key; | 
|  | 37 | 
|  | 38   enum LivenessIndicator { kForwardingPointer, kMarkBit }; | 
|  | 39   enum CallbackResult { kKeepEntry, kKeepAndUpdateEntry, kRemoveEntry }; | 
|  | 40 | 
|  | 41   explicit LocalArrayBufferTracker(Heap* heap) : heap_(heap), started_(false) {} | 
|  | 42   ~LocalArrayBufferTracker(); | 
|  | 43 | 
|  | 44   void Add(Key key, const Value& value); | 
|  | 45   void AddLive(Key key, const Value& value); | 
|  | 46   Value Remove(Key key); | 
|  | 47   void MarkLive(Key key); | 
|  | 48   bool IsEmpty(); | 
|  | 49 | 
|  | 50   // Resets the tracking set, i.e., not yet discovered buffers are initialized | 
|  | 51   // from the remaining live set of buffers. | 
|  | 52   void Reset(); | 
|  | 53 | 
|  | 54   // Frees up any dead backing stores of not yet discovered array buffers. | 
|  | 55   // Requires that the buffers have been properly marked using MarkLive. | 
|  | 56   void FreeDead(); | 
|  | 57 | 
|  | 58   // Scans the whole tracker and decides based on liveness_indicator whether | 
|  | 59   // a JSArrayBuffer is still considered live. | 
|  | 60   template <LivenessIndicator liveness_indicator> | 
|  | 61   inline void ScanAndFreeDead(); | 
|  | 62 | 
|  | 63   bool IsTracked(Key key) { return live_.find(key) != live_.end(); } | 
|  | 64 | 
|  | 65  private: | 
|  | 66   // TODO(mlippautz): Switch to unordered_map once it is supported on all | 
|  | 67   // platforms. | 
|  | 68   typedef std::map<Key, Value> TrackingMap; | 
|  | 69 | 
|  | 70   // Processes buffers one by one. The CallbackResult decides whether the buffer | 
|  | 71   // will be dropped or not. | 
|  | 72   // | 
|  | 73   // Callback should be of type: | 
|  | 74   //   CallbackResult fn(JSArrayBuffer*, JSArrayBuffer**); | 
|  | 75   template <typename Callback> | 
|  | 76   inline void Process(Callback callback); | 
|  | 77 | 
|  | 78   Heap* heap_; | 
|  | 79 | 
|  | 80   // |live_| maps tracked JSArrayBuffers to the internally allocated backing | 
|  | 81   // store and length. For each GC round |not_yet_discovered_| is initialized | 
|  | 82   // as a copy of |live_|. Upon finding a JSArrayBuffer during GC, the buffer | 
|  | 83   // is removed from |not_yet_discovered_|. At the end of a GC, we free up the | 
|  | 84   // remaining JSArrayBuffers in |not_yet_discovered_|. | 
|  | 85   TrackingMap live_; | 
|  | 86   TrackingMap not_yet_discovered_; | 
|  | 87 | 
|  | 88   bool started_; | 
|  | 89 }; | 
|  | 90 | 
| 20 class ArrayBufferTracker { | 91 class ArrayBufferTracker { | 
| 21  public: | 92  public: | 
| 22   explicit ArrayBufferTracker(Heap* heap) : heap_(heap) {} | 93   explicit ArrayBufferTracker(Heap* heap) : heap_(heap) {} | 
| 23   ~ArrayBufferTracker(); | 94   ~ArrayBufferTracker(); | 
| 24 | 95 | 
| 25   inline Heap* heap() { return heap_; } |  | 
| 26 |  | 
| 27   // The following methods are used to track raw C++ pointers to externally | 96   // The following methods are used to track raw C++ pointers to externally | 
| 28   // allocated memory used as backing store in live array buffers. | 97   // allocated memory used as backing store in live array buffers. | 
| 29 | 98 | 
| 30   // A new ArrayBuffer was created with |data| as backing store. | 99   // Register/unregister a new JSArrayBuffer |buffer| for tracking. | 
| 31   void RegisterNew(JSArrayBuffer* buffer); | 100   // |track_live| indicates whether marking will still visit the buffer and we | 
| 32 | 101   // can delay marking it as live. | 
| 33   // The backing store |data| is no longer owned by V8. | 102   void RegisterNew(JSArrayBuffer* buffer, bool track_live); | 
| 34   void Unregister(JSArrayBuffer* buffer); | 103   void Unregister(JSArrayBuffer* buffer); | 
| 35 | 104 | 
| 36   // A live ArrayBuffer was discovered during marking/scavenge. | 105   // Frees all backing store pointers for dead JSArrayBuffers in new space. | 
|  | 106   void FreeDeadInNewSpace(); | 
|  | 107 | 
|  | 108   void ResetTrackersInOldSpace(); | 
|  | 109 | 
|  | 110   // A live JSArrayBuffer was discovered during marking. | 
| 37   void MarkLive(JSArrayBuffer* buffer); | 111   void MarkLive(JSArrayBuffer* buffer); | 
| 38 | 112 | 
| 39   // Frees all backing store pointers that weren't discovered in the previous | 113  private: | 
| 40   // marking or scavenge phase. | 114   Heap* heap_; | 
| 41   void FreeDead(bool from_scavenge); | 115 }; | 
| 42 | 116 | 
| 43   // Prepare for a new scavenge phase. A new marking phase is implicitly |  | 
| 44   // prepared by finishing the previous one. |  | 
| 45   void PrepareDiscoveryInNewSpace(); |  | 
| 46 |  | 
| 47   // An ArrayBuffer moved from new space to old space. |  | 
| 48   void Promote(JSArrayBuffer* buffer); |  | 
| 49 |  | 
| 50  private: |  | 
| 51   base::Mutex mutex_; |  | 
| 52   Heap* heap_; |  | 
| 53 |  | 
| 54   // |live_array_buffers_| maps externally allocated memory used as backing |  | 
| 55   // store for ArrayBuffers to the length of the respective memory blocks. |  | 
| 56   // |  | 
| 57   // At the beginning of mark/compact, |not_yet_discovered_array_buffers_| is |  | 
| 58   // a copy of |live_array_buffers_| and we remove pointers as we discover live |  | 
| 59   // ArrayBuffer objects during marking. At the end of mark/compact, the |  | 
| 60   // remaining memory blocks can be freed. |  | 
| 61   std::map<void*, size_t> live_array_buffers_; |  | 
| 62   std::map<void*, size_t> not_yet_discovered_array_buffers_; |  | 
| 63 |  | 
| 64   // To be able to free memory held by ArrayBuffers during scavenge as well, we |  | 
| 65   // have a separate list of allocated memory held by ArrayBuffers in new space. |  | 
| 66   // |  | 
| 67   // Since mark/compact also evacuates the new space, all pointers in the |  | 
| 68   // |live_array_buffers_for_scavenge_| list are also in the |  | 
| 69   // |live_array_buffers_| list. |  | 
| 70   std::map<void*, size_t> live_array_buffers_for_scavenge_; |  | 
| 71   std::map<void*, size_t> not_yet_discovered_array_buffers_for_scavenge_; |  | 
| 72 }; |  | 
| 73 }  // namespace internal | 117 }  // namespace internal | 
| 74 }  // namespace v8 | 118 }  // namespace v8 | 
| 75 #endif  // V8_HEAP_ARRAY_BUFFER_TRACKER_H_ | 119 #endif  // V8_HEAP_ARRAY_BUFFER_TRACKER_H_ | 
| OLD | NEW | 
|---|