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

Side by Side Diff: src/runtime.cc

Issue 342333002: Array.concat: properly go to dictionary mode when required (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 6 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-crbug-387031.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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdlib.h> 5 #include <stdlib.h>
6 #include <limits> 6 #include <limits>
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/accessors.h" 10 #include "src/accessors.h"
(...skipping 10022 matching lines...) Expand 10 before | Expand all | Expand 10 after
10033 10033
10034 if (fast_elements_) { 10034 if (fast_elements_) {
10035 if (index < static_cast<uint32_t>(storage_->length())) { 10035 if (index < static_cast<uint32_t>(storage_->length())) {
10036 storage_->set(index, *elm); 10036 storage_->set(index, *elm);
10037 return; 10037 return;
10038 } 10038 }
10039 // Our initial estimate of length was foiled, possibly by 10039 // Our initial estimate of length was foiled, possibly by
10040 // getters on the arrays increasing the length of later arrays 10040 // getters on the arrays increasing the length of later arrays
10041 // during iteration. 10041 // during iteration.
10042 // This shouldn't happen in anything but pathological cases. 10042 // This shouldn't happen in anything but pathological cases.
10043 SetDictionaryMode(index); 10043 SetDictionaryMode();
10044 // Fall-through to dictionary mode. 10044 // Fall-through to dictionary mode.
10045 } 10045 }
10046 ASSERT(!fast_elements_); 10046 ASSERT(!fast_elements_);
10047 Handle<SeededNumberDictionary> dict( 10047 Handle<SeededNumberDictionary> dict(
10048 SeededNumberDictionary::cast(*storage_)); 10048 SeededNumberDictionary::cast(*storage_));
10049 Handle<SeededNumberDictionary> result = 10049 Handle<SeededNumberDictionary> result =
10050 SeededNumberDictionary::AtNumberPut(dict, index, elm); 10050 SeededNumberDictionary::AtNumberPut(dict, index, elm);
10051 if (!result.is_identical_to(dict)) { 10051 if (!result.is_identical_to(dict)) {
10052 // Dictionary needed to grow. 10052 // Dictionary needed to grow.
10053 clear_storage(); 10053 clear_storage();
10054 set_storage(*result); 10054 set_storage(*result);
10055 } 10055 }
10056 } 10056 }
10057 10057
10058 void increase_index_offset(uint32_t delta) { 10058 void increase_index_offset(uint32_t delta) {
10059 if (JSObject::kMaxElementCount - index_offset_ < delta) { 10059 if (JSObject::kMaxElementCount - index_offset_ < delta) {
10060 index_offset_ = JSObject::kMaxElementCount; 10060 index_offset_ = JSObject::kMaxElementCount;
10061 } else { 10061 } else {
10062 index_offset_ += delta; 10062 index_offset_ += delta;
10063 } 10063 }
10064 // If the initial length estimate was off (see special case in visit()),
10065 // but the array blowing the limit didn't contain elements beyond the
10066 // provided-for index range, go to dictionary mode now.
10067 if (fast_elements_ &&
10068 index_offset_ >= static_cast<uint32_t>(
10069 FixedArrayBase::cast(*storage_)->length())) {
10070 SetDictionaryMode();
10071 }
10064 } 10072 }
10065 10073
10066 bool exceeds_array_limit() { 10074 bool exceeds_array_limit() {
10067 return exceeds_array_limit_; 10075 return exceeds_array_limit_;
10068 } 10076 }
10069 10077
10070 Handle<JSArray> ToArray() { 10078 Handle<JSArray> ToArray() {
10071 Handle<JSArray> array = isolate_->factory()->NewJSArray(0); 10079 Handle<JSArray> array = isolate_->factory()->NewJSArray(0);
10072 Handle<Object> length = 10080 Handle<Object> length =
10073 isolate_->factory()->NewNumber(static_cast<double>(index_offset_)); 10081 isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
10074 Handle<Map> map = JSObject::GetElementsTransitionMap( 10082 Handle<Map> map = JSObject::GetElementsTransitionMap(
10075 array, 10083 array,
10076 fast_elements_ ? FAST_HOLEY_ELEMENTS : DICTIONARY_ELEMENTS); 10084 fast_elements_ ? FAST_HOLEY_ELEMENTS : DICTIONARY_ELEMENTS);
10077 array->set_map(*map); 10085 array->set_map(*map);
10078 array->set_length(*length); 10086 array->set_length(*length);
10079 array->set_elements(*storage_); 10087 array->set_elements(*storage_);
10080 return array; 10088 return array;
10081 } 10089 }
10082 10090
10083 private: 10091 private:
10084 // Convert storage to dictionary mode. 10092 // Convert storage to dictionary mode.
10085 void SetDictionaryMode(uint32_t index) { 10093 void SetDictionaryMode() {
10086 ASSERT(fast_elements_); 10094 ASSERT(fast_elements_);
10087 Handle<FixedArray> current_storage(*storage_); 10095 Handle<FixedArray> current_storage(*storage_);
10088 Handle<SeededNumberDictionary> slow_storage( 10096 Handle<SeededNumberDictionary> slow_storage(
10089 SeededNumberDictionary::New(isolate_, current_storage->length())); 10097 SeededNumberDictionary::New(isolate_, current_storage->length()));
10090 uint32_t current_length = static_cast<uint32_t>(current_storage->length()); 10098 uint32_t current_length = static_cast<uint32_t>(current_storage->length());
10091 for (uint32_t i = 0; i < current_length; i++) { 10099 for (uint32_t i = 0; i < current_length; i++) {
10092 HandleScope loop_scope(isolate_); 10100 HandleScope loop_scope(isolate_);
10093 Handle<Object> element(current_storage->get(i), isolate_); 10101 Handle<Object> element(current_storage->get(i), isolate_);
10094 if (!element->IsTheHole()) { 10102 if (!element->IsTheHole()) {
10095 Handle<SeededNumberDictionary> new_storage = 10103 Handle<SeededNumberDictionary> new_storage =
(...skipping 5123 matching lines...) Expand 10 before | Expand all | Expand 10 after
15219 } 15227 }
15220 return NULL; 15228 return NULL;
15221 } 15229 }
15222 15230
15223 15231
15224 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { 15232 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
15225 return &(kIntrinsicFunctions[static_cast<int>(id)]); 15233 return &(kIntrinsicFunctions[static_cast<int>(id)]);
15226 } 15234 }
15227 15235
15228 } } // namespace v8::internal 15236 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-crbug-387031.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698