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

Side by Side Diff: src/runtime/runtime-array.cc

Issue 700963002: Replace C++ bitfields with our own BitFields (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fixed AST node field sizes; more scanner fixes; undid hydrogen.h/cc changes Created 6 years, 1 month 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 | « src/profile-generator-inl.h ('k') | src/scanner.cc » ('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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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 "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/arguments.h" 7 #include "src/arguments.h"
8 #include "src/runtime/runtime-utils.h" 8 #include "src/runtime/runtime-utils.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 * length overflows 32-bit non-negative integer. 97 * length overflows 32-bit non-negative integer.
98 */ 98 */
99 class ArrayConcatVisitor { 99 class ArrayConcatVisitor {
100 public: 100 public:
101 ArrayConcatVisitor(Isolate* isolate, Handle<FixedArray> storage, 101 ArrayConcatVisitor(Isolate* isolate, Handle<FixedArray> storage,
102 bool fast_elements) 102 bool fast_elements)
103 : isolate_(isolate), 103 : isolate_(isolate),
104 storage_(Handle<FixedArray>::cast( 104 storage_(Handle<FixedArray>::cast(
105 isolate->global_handles()->Create(*storage))), 105 isolate->global_handles()->Create(*storage))),
106 index_offset_(0u), 106 index_offset_(0u),
107 fast_elements_(fast_elements), 107 bit_field_(FastElementsField::encode(fast_elements) |
108 exceeds_array_limit_(false) {} 108 ExceedsLimitField::encode(false)) {}
109 109
110 ~ArrayConcatVisitor() { clear_storage(); } 110 ~ArrayConcatVisitor() { clear_storage(); }
111 111
112 void visit(uint32_t i, Handle<Object> elm) { 112 void visit(uint32_t i, Handle<Object> elm) {
113 if (i > JSObject::kMaxElementCount - index_offset_) { 113 if (i > JSObject::kMaxElementCount - index_offset_) {
114 exceeds_array_limit_ = true; 114 set_exceeds_array_limit(true);
115 return; 115 return;
116 } 116 }
117 uint32_t index = index_offset_ + i; 117 uint32_t index = index_offset_ + i;
118 118
119 if (fast_elements_) { 119 if (fast_elements()) {
120 if (index < static_cast<uint32_t>(storage_->length())) { 120 if (index < static_cast<uint32_t>(storage_->length())) {
121 storage_->set(index, *elm); 121 storage_->set(index, *elm);
122 return; 122 return;
123 } 123 }
124 // Our initial estimate of length was foiled, possibly by 124 // Our initial estimate of length was foiled, possibly by
125 // getters on the arrays increasing the length of later arrays 125 // getters on the arrays increasing the length of later arrays
126 // during iteration. 126 // during iteration.
127 // This shouldn't happen in anything but pathological cases. 127 // This shouldn't happen in anything but pathological cases.
128 SetDictionaryMode(); 128 SetDictionaryMode();
129 // Fall-through to dictionary mode. 129 // Fall-through to dictionary mode.
130 } 130 }
131 DCHECK(!fast_elements_); 131 DCHECK(!fast_elements());
132 Handle<SeededNumberDictionary> dict( 132 Handle<SeededNumberDictionary> dict(
133 SeededNumberDictionary::cast(*storage_)); 133 SeededNumberDictionary::cast(*storage_));
134 Handle<SeededNumberDictionary> result = 134 Handle<SeededNumberDictionary> result =
135 SeededNumberDictionary::AtNumberPut(dict, index, elm); 135 SeededNumberDictionary::AtNumberPut(dict, index, elm);
136 if (!result.is_identical_to(dict)) { 136 if (!result.is_identical_to(dict)) {
137 // Dictionary needed to grow. 137 // Dictionary needed to grow.
138 clear_storage(); 138 clear_storage();
139 set_storage(*result); 139 set_storage(*result);
140 } 140 }
141 } 141 }
142 142
143 void increase_index_offset(uint32_t delta) { 143 void increase_index_offset(uint32_t delta) {
144 if (JSObject::kMaxElementCount - index_offset_ < delta) { 144 if (JSObject::kMaxElementCount - index_offset_ < delta) {
145 index_offset_ = JSObject::kMaxElementCount; 145 index_offset_ = JSObject::kMaxElementCount;
146 } else { 146 } else {
147 index_offset_ += delta; 147 index_offset_ += delta;
148 } 148 }
149 // If the initial length estimate was off (see special case in visit()), 149 // If the initial length estimate was off (see special case in visit()),
150 // but the array blowing the limit didn't contain elements beyond the 150 // but the array blowing the limit didn't contain elements beyond the
151 // provided-for index range, go to dictionary mode now. 151 // provided-for index range, go to dictionary mode now.
152 if (fast_elements_ && 152 if (fast_elements() &&
153 index_offset_ > 153 index_offset_ >
154 static_cast<uint32_t>(FixedArrayBase::cast(*storage_)->length())) { 154 static_cast<uint32_t>(FixedArrayBase::cast(*storage_)->length())) {
155 SetDictionaryMode(); 155 SetDictionaryMode();
156 } 156 }
157 } 157 }
158 158
159 bool exceeds_array_limit() { return exceeds_array_limit_; } 159 bool exceeds_array_limit() const {
160 return ExceedsLimitField::decode(bit_field_);
161 }
160 162
161 Handle<JSArray> ToArray() { 163 Handle<JSArray> ToArray() {
162 Handle<JSArray> array = isolate_->factory()->NewJSArray(0); 164 Handle<JSArray> array = isolate_->factory()->NewJSArray(0);
163 Handle<Object> length = 165 Handle<Object> length =
164 isolate_->factory()->NewNumber(static_cast<double>(index_offset_)); 166 isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
165 Handle<Map> map = JSObject::GetElementsTransitionMap( 167 Handle<Map> map = JSObject::GetElementsTransitionMap(
166 array, fast_elements_ ? FAST_HOLEY_ELEMENTS : DICTIONARY_ELEMENTS); 168 array, fast_elements() ? FAST_HOLEY_ELEMENTS : DICTIONARY_ELEMENTS);
167 array->set_map(*map); 169 array->set_map(*map);
168 array->set_length(*length); 170 array->set_length(*length);
169 array->set_elements(*storage_); 171 array->set_elements(*storage_);
170 return array; 172 return array;
171 } 173 }
172 174
173 private: 175 private:
174 // Convert storage to dictionary mode. 176 // Convert storage to dictionary mode.
175 void SetDictionaryMode() { 177 void SetDictionaryMode() {
176 DCHECK(fast_elements_); 178 DCHECK(fast_elements());
177 Handle<FixedArray> current_storage(*storage_); 179 Handle<FixedArray> current_storage(*storage_);
178 Handle<SeededNumberDictionary> slow_storage( 180 Handle<SeededNumberDictionary> slow_storage(
179 SeededNumberDictionary::New(isolate_, current_storage->length())); 181 SeededNumberDictionary::New(isolate_, current_storage->length()));
180 uint32_t current_length = static_cast<uint32_t>(current_storage->length()); 182 uint32_t current_length = static_cast<uint32_t>(current_storage->length());
181 for (uint32_t i = 0; i < current_length; i++) { 183 for (uint32_t i = 0; i < current_length; i++) {
182 HandleScope loop_scope(isolate_); 184 HandleScope loop_scope(isolate_);
183 Handle<Object> element(current_storage->get(i), isolate_); 185 Handle<Object> element(current_storage->get(i), isolate_);
184 if (!element->IsTheHole()) { 186 if (!element->IsTheHole()) {
185 Handle<SeededNumberDictionary> new_storage = 187 Handle<SeededNumberDictionary> new_storage =
186 SeededNumberDictionary::AtNumberPut(slow_storage, i, element); 188 SeededNumberDictionary::AtNumberPut(slow_storage, i, element);
187 if (!new_storage.is_identical_to(slow_storage)) { 189 if (!new_storage.is_identical_to(slow_storage)) {
188 slow_storage = loop_scope.CloseAndEscape(new_storage); 190 slow_storage = loop_scope.CloseAndEscape(new_storage);
189 } 191 }
190 } 192 }
191 } 193 }
192 clear_storage(); 194 clear_storage();
193 set_storage(*slow_storage); 195 set_storage(*slow_storage);
194 fast_elements_ = false; 196 set_fast_elements(false);
195 } 197 }
196 198
197 inline void clear_storage() { 199 inline void clear_storage() {
198 GlobalHandles::Destroy(Handle<Object>::cast(storage_).location()); 200 GlobalHandles::Destroy(Handle<Object>::cast(storage_).location());
199 } 201 }
200 202
201 inline void set_storage(FixedArray* storage) { 203 inline void set_storage(FixedArray* storage) {
202 storage_ = 204 storage_ =
203 Handle<FixedArray>::cast(isolate_->global_handles()->Create(storage)); 205 Handle<FixedArray>::cast(isolate_->global_handles()->Create(storage));
204 } 206 }
205 207
208 class FastElementsField : public BitField<bool, 0, 1> {};
209 class ExceedsLimitField : public BitField<bool, 1, 1> {};
210
211 bool fast_elements() const { return FastElementsField::decode(bit_field_); }
212 void set_fast_elements(bool fast) {
213 bit_field_ = FastElementsField::update(bit_field_, fast);
214 }
215 void set_exceeds_array_limit(bool exceeds) {
216 bit_field_ = ExceedsLimitField::update(bit_field_, exceeds);
217 }
218
206 Isolate* isolate_; 219 Isolate* isolate_;
207 Handle<FixedArray> storage_; // Always a global handle. 220 Handle<FixedArray> storage_; // Always a global handle.
208 // Index after last seen index. Always less than or equal to 221 // Index after last seen index. Always less than or equal to
209 // JSObject::kMaxElementCount. 222 // JSObject::kMaxElementCount.
210 uint32_t index_offset_; 223 uint32_t index_offset_;
211 bool fast_elements_ : 1; 224 uint32_t bit_field_;
212 bool exceeds_array_limit_ : 1;
213 }; 225 };
214 226
215 227
216 static uint32_t EstimateElementCount(Handle<JSArray> array) { 228 static uint32_t EstimateElementCount(Handle<JSArray> array) {
217 uint32_t length = static_cast<uint32_t>(array->length()->Number()); 229 uint32_t length = static_cast<uint32_t>(array->length()->Number());
218 int element_count = 0; 230 int element_count = 0;
219 switch (array->GetElementsKind()) { 231 switch (array->GetElementsKind()) {
220 case FAST_SMI_ELEMENTS: 232 case FAST_SMI_ELEMENTS:
221 case FAST_HOLEY_SMI_ELEMENTS: 233 case FAST_HOLEY_SMI_ELEMENTS:
222 case FAST_ELEMENTS: 234 case FAST_ELEMENTS:
(...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 } 1187 }
1176 1188
1177 1189
1178 RUNTIME_FUNCTION(RuntimeReference_FastOneByteArrayJoin) { 1190 RUNTIME_FUNCTION(RuntimeReference_FastOneByteArrayJoin) {
1179 SealHandleScope shs(isolate); 1191 SealHandleScope shs(isolate);
1180 DCHECK(args.length() == 2); 1192 DCHECK(args.length() == 2);
1181 return isolate->heap()->undefined_value(); 1193 return isolate->heap()->undefined_value();
1182 } 1194 }
1183 } 1195 }
1184 } // namespace v8::internal 1196 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/profile-generator-inl.h ('k') | src/scanner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698