Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 39c30336ea755b86a1c9a25fccbba19d76adb284..8639bde44ade6880eb53e49be6289d03f08691a0 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -7502,7 +7502,7 @@ Handle<FixedArray> JSObject::GetEnumPropertyKeys(Handle<JSObject> object, |
KeyAccumulator::~KeyAccumulator() { |
- for (int i = 0; i < elements_.length(); i++) { |
+ for (uint32_t i = 0; i < elements_.size(); i++) { |
Igor Sheludko
2015/10/22 21:42:57
I guess it should be size_t or you will have compi
Camillo Bruni
2015/10/23 08:56:35
right
|
delete elements_[i]; |
} |
} |
@@ -7523,7 +7523,7 @@ Handle<FixedArray> KeyAccumulator::GetKeys(GetKeysConversion convert) { |
Handle<FixedArray> result = isolate_->factory()->NewFixedArray(length_); |
int index = 0; |
int properties_index = 0; |
- for (int level = 0; level < levelLengths_.length(); level++) { |
+ for (uint32_t level = 0; level < levelLengths_.size(); level++) { |
Igor Sheludko
2015/10/22 21:42:57
Ditto.
|
int num_total = levelLengths_[level]; |
int num_elements = 0; |
if (num_total < 0) { |
@@ -7531,9 +7531,9 @@ Handle<FixedArray> KeyAccumulator::GetKeys(GetKeysConversion convert) { |
// proxy, hence we skip the integer keys in |elements_| since proxies |
// define the complete ordering. |
num_total = -num_total; |
- } else if (level < elements_.length()) { |
- List<uint32_t>* elements = elements_[level]; |
- num_elements = elements->length(); |
+ } else if (level < elements_.size()) { |
+ std::vector<uint32_t>* elements = elements_[level]; |
+ num_elements = static_cast<int>(elements->size()); |
for (int i = 0; i < num_elements; i++) { |
Handle<Object> key; |
if (convert == KEEP_NUMBERS) { |
@@ -7561,22 +7561,8 @@ Handle<FixedArray> KeyAccumulator::GetKeys(GetKeysConversion convert) { |
namespace { |
-class FindKey { |
- public: |
- explicit FindKey(uint32_t key) : key_(key) {} |
- int operator()(uint32_t* entry) { |
- if (*entry == key_) return 0; |
- return *entry < key_ ? -1 : 1; |
- } |
- |
- private: |
- uint32_t key_; |
-}; |
- |
- |
-bool AccumulatorHasKey(List<uint32_t>* sub_elements, uint32_t key) { |
- int index = SortedListBSearch(*sub_elements, FindKey(key)); |
- return index != -1; |
+bool AccumulatorHasKey(std::vector<uint32_t>* sub_elements, uint32_t key) { |
+ return std::binary_search(sub_elements->begin(), sub_elements->end(), key); |
} |
} // namespace |
@@ -7584,12 +7570,23 @@ bool AccumulatorHasKey(List<uint32_t>* sub_elements, uint32_t key) { |
bool KeyAccumulator::AddKey(uint32_t key) { |
// Make sure we do not add keys to a proxy-level (see AddKeysFromProxy). |
+ // We mark proxy-levels with a negative length |
DCHECK_LE(0, levelLength_); |
- int lookup_limit = elements_.length(); |
- for (int i = 0; i < lookup_limit; i++) { |
- if (AccumulatorHasKey(elements_[i], key)) return false; |
+ // Binary search over all but the last level. The last one might not be |
+ // sorted yet. |
+ for (uint32_t i = 1; i < elements_.size(); i++) { |
Igor Sheludko
2015/10/22 21:42:57
Ditto.
|
+ if (AccumulatorHasKey(elements_[i - 1], key)) return false; |
+ } |
+ if (elementKeysAddCheckLimit_ == INCLUDE_CURRENT_LEVEL) { |
+ // the last level may have not been sorted yet, hence we have to do |
+ // a linear search here if required. |
+ auto last_level = elements_.back(); |
+ if (std::find(last_level->begin(), last_level->end(), key) != |
+ last_level->end()) { |
+ return false; |
+ } |
} |
- elements_[lookup_limit - 1]->Add(key); |
+ elements_.back()->push_back(key); |
length_++; |
levelLength_++; |
return true; |
@@ -7683,32 +7680,28 @@ void KeyAccumulator::AddKeysFromProxy(Handle<JSObject> array_like) { |
} |
-namespace { |
- |
-// Used for sorting indices in a List<uint32_t>. |
-int compareUInt32(const uint32_t* ap, const uint32_t* bp) { |
- uint32_t a = *ap; |
- uint32_t b = *bp; |
- return (a == b) ? 0 : (a < b) ? -1 : 1; |
+void KeyAccumulator::AddKeysFromInterceptor(Handle<JSObject> array_like) { |
+ // The accumulator might introduce duplicates for the current level, |
+ // hence we set INCLUDE_CURRENT_LEVEL |
Igor Sheludko
2015/10/22 21:42:57
DCHECK_EQ(EXCLUDE_CURRENT_LEVEL, elementKeysAddChe
|
+ elementKeysAddCheckLimit_ = INCLUDE_CURRENT_LEVEL; |
Igor Sheludko
2015/10/22 21:42:57
WDYT about adding all the elements without checkin
Camillo Bruni
2015/10/26 09:53:48
ah right, makes sense :)
|
+ AddKeys(array_like, CONVERT_TO_ARRAY_INDEX); |
+ elementKeysAddCheckLimit_ = EXCLUDE_CURRENT_LEVEL; |
} |
-} // namespace |
- |
- |
void KeyAccumulator::SortCurrentElementsList() { |
- if (elements_.length() == 0) return; |
- List<uint32_t>* element_keys = elements_[elements_.length() - 1]; |
- element_keys->Sort(&compareUInt32); |
+ if (elements_.empty()) return; |
+ std::vector<uint32_t>* element_keys = elements_.back(); |
+ std::sort(element_keys->begin(), element_keys->end()); |
} |
void KeyAccumulator::NextPrototype() { |
// Store the protoLength on the first call of this method. |
- if (!elements_.is_empty()) { |
- levelLengths_.Add(levelLength_); |
+ if (!elements_.empty()) { |
+ levelLengths_.push_back(levelLength_); |
} |
- elements_.Add(new List<uint32_t>()); |
+ elements_.push_back(new std::vector<uint32_t>()); |
levelLength_ = 0; |
} |
@@ -7767,7 +7760,7 @@ MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, |
Handle<JSObject> result; |
if (JSObject::GetKeysForIndexedInterceptor(current, object) |
.ToHandle(&result)) { |
- accumulator.AddKeys(result, CONVERT_TO_ARRAY_INDEX); |
+ accumulator.AddKeysFromInterceptor(result); |
} |
} |