Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef VM_OBJECT_SET_H_ | 5 #ifndef VM_OBJECT_SET_H_ |
| 6 #define VM_OBJECT_SET_H_ | 6 #define VM_OBJECT_SET_H_ |
| 7 | 7 |
| 8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 #include "vm/bit_vector.h" | |
| 9 #include "vm/globals.h" | 10 #include "vm/globals.h" |
| 10 #include "vm/raw_object.h" | 11 #include "vm/raw_object.h" |
| 12 #include "vm/zone.h" | |
| 11 | 13 |
| 12 namespace dart { | 14 namespace dart { |
| 13 | 15 |
| 14 class ObjectSet { | 16 class ObjectSetRegion : public ZoneAllocated { |
| 15 public: | 17 public: |
| 16 ObjectSet() { | 18 ObjectSetRegion(Zone* zone, uword start, uword end) |
| 17 Init(0, 0); | 19 : start_(start), |
| 20 end_(end), | |
| 21 bit_vector_(zone, (end - start) >> kWordSizeLog2), | |
| 22 next_(NULL) { | |
| 18 } | 23 } |
| 19 | 24 |
| 20 ObjectSet(uword start, uword end) { | 25 bool ContainsAddress(uword address) { |
| 21 Init(start, end); | 26 return address >= start_ && address < end_; |
| 22 } | 27 } |
| 23 | 28 |
| 24 ~ObjectSet() { | 29 intptr_t IndexForAddress(uword address) { |
| 25 delete[] allocation_; | 30 ASSERT(Utils::IsAligned(address, kWordSize)); |
| 31 return (address - start_) >> kWordSizeLog2; | |
| 26 } | 32 } |
| 27 | 33 |
| 28 void Init(uword start, uword end) { | 34 void AddObject(uword address) { |
| 29 start_ = start; | 35 bit_vector_.Add(IndexForAddress(address)); |
| 30 end_ = end; | 36 } |
| 31 ASSERT(start_ <= end_); | 37 |
| 32 size_ = SizeFor((end_ - start_) >> kWordSizeLog2); | 38 bool ContainsObject(uword address) { |
| 33 allocation_ = new uword[size_]; | 39 return bit_vector_.Contains(IndexForAddress(address)); |
| 34 const intptr_t skipped_bitfield_words = | 40 } |
| 35 (start >> kWordSizeLog2) / kBitsPerWord; | 41 |
| 36 data_ = &allocation_[-skipped_bitfield_words]; | 42 ObjectSetRegion* next() { return next_; } |
| 37 ASSERT(allocation_ == &data_[skipped_bitfield_words]); | 43 void set_next(ObjectSetRegion* region) { next_ = region; } |
| 38 Clear(); | 44 |
| 45 private: | |
| 46 uword start_; | |
| 47 uword end_; | |
| 48 BitVector bit_vector_; | |
| 49 ObjectSetRegion* next_; | |
| 50 }; | |
| 51 | |
| 52 class ObjectSet : public ZoneAllocated { | |
| 53 public: | |
| 54 explicit ObjectSet(Zone* zone) : zone_(zone), head_(NULL) { } | |
| 55 | |
| 56 void AddRegion(uword start, uword end) { | |
| 57 ObjectSetRegion* region = new(zone_) ObjectSetRegion(zone_, start, end); | |
| 58 region->set_next(head_); | |
| 59 head_ = region; | |
| 39 } | 60 } |
| 40 | 61 |
| 41 bool Contains(RawObject* raw_obj) const { | 62 bool Contains(RawObject* raw_obj) const { |
| 42 uword raw_addr = RawObject::ToAddr(raw_obj); | 63 uword raw_addr = RawObject::ToAddr(raw_obj); |
| 43 ASSERT(raw_addr >= start_); | 64 for (ObjectSetRegion* region = head_; |
|
zra
2016/09/16 22:30:22
How slow is this? I guess we'll have to monitor th
rmacnak
2016/09/16 22:39:49
I didn't see timeouts locally with another workspa
| |
| 44 ASSERT(raw_addr < end_); | 65 region != NULL; |
| 45 uword i = raw_addr >> kWordSizeLog2; | 66 region = region->next()) { |
| 46 uword mask = (static_cast<uword>(1) << (i % kBitsPerWord)); | 67 if (region->ContainsAddress(raw_addr)) { |
| 47 return (data_[i / kBitsPerWord] & mask) != 0; | 68 return region->ContainsObject(raw_addr); |
| 69 } | |
| 70 } | |
| 71 return false; | |
| 48 } | 72 } |
| 49 | 73 |
| 50 void Add(RawObject* raw_obj) { | 74 void Add(RawObject* raw_obj) { |
| 51 uword raw_addr = RawObject::ToAddr(raw_obj); | 75 uword raw_addr = RawObject::ToAddr(raw_obj); |
| 52 ASSERT(raw_addr >= start_); | 76 for (ObjectSetRegion* region = head_; |
| 53 ASSERT(raw_addr < end_); | 77 region != NULL; |
| 54 uword i = raw_addr >> kWordSizeLog2; | 78 region = region->next()) { |
| 55 data_[i / kBitsPerWord] |= (static_cast<uword>(1) << (i % kBitsPerWord)); | 79 if (region->ContainsAddress(raw_addr)) { |
| 56 min_ = Utils::Minimum(raw_addr, min_); | 80 return region->AddObject(raw_addr); |
| 57 max_ = Utils::Maximum(raw_addr, max_); | 81 } |
| 58 } | |
| 59 | |
| 60 void Resize(uword start, uword end) { | |
| 61 if (start_ != start || end_ != end) { | |
| 62 delete[] allocation_; | |
| 63 Init(start, end); | |
| 64 } | 82 } |
| 65 } | 83 FATAL("Address not in any heap region"); |
| 66 | |
| 67 void Clear() { | |
| 68 memset(allocation_, 0, (size_ * sizeof(allocation_[0]))); | |
| 69 min_ = end_; | |
| 70 max_ = start_; | |
| 71 } | |
| 72 | |
| 73 void FastClear() { | |
| 74 uword i = min_ >> kWordSizeLog2; | |
| 75 memset(&data_[i / kBitsPerWord], | |
| 76 0, | |
| 77 sizeof(uword) * SizeFor((max_ + 1 - min_) >> kWordSizeLog2)); | |
| 78 min_ = end_; | |
| 79 max_ = start_; | |
| 80 } | 84 } |
| 81 | 85 |
| 82 private: | 86 private: |
| 83 static intptr_t SizeFor(intptr_t length) { | 87 Zone* zone_; |
| 84 return 1 + ((length - 1) / kBitsPerWord); | 88 ObjectSetRegion* head_; |
| 85 } | |
| 86 | |
| 87 // Biased data pointer aliased to allocation_. This value can be | |
| 88 // indexed without adjusting for the starting address of the heap. | |
| 89 uword* data_; | |
| 90 | |
| 91 // Allocated data pointer. | |
| 92 uword* allocation_; | |
| 93 | |
| 94 // Allocation size in uwords. | |
| 95 intptr_t size_; | |
| 96 | |
| 97 // Lowest possible heap address, inclusive. | |
| 98 uword start_; | |
| 99 | |
| 100 // Highest possible heap address, exclusive. | |
| 101 uword end_; | |
| 102 | |
| 103 // The inclusive minimum address set in this ObjectMap. | |
| 104 // Used by FastClear | |
| 105 uword min_; | |
| 106 | |
| 107 // The inclusive maximum address in this ObjectMap. | |
| 108 // Used by FastClear | |
| 109 uword max_; | |
| 110 | |
| 111 DISALLOW_COPY_AND_ASSIGN(ObjectSet); | |
| 112 }; | 89 }; |
| 113 | 90 |
| 114 } // namespace dart | 91 } // namespace dart |
| 115 | 92 |
| 116 #endif // VM_OBJECT_SET_H_ | 93 #endif // VM_OBJECT_SET_H_ |
| OLD | NEW |