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 |