| OLD | NEW | 
|    1 // Copyright 2016 the V8 project authors. All rights reserved. |    1 // Copyright 2016 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_SLOT_SET_H |    5 #ifndef V8_SLOT_SET_H | 
|    6 #define V8_SLOT_SET_H |    6 #define V8_SLOT_SET_H | 
|    7  |    7  | 
|    8 #include <stack> |    8 #include <stack> | 
|    9  |    9  | 
|   10 #include "src/allocation.h" |   10 #include "src/allocation.h" | 
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   73       uint32_t cell = current_bucket[cell_index].Value(); |   73       uint32_t cell = current_bucket[cell_index].Value(); | 
|   74       if (cell) { |   74       if (cell) { | 
|   75         uint32_t bit_mask = 1u << bit_index; |   75         uint32_t bit_mask = 1u << bit_index; | 
|   76         if (cell & bit_mask) { |   76         if (cell & bit_mask) { | 
|   77           current_bucket[cell_index].ClearBit(bit_index); |   77           current_bucket[cell_index].ClearBit(bit_index); | 
|   78         } |   78         } | 
|   79       } |   79       } | 
|   80     } |   80     } | 
|   81   } |   81   } | 
|   82  |   82  | 
|   83   void PreFreeEmptyBucket(int bucket_index) { |  | 
|   84     base::AtomicValue<uint32_t>* bucket_ptr = bucket[bucket_index].Value(); |  | 
|   85     if (bucket_ptr != nullptr) { |  | 
|   86       base::LockGuard<base::Mutex> guard(&to_be_freed_buckets_mutex_); |  | 
|   87       to_be_freed_buckets_.push(bucket_ptr); |  | 
|   88       bucket[bucket_index].SetValue(nullptr); |  | 
|   89     } |  | 
|   90   } |  | 
|   91  |  | 
|   92   // The slot offsets specify a range of slots at addresses: |   83   // The slot offsets specify a range of slots at addresses: | 
|   93   // [page_start_ + start_offset ... page_start_ + end_offset). |   84   // [page_start_ + start_offset ... page_start_ + end_offset). | 
|   94   void RemoveRange(int start_offset, int end_offset, EmptyBucketMode mode) { |   85   void RemoveRange(int start_offset, int end_offset, EmptyBucketMode mode) { | 
|   95     CHECK_LE(end_offset, 1 << kPageSizeBits); |   86     CHECK_LE(end_offset, 1 << kPageSizeBits); | 
|   96     DCHECK_LE(start_offset, end_offset); |   87     DCHECK_LE(start_offset, end_offset); | 
|   97     int start_bucket, start_cell, start_bit; |   88     int start_bucket, start_cell, start_bit; | 
|   98     SlotToIndices(start_offset, &start_bucket, &start_cell, &start_bit); |   89     SlotToIndices(start_offset, &start_bucket, &start_cell, &start_bit); | 
|   99     int end_bucket, end_cell, end_bit; |   90     int end_bucket, end_cell, end_bit; | 
|  100     SlotToIndices(end_offset, &end_bucket, &end_cell, &end_bit); |   91     SlotToIndices(end_offset, &end_bucket, &end_cell, &end_bit); | 
|  101     uint32_t start_mask = (1u << start_bit) - 1; |   92     uint32_t start_mask = (1u << start_bit) - 1; | 
|  102     uint32_t end_mask = ~((1u << end_bit) - 1); |   93     uint32_t end_mask = ~((1u << end_bit) - 1); | 
|  103     if (start_bucket == end_bucket && start_cell == end_cell) { |   94     if (start_bucket == end_bucket && start_cell == end_cell) { | 
|  104       ClearCell(start_bucket, start_cell, ~(start_mask | end_mask)); |   95       ClearCell(start_bucket, start_cell, ~(start_mask | end_mask)); | 
|  105       return; |   96       return; | 
|  106     } |   97     } | 
|  107     int current_bucket = start_bucket; |   98     int current_bucket = start_bucket; | 
|  108     int current_cell = start_cell; |   99     int current_cell = start_cell; | 
|  109     ClearCell(current_bucket, current_cell, ~start_mask); |  100     ClearCell(current_bucket, current_cell, ~start_mask); | 
|  110     current_cell++; |  101     current_cell++; | 
 |  102     base::AtomicValue<uint32_t>* bucket_ptr = bucket[current_bucket].Value(); | 
|  111     if (current_bucket < end_bucket) { |  103     if (current_bucket < end_bucket) { | 
|  112       if (bucket[current_bucket].Value() != nullptr) { |  104       if (bucket_ptr != nullptr) { | 
|  113         while (current_cell < kCellsPerBucket) { |  105         ClearBucket(bucket_ptr, current_cell, kCellsPerBucket); | 
|  114           bucket[current_bucket].Value()[current_cell].SetValue(0); |  | 
|  115           current_cell++; |  | 
|  116         } |  | 
|  117       } |  106       } | 
|  118       // The rest of the current bucket is cleared. |  107       // The rest of the current bucket is cleared. | 
|  119       // Move on to the next bucket. |  108       // Move on to the next bucket. | 
|  120       current_bucket++; |  109       current_bucket++; | 
|  121       current_cell = 0; |  110       current_cell = 0; | 
|  122     } |  111     } | 
|  123     DCHECK(current_bucket == end_bucket || |  112     DCHECK(current_bucket == end_bucket || | 
|  124            (current_bucket < end_bucket && current_cell == 0)); |  113            (current_bucket < end_bucket && current_cell == 0)); | 
|  125     while (current_bucket < end_bucket) { |  114     while (current_bucket < end_bucket) { | 
|  126       if (mode == PREFREE_EMPTY_BUCKETS) { |  115       if (mode == PREFREE_EMPTY_BUCKETS) { | 
|  127         PreFreeEmptyBucket(current_bucket); |  116         PreFreeEmptyBucket(current_bucket); | 
|  128       } else if (mode == FREE_EMPTY_BUCKETS) { |  117       } else if (mode == FREE_EMPTY_BUCKETS) { | 
|  129         ReleaseBucket(current_bucket); |  118         ReleaseBucket(current_bucket); | 
 |  119       } else { | 
 |  120         DCHECK(mode == KEEP_EMPTY_BUCKETS); | 
 |  121         bucket_ptr = bucket[current_bucket].Value(); | 
 |  122         if (bucket_ptr) { | 
 |  123           ClearBucket(bucket_ptr, 0, kCellsPerBucket); | 
 |  124         } | 
|  130       } |  125       } | 
|  131       current_bucket++; |  126       current_bucket++; | 
|  132     } |  127     } | 
|  133     // All buckets between start_bucket and end_bucket are cleared. |  128     // All buckets between start_bucket and end_bucket are cleared. | 
 |  129     bucket_ptr = bucket[current_bucket].Value(); | 
|  134     DCHECK(current_bucket == end_bucket && current_cell <= end_cell); |  130     DCHECK(current_bucket == end_bucket && current_cell <= end_cell); | 
|  135     if (current_bucket == kBuckets || |  131     if (current_bucket == kBuckets || bucket_ptr == nullptr) { | 
|  136         bucket[current_bucket].Value() == nullptr) { |  | 
|  137       return; |  132       return; | 
|  138     } |  133     } | 
|  139     while (current_cell < end_cell) { |  134     while (current_cell < end_cell) { | 
|  140       bucket[current_bucket].Value()[current_cell].SetValue(0); |  135       bucket_ptr[current_cell].SetValue(0); | 
|  141       current_cell++; |  136       current_cell++; | 
|  142     } |  137     } | 
|  143     // All cells between start_cell and end_cell are cleared. |  138     // All cells between start_cell and end_cell are cleared. | 
|  144     DCHECK(current_bucket == end_bucket && current_cell == end_cell); |  139     DCHECK(current_bucket == end_bucket && current_cell == end_cell); | 
|  145     ClearCell(end_bucket, end_cell, ~end_mask); |  140     ClearCell(end_bucket, end_cell, ~end_mask); | 
|  146   } |  141   } | 
|  147  |  142  | 
|  148   // The slot offset specifies a slot at address page_start_ + slot_offset. |  143   // The slot offset specifies a slot at address page_start_ + slot_offset. | 
|  149   bool Lookup(int slot_offset) { |  144   bool Lookup(int slot_offset) { | 
|  150     int bucket_index, cell_index, bit_index; |  145     int bucket_index, cell_index, bit_index; | 
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  235  |  230  | 
|  236   base::AtomicValue<uint32_t>* AllocateBucket() { |  231   base::AtomicValue<uint32_t>* AllocateBucket() { | 
|  237     base::AtomicValue<uint32_t>* result = |  232     base::AtomicValue<uint32_t>* result = | 
|  238         NewArray<base::AtomicValue<uint32_t>>(kCellsPerBucket); |  233         NewArray<base::AtomicValue<uint32_t>>(kCellsPerBucket); | 
|  239     for (int i = 0; i < kCellsPerBucket; i++) { |  234     for (int i = 0; i < kCellsPerBucket; i++) { | 
|  240       result[i].SetValue(0); |  235       result[i].SetValue(0); | 
|  241     } |  236     } | 
|  242     return result; |  237     return result; | 
|  243   } |  238   } | 
|  244  |  239  | 
 |  240   void ClearBucket(base::AtomicValue<uint32_t>* bucket, int start_cell, | 
 |  241                    int end_cell) { | 
 |  242     DCHECK_GE(start_cell, 0); | 
 |  243     DCHECK_LE(end_cell, kCellsPerBucket); | 
 |  244     int current_cell = start_cell; | 
 |  245     while (current_cell < kCellsPerBucket) { | 
 |  246       bucket[current_cell].SetValue(0); | 
 |  247       current_cell++; | 
 |  248     } | 
 |  249   } | 
 |  250  | 
 |  251   void PreFreeEmptyBucket(int bucket_index) { | 
 |  252     base::AtomicValue<uint32_t>* bucket_ptr = bucket[bucket_index].Value(); | 
 |  253     if (bucket_ptr != nullptr) { | 
 |  254       base::LockGuard<base::Mutex> guard(&to_be_freed_buckets_mutex_); | 
 |  255       to_be_freed_buckets_.push(bucket_ptr); | 
 |  256       bucket[bucket_index].SetValue(nullptr); | 
 |  257     } | 
 |  258   } | 
 |  259  | 
|  245   void ReleaseBucket(int bucket_index) { |  260   void ReleaseBucket(int bucket_index) { | 
|  246     DeleteArray<base::AtomicValue<uint32_t>>(bucket[bucket_index].Value()); |  261     DeleteArray<base::AtomicValue<uint32_t>>(bucket[bucket_index].Value()); | 
|  247     bucket[bucket_index].SetValue(nullptr); |  262     bucket[bucket_index].SetValue(nullptr); | 
|  248   } |  263   } | 
|  249  |  264  | 
|  250   void ClearCell(int bucket_index, int cell_index, uint32_t mask) { |  265   void ClearCell(int bucket_index, int cell_index, uint32_t mask) { | 
|  251     if (bucket_index < kBuckets) { |  266     if (bucket_index < kBuckets) { | 
|  252       base::AtomicValue<uint32_t>* cells = bucket[bucket_index].Value(); |  267       base::AtomicValue<uint32_t>* cells = bucket[bucket_index].Value(); | 
|  253       if (cells != nullptr) { |  268       if (cells != nullptr) { | 
|  254         uint32_t cell = cells[cell_index].Value(); |  269         uint32_t cell = cells[cell_index].Value(); | 
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  484   Address page_start_; |  499   Address page_start_; | 
|  485   base::AtomicValue<Chunk*> chunk_; |  500   base::AtomicValue<Chunk*> chunk_; | 
|  486   base::Mutex to_be_freed_chunks_mutex_; |  501   base::Mutex to_be_freed_chunks_mutex_; | 
|  487   std::stack<Chunk*> to_be_freed_chunks_; |  502   std::stack<Chunk*> to_be_freed_chunks_; | 
|  488 }; |  503 }; | 
|  489  |  504  | 
|  490 }  // namespace internal |  505 }  // namespace internal | 
|  491 }  // namespace v8 |  506 }  // namespace v8 | 
|  492  |  507  | 
|  493 #endif  // V8_SLOT_SET_H |  508 #endif  // V8_SLOT_SET_H | 
| OLD | NEW |