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_) { |
| 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 |
| 9011 bool exceeds_array_limit() { |
| 9012 return exceeds_array_limit_; |
| 9013 } |
| 9014 |
9007 Handle<JSArray> ToArray() { | 9015 Handle<JSArray> ToArray() { |
9008 Handle<JSArray> array = isolate_->factory()->NewJSArray(0); | 9016 Handle<JSArray> array = isolate_->factory()->NewJSArray(0); |
9009 Handle<Object> length = | 9017 Handle<Object> length = |
9010 isolate_->factory()->NewNumber(static_cast<double>(index_offset_)); | 9018 isolate_->factory()->NewNumber(static_cast<double>(index_offset_)); |
9011 Handle<Map> map; | 9019 Handle<Map> map; |
9012 if (fast_elements_) { | 9020 if (fast_elements_) { |
9013 map = isolate_->factory()->GetElementsTransitionMap(array, | 9021 map = isolate_->factory()->GetElementsTransitionMap(array, |
9014 FAST_HOLEY_ELEMENTS); | 9022 FAST_HOLEY_ELEMENTS); |
9015 } else { | 9023 } else { |
9016 map = isolate_->factory()->GetElementsTransitionMap(array, | 9024 map = isolate_->factory()->GetElementsTransitionMap(array, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9056 storage_ = Handle<FixedArray>::cast( | 9064 storage_ = Handle<FixedArray>::cast( |
9057 isolate_->global_handles()->Create(storage)); | 9065 isolate_->global_handles()->Create(storage)); |
9058 } | 9066 } |
9059 | 9067 |
9060 Isolate* isolate_; | 9068 Isolate* isolate_; |
9061 Handle<FixedArray> storage_; // Always a global handle. | 9069 Handle<FixedArray> storage_; // Always a global handle. |
9062 // Index after last seen index. Always less than or equal to | 9070 // Index after last seen index. Always less than or equal to |
9063 // JSObject::kMaxElementCount. | 9071 // JSObject::kMaxElementCount. |
9064 uint32_t index_offset_; | 9072 uint32_t index_offset_; |
9065 bool fast_elements_; | 9073 bool fast_elements_; |
| 9074 bool exceeds_array_limit_; |
9066 }; | 9075 }; |
9067 | 9076 |
9068 | 9077 |
9069 static uint32_t EstimateElementCount(Handle<JSArray> array) { | 9078 static uint32_t EstimateElementCount(Handle<JSArray> array) { |
9070 uint32_t length = static_cast<uint32_t>(array->length()->Number()); | 9079 uint32_t length = static_cast<uint32_t>(array->length()->Number()); |
9071 int element_count = 0; | 9080 int element_count = 0; |
9072 switch (array->GetElementsKind()) { | 9081 switch (array->GetElementsKind()) { |
9073 case FAST_SMI_ELEMENTS: | 9082 case FAST_SMI_ELEMENTS: |
9074 case FAST_HOLEY_SMI_ELEMENTS: | 9083 case FAST_HOLEY_SMI_ELEMENTS: |
9075 case FAST_ELEMENTS: | 9084 case FAST_ELEMENTS: |
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9611 Handle<JSArray> array = Handle<JSArray>::cast(obj); | 9620 Handle<JSArray> array = Handle<JSArray>::cast(obj); |
9612 if (!IterateElements(isolate, array, &visitor)) { | 9621 if (!IterateElements(isolate, array, &visitor)) { |
9613 return Failure::Exception(); | 9622 return Failure::Exception(); |
9614 } | 9623 } |
9615 } else { | 9624 } else { |
9616 visitor.visit(0, obj); | 9625 visitor.visit(0, obj); |
9617 visitor.increase_index_offset(1); | 9626 visitor.increase_index_offset(1); |
9618 } | 9627 } |
9619 } | 9628 } |
9620 | 9629 |
| 9630 if (visitor.exceeds_array_limit()) { |
| 9631 return isolate->Throw( |
| 9632 *isolate->factory()->NewRangeError("invalid_array_length", |
| 9633 HandleVector<Object>(NULL, 0))); |
| 9634 } |
9621 return *visitor.ToArray(); | 9635 return *visitor.ToArray(); |
9622 } | 9636 } |
9623 | 9637 |
9624 | 9638 |
9625 // This will not allocate (flatten the string), but it may run | 9639 // This will not allocate (flatten the string), but it may run |
9626 // very slowly for very deeply nested ConsStrings. For debugging use only. | 9640 // very slowly for very deeply nested ConsStrings. For debugging use only. |
9627 RUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalPrint) { | 9641 RUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalPrint) { |
9628 NoHandleAllocation ha(isolate); | 9642 NoHandleAllocation ha(isolate); |
9629 ASSERT(args.length() == 1); | 9643 ASSERT(args.length() == 1); |
9630 | 9644 |
(...skipping 3519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13150 // Handle last resort GC and make sure to allow future allocations | 13164 // Handle last resort GC and make sure to allow future allocations |
13151 // to grow the heap without causing GCs (if possible). | 13165 // to grow the heap without causing GCs (if possible). |
13152 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13166 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13153 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13167 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13154 "Runtime::PerformGC"); | 13168 "Runtime::PerformGC"); |
13155 } | 13169 } |
13156 } | 13170 } |
13157 | 13171 |
13158 | 13172 |
13159 } } // namespace v8::internal | 13173 } } // namespace v8::internal |
OLD | NEW |