Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 8944 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8955 */ | 8955 */ |
| 8956 class ArrayConcatVisitor { | 8956 class ArrayConcatVisitor { |
| 8957 public: | 8957 public: |
| 8958 ArrayConcatVisitor(Isolate* isolate, | 8958 ArrayConcatVisitor(Isolate* isolate, |
| 8959 Handle<FixedArray> storage, | 8959 Handle<FixedArray> storage, |
| 8960 bool fast_elements) : | 8960 bool fast_elements) : |
| 8961 isolate_(isolate), | 8961 isolate_(isolate), |
| 8962 storage_(Handle<FixedArray>::cast( | 8962 storage_(Handle<FixedArray>::cast( |
| 8963 isolate->global_handles()->Create(*storage))), | 8963 isolate->global_handles()->Create(*storage))), |
| 8964 index_offset_(0u), | 8964 index_offset_(0u), |
| 8965 fast_elements_(fast_elements) { } | 8965 fast_elements_(fast_elements), |
| 8966 exceeds_array_limit_(false) { } | |
| 8966 | 8967 |
| 8967 ~ArrayConcatVisitor() { | 8968 ~ArrayConcatVisitor() { |
| 8968 clear_storage(); | 8969 clear_storage(); |
| 8969 } | 8970 } |
| 8970 | 8971 |
| 8971 void visit(uint32_t i, Handle<Object> elm) { | 8972 void visit(uint32_t i, Handle<Object> elm) { |
| 8972 if (i >= JSObject::kMaxElementCount - index_offset_) return; | 8973 if (i >= JSObject::kMaxElementCount - index_offset_) { |
|
Toon Verwaest
2013/04/04 12:52:24
Seems like an off-by-one error.
What about index_o
| |
| 8974 exceeds_array_limit_ = true; | |
| 8975 return; | |
| 8976 } | |
| 8973 uint32_t index = index_offset_ + i; | 8977 uint32_t index = index_offset_ + i; |
| 8974 | 8978 |
| 8975 if (fast_elements_) { | 8979 if (fast_elements_) { |
| 8976 if (index < static_cast<uint32_t>(storage_->length())) { | 8980 if (index < static_cast<uint32_t>(storage_->length())) { |
| 8977 storage_->set(index, *elm); | 8981 storage_->set(index, *elm); |
| 8978 return; | 8982 return; |
| 8979 } | 8983 } |
| 8980 // Our initial estimate of length was foiled, possibly by | 8984 // Our initial estimate of length was foiled, possibly by |
| 8981 // getters on the arrays increasing the length of later arrays | 8985 // getters on the arrays increasing the length of later arrays |
| 8982 // during iteration. | 8986 // during iteration. |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 8997 } | 9001 } |
| 8998 | 9002 |
| 8999 void increase_index_offset(uint32_t delta) { | 9003 void increase_index_offset(uint32_t delta) { |
| 9000 if (JSObject::kMaxElementCount - index_offset_ < delta) { | 9004 if (JSObject::kMaxElementCount - index_offset_ < delta) { |
| 9001 index_offset_ = JSObject::kMaxElementCount; | 9005 index_offset_ = JSObject::kMaxElementCount; |
| 9002 } else { | 9006 } else { |
| 9003 index_offset_ += delta; | 9007 index_offset_ += delta; |
| 9004 } | 9008 } |
| 9005 } | 9009 } |
| 9006 | 9010 |
| 9007 Handle<JSArray> ToArray() { | 9011 Handle<Object> ToArray() { |
| 9012 if (exceeds_array_limit_) { | |
| 9013 // Index exceeds the array size limit, so that elements would be stored | |
| 9014 // as properties are missing. | |
| 9015 return Handle<Smi>(Smi::FromInt(0), isolate_); | |
| 9016 } | |
| 9008 Handle<JSArray> array = isolate_->factory()->NewJSArray(0); | 9017 Handle<JSArray> array = isolate_->factory()->NewJSArray(0); |
| 9009 Handle<Object> length = | 9018 Handle<Object> length = |
| 9010 isolate_->factory()->NewNumber(static_cast<double>(index_offset_)); | 9019 isolate_->factory()->NewNumber(static_cast<double>(index_offset_)); |
| 9011 Handle<Map> map; | 9020 Handle<Map> map; |
| 9012 if (fast_elements_) { | 9021 if (fast_elements_) { |
| 9013 map = isolate_->factory()->GetElementsTransitionMap(array, | 9022 map = isolate_->factory()->GetElementsTransitionMap(array, |
| 9014 FAST_HOLEY_ELEMENTS); | 9023 FAST_HOLEY_ELEMENTS); |
| 9015 } else { | 9024 } else { |
| 9016 map = isolate_->factory()->GetElementsTransitionMap(array, | 9025 map = isolate_->factory()->GetElementsTransitionMap(array, |
| 9017 DICTIONARY_ELEMENTS); | 9026 DICTIONARY_ELEMENTS); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9056 storage_ = Handle<FixedArray>::cast( | 9065 storage_ = Handle<FixedArray>::cast( |
| 9057 isolate_->global_handles()->Create(storage)); | 9066 isolate_->global_handles()->Create(storage)); |
| 9058 } | 9067 } |
| 9059 | 9068 |
| 9060 Isolate* isolate_; | 9069 Isolate* isolate_; |
| 9061 Handle<FixedArray> storage_; // Always a global handle. | 9070 Handle<FixedArray> storage_; // Always a global handle. |
| 9062 // Index after last seen index. Always less than or equal to | 9071 // Index after last seen index. Always less than or equal to |
| 9063 // JSObject::kMaxElementCount. | 9072 // JSObject::kMaxElementCount. |
| 9064 uint32_t index_offset_; | 9073 uint32_t index_offset_; |
| 9065 bool fast_elements_; | 9074 bool fast_elements_; |
| 9075 bool exceeds_array_limit_; | |
| 9066 }; | 9076 }; |
| 9067 | 9077 |
| 9068 | 9078 |
| 9069 static uint32_t EstimateElementCount(Handle<JSArray> array) { | 9079 static uint32_t EstimateElementCount(Handle<JSArray> array) { |
| 9070 uint32_t length = static_cast<uint32_t>(array->length()->Number()); | 9080 uint32_t length = static_cast<uint32_t>(array->length()->Number()); |
| 9071 int element_count = 0; | 9081 int element_count = 0; |
| 9072 switch (array->GetElementsKind()) { | 9082 switch (array->GetElementsKind()) { |
| 9073 case FAST_SMI_ELEMENTS: | 9083 case FAST_SMI_ELEMENTS: |
| 9074 case FAST_HOLEY_SMI_ELEMENTS: | 9084 case FAST_HOLEY_SMI_ELEMENTS: |
| 9075 case FAST_ELEMENTS: | 9085 case FAST_ELEMENTS: |
| (...skipping 4074 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13150 // Handle last resort GC and make sure to allow future allocations | 13160 // Handle last resort GC and make sure to allow future allocations |
| 13151 // to grow the heap without causing GCs (if possible). | 13161 // to grow the heap without causing GCs (if possible). |
| 13152 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13162 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 13153 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13163 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 13154 "Runtime::PerformGC"); | 13164 "Runtime::PerformGC"); |
| 13155 } | 13165 } |
| 13156 } | 13166 } |
| 13157 | 13167 |
| 13158 | 13168 |
| 13159 } } // namespace v8::internal | 13169 } } // namespace v8::internal |
| OLD | NEW |