Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: src/runtime.cc

Issue 13465008: Fix Array.prototype.concat when exceeding array size limit. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-581.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-581.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698