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

Side by Side Diff: src/elements.cc

Issue 10170030: Implement tracking and optimizations of packed arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: ia32 ready to go Created 8 years, 7 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
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 21 matching lines...) Expand all
32 #include "utils.h" 32 #include "utils.h"
33 33
34 34
35 // Each concrete ElementsAccessor can handle exactly one ElementsKind, 35 // Each concrete ElementsAccessor can handle exactly one ElementsKind,
36 // several abstract ElementsAccessor classes are used to allow sharing 36 // several abstract ElementsAccessor classes are used to allow sharing
37 // common code. 37 // common code.
38 // 38 //
39 // Inheritance hierarchy: 39 // Inheritance hierarchy:
40 // - ElementsAccessorBase (abstract) 40 // - ElementsAccessorBase (abstract)
41 // - FastElementsAccessor (abstract) 41 // - FastElementsAccessor (abstract)
42 // - FastObjectElementsAccessor 42 // - FastSmiOrObjectElementsAccessor
43 // - FastPackedSmiElementsAccessor
44 // - FastHoleySmiElementsAccessor
45 // - FastPackedObjectElementsAccessor
46 // - FastHoleyObjectElementsAccessor
43 // - FastDoubleElementsAccessor 47 // - FastDoubleElementsAccessor
48 // - FastPackedDoubleElementsAccessor
49 // - FastHoleyDoubleElementsAccessor
44 // - ExternalElementsAccessor (abstract) 50 // - ExternalElementsAccessor (abstract)
45 // - ExternalByteElementsAccessor 51 // - ExternalByteElementsAccessor
46 // - ExternalUnsignedByteElementsAccessor 52 // - ExternalUnsignedByteElementsAccessor
47 // - ExternalShortElementsAccessor 53 // - ExternalShortElementsAccessor
48 // - ExternalUnsignedShortElementsAccessor 54 // - ExternalUnsignedShortElementsAccessor
49 // - ExternalIntElementsAccessor 55 // - ExternalIntElementsAccessor
50 // - ExternalUnsignedIntElementsAccessor 56 // - ExternalUnsignedIntElementsAccessor
51 // - ExternalFloatElementsAccessor 57 // - ExternalFloatElementsAccessor
52 // - ExternalDoubleElementsAccessor 58 // - ExternalDoubleElementsAccessor
53 // - PixelElementsAccessor 59 // - PixelElementsAccessor
54 // - DictionaryElementsAccessor 60 // - DictionaryElementsAccessor
55 // - NonStrictArgumentsElementsAccessor 61 // - NonStrictArgumentsElementsAccessor
56 62
57 63
58 namespace v8 { 64 namespace v8 {
59 namespace internal { 65 namespace internal {
60 66
61 67
62 // First argument in list is the accessor class, the second argument is the 68 // First argument in list is the accessor class, the second argument is the
63 // accessor ElementsKind, and the third is the backing store class. Use the 69 // accessor ElementsKind, and the third is the backing store class. Use the
64 // fast element handler for smi-only arrays. The implementation is currently 70 // fast element handler for smi-only arrays. The implementation is currently
65 // identical. Note that the order must match that of the ElementsKind enum for 71 // identical. Note that the order must match that of the ElementsKind enum for
66 // the |accessor_array[]| below to work. 72 // the |accessor_array[]| below to work.
67 #define ELEMENTS_LIST(V) \ 73 #define ELEMENTS_LIST(V) \
68 V(FastObjectElementsAccessor, FAST_SMI_ONLY_ELEMENTS, FixedArray) \ 74 V(FastPackedSmiElementsAccessor, FAST_SMI_ELEMENTS, FixedArray) \
69 V(FastObjectElementsAccessor, FAST_ELEMENTS, FixedArray) \ 75 V(FastHoleySmiElementsAccessor, FAST_HOLEY_SMI_ELEMENTS, \
70 V(FastDoubleElementsAccessor, FAST_DOUBLE_ELEMENTS, FixedDoubleArray) \ 76 FixedArray) \
77 V(FastPackedObjectElementsAccessor, FAST_ELEMENTS, FixedArray) \
78 V(FastHoleyObjectElementsAccessor, FAST_HOLEY_ELEMENTS, FixedArray) \
79 V(FastPackedDoubleElementsAccessor, FAST_DOUBLE_ELEMENTS, \
80 FixedDoubleArray) \
81 V(FastHoleyDoubleElementsAccessor, FAST_HOLEY_DOUBLE_ELEMENTS, \
82 FixedDoubleArray) \
71 V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS, \ 83 V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS, \
72 SeededNumberDictionary) \ 84 SeededNumberDictionary) \
73 V(NonStrictArgumentsElementsAccessor, NON_STRICT_ARGUMENTS_ELEMENTS, \ 85 V(NonStrictArgumentsElementsAccessor, NON_STRICT_ARGUMENTS_ELEMENTS, \
74 FixedArray) \ 86 FixedArray) \
75 V(ExternalByteElementsAccessor, EXTERNAL_BYTE_ELEMENTS, \ 87 V(ExternalByteElementsAccessor, EXTERNAL_BYTE_ELEMENTS, \
76 ExternalByteArray) \ 88 ExternalByteArray) \
77 V(ExternalUnsignedByteElementsAccessor, \ 89 V(ExternalUnsignedByteElementsAccessor, \
78 EXTERNAL_UNSIGNED_BYTE_ELEMENTS, ExternalUnsignedByteArray) \ 90 EXTERNAL_UNSIGNED_BYTE_ELEMENTS, ExternalUnsignedByteArray) \
79 V(ExternalShortElementsAccessor, EXTERNAL_SHORT_ELEMENTS, \ 91 V(ExternalShortElementsAccessor, EXTERNAL_SHORT_ELEMENTS, \
80 ExternalShortArray) \ 92 ExternalShortArray) \
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 144
133 145
134 void CopyObjectToObjectElements(FixedArray* from, 146 void CopyObjectToObjectElements(FixedArray* from,
135 ElementsKind from_kind, 147 ElementsKind from_kind,
136 uint32_t from_start, 148 uint32_t from_start,
137 FixedArray* to, 149 FixedArray* to,
138 ElementsKind to_kind, 150 ElementsKind to_kind,
139 uint32_t to_start, 151 uint32_t to_start,
140 int raw_copy_size) { 152 int raw_copy_size) {
141 ASSERT(to->map() != HEAP->fixed_cow_array_map()); 153 ASSERT(to->map() != HEAP->fixed_cow_array_map());
142 ASSERT(from_kind == FAST_ELEMENTS || from_kind == FAST_SMI_ONLY_ELEMENTS); 154 ASSERT(IsFastSmiOrObjectElementsKind(from_kind));
143 ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS); 155 ASSERT(IsFastSmiOrObjectElementsKind(to_kind));
144 int copy_size = raw_copy_size; 156 int copy_size = raw_copy_size;
145 if (raw_copy_size < 0) { 157 if (raw_copy_size < 0) {
146 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || 158 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
147 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 159 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
148 copy_size = Min(from->length() - from_start, 160 copy_size = Min(from->length() - from_start,
149 to->length() - to_start); 161 to->length() - to_start);
150 #ifdef DEBUG 162 #ifdef DEBUG
151 // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already 163 // FAST_*_ELEMENTS arrays cannot be uninitialized. Ensure they are already
152 // marked with the hole. 164 // marked with the hole.
153 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 165 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
154 for (int i = to_start + copy_size; i < to->length(); ++i) { 166 for (int i = to_start + copy_size; i < to->length(); ++i) {
155 ASSERT(to->get(i)->IsTheHole()); 167 ASSERT(to->get(i)->IsTheHole());
156 } 168 }
157 } 169 }
158 #endif 170 #endif
159 } 171 }
160 ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && 172 ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() &&
161 (copy_size + static_cast<int>(from_start)) <= from->length()); 173 (copy_size + static_cast<int>(from_start)) <= from->length());
162 if (copy_size == 0) return; 174 if (copy_size == 0) return;
163 Address to_address = to->address() + FixedArray::kHeaderSize; 175 Address to_address = to->address() + FixedArray::kHeaderSize;
164 Address from_address = from->address() + FixedArray::kHeaderSize; 176 Address from_address = from->address() + FixedArray::kHeaderSize;
165 CopyWords(reinterpret_cast<Object**>(to_address) + to_start, 177 CopyWords(reinterpret_cast<Object**>(to_address) + to_start,
166 reinterpret_cast<Object**>(from_address) + from_start, 178 reinterpret_cast<Object**>(from_address) + from_start,
167 copy_size); 179 copy_size);
168 if (from_kind == FAST_ELEMENTS && to_kind == FAST_ELEMENTS) { 180 if (IsFastObjectElementsKind(from_kind) &&
181 IsFastObjectElementsKind(to_kind)) {
169 Heap* heap = from->GetHeap(); 182 Heap* heap = from->GetHeap();
170 if (!heap->InNewSpace(to)) { 183 if (!heap->InNewSpace(to)) {
171 heap->RecordWrites(to->address(), 184 heap->RecordWrites(to->address(),
172 to->OffsetOfElementAt(to_start), 185 to->OffsetOfElementAt(to_start),
173 copy_size); 186 copy_size);
174 } 187 }
175 heap->incremental_marking()->RecordWrites(to); 188 heap->incremental_marking()->RecordWrites(to);
176 } 189 }
177 } 190 }
178 191
179 192
180 static void CopyDictionaryToObjectElements(SeededNumberDictionary* from, 193 static void CopyDictionaryToObjectElements(SeededNumberDictionary* from,
181 uint32_t from_start, 194 uint32_t from_start,
182 FixedArray* to, 195 FixedArray* to,
183 ElementsKind to_kind, 196 ElementsKind to_kind,
184 uint32_t to_start, 197 uint32_t to_start,
185 int raw_copy_size) { 198 int raw_copy_size) {
186 int copy_size = raw_copy_size; 199 int copy_size = raw_copy_size;
187 Heap* heap = from->GetHeap(); 200 Heap* heap = from->GetHeap();
188 if (raw_copy_size < 0) { 201 if (raw_copy_size < 0) {
189 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || 202 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
190 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 203 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
191 copy_size = from->max_number_key() + 1 - from_start; 204 copy_size = from->max_number_key() + 1 - from_start;
192 #ifdef DEBUG 205 #ifdef DEBUG
193 // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already 206 // Fast object arrays cannot be uninitialized. Ensure they are already
194 // marked with the hole. 207 // marked with the hole.
195 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 208 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
196 for (int i = to_start + copy_size; i < to->length(); ++i) { 209 for (int i = to_start + copy_size; i < to->length(); ++i) {
197 ASSERT(to->get(i)->IsTheHole()); 210 ASSERT(to->get(i)->IsTheHole());
198 } 211 }
199 } 212 }
200 #endif 213 #endif
201 } 214 }
202 ASSERT(to != from); 215 ASSERT(to != from);
203 ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS); 216 ASSERT(IsFastSmiOrObjectElementsKind(to_kind));
204 if (copy_size == 0) return; 217 if (copy_size == 0) return;
205 uint32_t to_length = to->length(); 218 uint32_t to_length = to->length();
206 if (to_start + copy_size > to_length) { 219 if (to_start + copy_size > to_length) {
207 copy_size = to_length - to_start; 220 copy_size = to_length - to_start;
208 } 221 }
209 for (int i = 0; i < copy_size; i++) { 222 for (int i = 0; i < copy_size; i++) {
210 int entry = from->FindEntry(i + from_start); 223 int entry = from->FindEntry(i + from_start);
211 if (entry != SeededNumberDictionary::kNotFound) { 224 if (entry != SeededNumberDictionary::kNotFound) {
212 Object* value = from->ValueAt(entry); 225 Object* value = from->ValueAt(entry);
213 ASSERT(!value->IsTheHole()); 226 ASSERT(!value->IsTheHole());
214 to->set(i + to_start, value, SKIP_WRITE_BARRIER); 227 to->set(i + to_start, value, SKIP_WRITE_BARRIER);
215 } else { 228 } else {
216 to->set_the_hole(i + to_start); 229 to->set_the_hole(i + to_start);
217 } 230 }
218 } 231 }
219 if (to_kind == FAST_ELEMENTS) { 232 if (IsFastObjectElementsKind(to_kind)) {
220 if (!heap->InNewSpace(to)) { 233 if (!heap->InNewSpace(to)) {
221 heap->RecordWrites(to->address(), 234 heap->RecordWrites(to->address(),
222 to->OffsetOfElementAt(to_start), 235 to->OffsetOfElementAt(to_start),
223 copy_size); 236 copy_size);
224 } 237 }
225 heap->incremental_marking()->RecordWrites(to); 238 heap->incremental_marking()->RecordWrites(to);
226 } 239 }
227 } 240 }
228 241
229 242
230 MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements( 243 MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements(
231 FixedDoubleArray* from, 244 FixedDoubleArray* from,
232 uint32_t from_start, 245 uint32_t from_start,
233 FixedArray* to, 246 FixedArray* to,
234 ElementsKind to_kind, 247 ElementsKind to_kind,
235 uint32_t to_start, 248 uint32_t to_start,
236 int raw_copy_size) { 249 int raw_copy_size) {
237 ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS); 250 ASSERT(IsFastSmiOrObjectElementsKind(to_kind));
238 int copy_size = raw_copy_size; 251 int copy_size = raw_copy_size;
239 if (raw_copy_size < 0) { 252 if (raw_copy_size < 0) {
240 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || 253 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
241 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 254 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
242 copy_size = Min(from->length() - from_start, 255 copy_size = Min(from->length() - from_start,
243 to->length() - to_start); 256 to->length() - to_start);
244 #ifdef DEBUG 257 #ifdef DEBUG
245 // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already 258 // FAST_*_ELEMENTS arrays cannot be uninitialized. Ensure they are already
246 // marked with the hole. 259 // marked with the hole.
247 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 260 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
248 for (int i = to_start + copy_size; i < to->length(); ++i) { 261 for (int i = to_start + copy_size; i < to->length(); ++i) {
249 ASSERT(to->get(i)->IsTheHole()); 262 ASSERT(to->get(i)->IsTheHole());
250 } 263 }
251 } 264 }
252 #endif 265 #endif
253 } 266 }
254 ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && 267 ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() &&
255 (copy_size + static_cast<int>(from_start)) <= from->length()); 268 (copy_size + static_cast<int>(from_start)) <= from->length());
256 if (copy_size == 0) return from; 269 if (copy_size == 0) return from;
257 for (int i = 0; i < copy_size; ++i) { 270 for (int i = 0; i < copy_size; ++i) {
258 if (to_kind == FAST_SMI_ONLY_ELEMENTS) { 271 if (IsFastSmiElementsKind(to_kind)) {
259 UNIMPLEMENTED(); 272 UNIMPLEMENTED();
260 return Failure::Exception(); 273 return Failure::Exception();
261 } else { 274 } else {
262 MaybeObject* maybe_value = from->get(i + from_start); 275 MaybeObject* maybe_value = from->get(i + from_start);
263 Object* value; 276 Object* value;
264 ASSERT(to_kind == FAST_ELEMENTS); 277 ASSERT(IsFastObjectElementsKind(to_kind));
265 // Because FAST_DOUBLE_ELEMENTS -> FAST_ELEMENT allocate HeapObjects 278 // Because Double -> Object elements transitions allocate HeapObjects
266 // iteratively, the allocate must succeed within a single GC cycle, 279 // iteratively, the allocate must succeed within a single GC cycle,
267 // otherwise the retry after the GC will also fail. In order to ensure 280 // otherwise the retry after the GC will also fail. In order to ensure
268 // that no GC is triggered, allocate HeapNumbers from old space if they 281 // that no GC is triggered, allocate HeapNumbers from old space if they
269 // can't be taken from new space. 282 // can't be taken from new space.
270 if (!maybe_value->ToObject(&value)) { 283 if (!maybe_value->ToObject(&value)) {
271 ASSERT(maybe_value->IsRetryAfterGC() || maybe_value->IsOutOfMemory()); 284 ASSERT(maybe_value->IsRetryAfterGC() || maybe_value->IsOutOfMemory());
272 Heap* heap = from->GetHeap(); 285 Heap* heap = from->GetHeap();
273 MaybeObject* maybe_value_object = 286 MaybeObject* maybe_value_object =
274 heap->AllocateHeapNumber(from->get_scalar(i + from_start), 287 heap->AllocateHeapNumber(from->get_scalar(i + from_start),
275 TENURED); 288 TENURED);
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 class ElementsAccessorBase : public ElementsAccessor { 410 class ElementsAccessorBase : public ElementsAccessor {
398 protected: 411 protected:
399 explicit ElementsAccessorBase(const char* name) 412 explicit ElementsAccessorBase(const char* name)
400 : ElementsAccessor(name) { } 413 : ElementsAccessor(name) { }
401 414
402 typedef ElementsTraitsParam ElementsTraits; 415 typedef ElementsTraitsParam ElementsTraits;
403 typedef typename ElementsTraitsParam::BackingStore BackingStore; 416 typedef typename ElementsTraitsParam::BackingStore BackingStore;
404 417
405 virtual ElementsKind kind() const { return ElementsTraits::Kind; } 418 virtual ElementsKind kind() const { return ElementsTraits::Kind; }
406 419
420 static void ValidateContents(JSObject* holder, int length) {
421 }
422
423 static void ValidateImpl(JSObject* holder) {
424 FixedArrayBase* fixed_array_base = holder->elements();
425 // When objects are first allocated, its elements are Failures.
426 if (fixed_array_base->IsFailure()) return;
427 if (!fixed_array_base->IsHeapObject()) return;
428 Map* map = fixed_array_base->map();
429 // Arrays that have been shifted in place can't be verified.
430 Heap* heap = holder->GetHeap();
431 if (map == heap->raw_unchecked_one_pointer_filler_map() ||
432 map == heap->raw_unchecked_two_pointer_filler_map() ||
433 map == heap->free_space_map()) {
434 return;
435 }
436 int length = 0;
437 if (holder->IsJSArray()) {
438 Object* length_obj = JSArray::cast(holder)->length();
439 if (length_obj->IsSmi()) {
440 length = Smi::cast(length_obj)->value();
441 }
442 } else {
443 length = fixed_array_base->length();
444 }
445 ElementsAccessorSubclass::ValidateContents(holder, length);
446 }
447
448 virtual void Validate(JSObject* holder) {
449 ElementsAccessorSubclass::ValidateImpl(holder);
450 }
451
407 static bool HasElementImpl(Object* receiver, 452 static bool HasElementImpl(Object* receiver,
408 JSObject* holder, 453 JSObject* holder,
409 uint32_t key, 454 uint32_t key,
410 BackingStore* backing_store) { 455 BackingStore* backing_store) {
411 MaybeObject* element = 456 MaybeObject* element =
412 ElementsAccessorSubclass::GetImpl(receiver, holder, key, backing_store); 457 ElementsAccessorSubclass::GetImpl(receiver, holder, key, backing_store);
413 return !element->IsTheHole(); 458 return !element->IsTheHole();
414 } 459 }
415 460
416 virtual bool HasElement(Object* receiver, 461 virtual bool HasElement(Object* receiver,
(...skipping 30 matching lines...) Expand all
447 virtual MaybeObject* SetLength(JSArray* array, 492 virtual MaybeObject* SetLength(JSArray* array,
448 Object* length) { 493 Object* length) {
449 return ElementsAccessorSubclass::SetLengthImpl( 494 return ElementsAccessorSubclass::SetLengthImpl(
450 array, length, BackingStore::cast(array->elements())); 495 array, length, BackingStore::cast(array->elements()));
451 } 496 }
452 497
453 static MaybeObject* SetLengthImpl(JSObject* obj, 498 static MaybeObject* SetLengthImpl(JSObject* obj,
454 Object* length, 499 Object* length,
455 BackingStore* backing_store); 500 BackingStore* backing_store);
456 501
457 virtual MaybeObject* SetCapacityAndLength(JSArray* array, 502 virtual MaybeObject* SetCapacityAndLength(
Jakob Kummerow 2012/05/13 21:55:27 nit: both this and the following change seem unnec
danno 2012/05/22 11:05:21 Done.
458 int capacity, 503 JSArray* array,
459 int length) { 504 int capacity,
505 int length) {
460 return ElementsAccessorSubclass::SetFastElementsCapacityAndLength( 506 return ElementsAccessorSubclass::SetFastElementsCapacityAndLength(
461 array, 507 array,
462 capacity, 508 capacity,
463 length); 509 length);
464 } 510 }
465 511
466 static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj, 512 static MaybeObject* SetFastElementsCapacityAndLength(
467 int capacity, 513 JSObject* obj,
468 int length) { 514 int capacity,
515 int length) {
469 UNIMPLEMENTED(); 516 UNIMPLEMENTED();
470 return obj; 517 return obj;
471 } 518 }
472 519
473 virtual MaybeObject* Delete(JSObject* obj, 520 virtual MaybeObject* Delete(JSObject* obj,
474 uint32_t key, 521 uint32_t key,
475 JSReceiver::DeleteMode mode) = 0; 522 JSReceiver::DeleteMode mode) = 0;
476 523
477 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, 524 static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
478 uint32_t from_start, 525 uint32_t from_start,
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 typename KindTraits, 660 typename KindTraits,
614 int ElementSize> 661 int ElementSize>
615 class FastElementsAccessor 662 class FastElementsAccessor
616 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> { 663 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> {
617 public: 664 public:
618 explicit FastElementsAccessor(const char* name) 665 explicit FastElementsAccessor(const char* name)
619 : ElementsAccessorBase<FastElementsAccessorSubclass, 666 : ElementsAccessorBase<FastElementsAccessorSubclass,
620 KindTraits>(name) {} 667 KindTraits>(name) {}
621 protected: 668 protected:
622 friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>; 669 friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>;
670 friend class NonStrictArgumentsElementsAccessor;
623 671
624 typedef typename KindTraits::BackingStore BackingStore; 672 typedef typename KindTraits::BackingStore BackingStore;
625 673
626 // Adjusts the length of the fast backing store or returns the new length or 674 // Adjusts the length of the fast backing store or returns the new length or
627 // undefined in case conversion to a slow backing store should be performed. 675 // undefined in case conversion to a slow backing store should be performed.
628 static MaybeObject* SetLengthWithoutNormalize(BackingStore* backing_store, 676 static MaybeObject* SetLengthWithoutNormalize(BackingStore* backing_store,
629 JSArray* array, 677 JSArray* array,
630 Object* length_object, 678 Object* length_object,
631 uint32_t length) { 679 uint32_t length) {
632 uint32_t old_capacity = backing_store->length(); 680 uint32_t old_capacity = backing_store->length();
681 Object* old_length = array->length();
682 bool same_size = old_length->IsSmi() &&
683 static_cast<uint32_t>(Smi::cast(old_length)->value()) == length;
684 ElementsKind kind = array->GetElementsKind();
685
686 if (!same_size && IsFastElementsKind(kind) &&
687 !IsFastHoleyElementsKind(kind)) {
688 kind = GetHoleyElementsKind(kind);
689 MaybeObject* maybe_obj = array->TransitionElementsKind(kind);
690 if (maybe_obj->IsFailure()) return maybe_obj;
691 }
633 692
634 // Check whether the backing store should be shrunk. 693 // Check whether the backing store should be shrunk.
635 if (length <= old_capacity) { 694 if (length <= old_capacity) {
636 if (array->HasFastTypeElements()) { 695 if (array->HasFastSmiOrObjectElements()) {
637 MaybeObject* maybe_obj = array->EnsureWritableFastElements(); 696 MaybeObject* maybe_obj = array->EnsureWritableFastElements();
638 if (!maybe_obj->To(&backing_store)) return maybe_obj; 697 if (!maybe_obj->To(&backing_store)) return maybe_obj;
639 } 698 }
640 if (2 * length <= old_capacity) { 699 if (2 * length <= old_capacity) {
641 // If more than half the elements won't be used, trim the array. 700 // If more than half the elements won't be used, trim the array.
642 if (length == 0) { 701 if (length == 0) {
643 array->initialize_elements(); 702 array->initialize_elements();
644 } else { 703 } else {
645 backing_store->set_length(length); 704 backing_store->set_length(length);
646 Address filler_start = backing_store->address() + 705 Address filler_start = backing_store->address() +
(...skipping 11 matching lines...) Expand all
658 return length_object; 717 return length_object;
659 } 718 }
660 719
661 // Check whether the backing store should be expanded. 720 // Check whether the backing store should be expanded.
662 uint32_t min = JSObject::NewElementsCapacity(old_capacity); 721 uint32_t min = JSObject::NewElementsCapacity(old_capacity);
663 uint32_t new_capacity = length > min ? length : min; 722 uint32_t new_capacity = length > min ? length : min;
664 if (!array->ShouldConvertToSlowElements(new_capacity)) { 723 if (!array->ShouldConvertToSlowElements(new_capacity)) {
665 MaybeObject* result = FastElementsAccessorSubclass:: 724 MaybeObject* result = FastElementsAccessorSubclass::
666 SetFastElementsCapacityAndLength(array, new_capacity, length); 725 SetFastElementsCapacityAndLength(array, new_capacity, length);
667 if (result->IsFailure()) return result; 726 if (result->IsFailure()) return result;
727 array->ValidateElements();
668 return length_object; 728 return length_object;
669 } 729 }
670 730
671 // Request conversion to slow elements. 731 // Request conversion to slow elements.
672 return array->GetHeap()->undefined_value(); 732 return array->GetHeap()->undefined_value();
673 } 733 }
674 };
675
676
677 class FastObjectElementsAccessor
678 : public FastElementsAccessor<FastObjectElementsAccessor,
679 ElementsKindTraits<FAST_ELEMENTS>,
680 kPointerSize> {
681 public:
682 explicit FastObjectElementsAccessor(const char* name)
683 : FastElementsAccessor<FastObjectElementsAccessor,
684 ElementsKindTraits<FAST_ELEMENTS>,
685 kPointerSize>(name) {}
686 734
687 static MaybeObject* DeleteCommon(JSObject* obj, 735 static MaybeObject* DeleteCommon(JSObject* obj,
688 uint32_t key) { 736 uint32_t key,
689 ASSERT(obj->HasFastElements() || 737 JSReceiver::DeleteMode mode) {
690 obj->HasFastSmiOnlyElements() || 738 ASSERT(obj->HasFastSmiOrObjectElements() ||
739 obj->HasFastDoubleElements() ||
691 obj->HasFastArgumentsElements()); 740 obj->HasFastArgumentsElements());
741 typename KindTraits::BackingStore* backing_store =
742 KindTraits::BackingStore::cast(obj->elements());
692 Heap* heap = obj->GetHeap(); 743 Heap* heap = obj->GetHeap();
693 FixedArray* backing_store = FixedArray::cast(obj->elements());
694 if (backing_store->map() == heap->non_strict_arguments_elements_map()) { 744 if (backing_store->map() == heap->non_strict_arguments_elements_map()) {
695 backing_store = FixedArray::cast(backing_store->get(1)); 745 backing_store =
746 KindTraits::BackingStore::cast(
747 FixedArray::cast(backing_store)->get(1));
696 } else { 748 } else {
697 Object* writable; 749 ElementsKind kind = KindTraits::Kind;
698 MaybeObject* maybe = obj->EnsureWritableFastElements(); 750 if (IsFastPackedElementsKind(kind)) {
699 if (!maybe->ToObject(&writable)) return maybe; 751 MaybeObject* transitioned =
700 backing_store = FixedArray::cast(writable); 752 obj->TransitionElementsKind(GetHoleyElementsKind(kind));
753 if (transitioned->IsFailure()) return transitioned;
754 }
755 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) {
756 Object* writable;
757 MaybeObject* maybe = obj->EnsureWritableFastElements();
758 if (!maybe->ToObject(&writable)) return maybe;
759 backing_store = KindTraits::BackingStore::cast(writable);
760 }
701 } 761 }
702 uint32_t length = static_cast<uint32_t>( 762 uint32_t length = static_cast<uint32_t>(
703 obj->IsJSArray() 763 obj->IsJSArray()
704 ? Smi::cast(JSArray::cast(obj)->length())->value() 764 ? Smi::cast(JSArray::cast(obj)->length())->value()
705 : backing_store->length()); 765 : backing_store->length());
706 if (key < length) { 766 if (key < length) {
707 backing_store->set_the_hole(key); 767 backing_store->set_the_hole(key);
708 // If an old space backing store is larger than a certain size and 768 // If an old space backing store is larger than a certain size and
709 // has too few used values, normalize it. 769 // has too few used values, normalize it.
710 // To avoid doing the check on every delete we require at least 770 // To avoid doing the check on every delete we require at least
711 // one adjacent hole to the value being deleted. 771 // one adjacent hole to the value being deleted.
712 Object* hole = heap->the_hole_value();
713 const int kMinLengthForSparsenessCheck = 64; 772 const int kMinLengthForSparsenessCheck = 64;
714 if (backing_store->length() >= kMinLengthForSparsenessCheck && 773 if (backing_store->length() >= kMinLengthForSparsenessCheck &&
715 !heap->InNewSpace(backing_store) && 774 !heap->InNewSpace(backing_store) &&
716 ((key > 0 && backing_store->get(key - 1) == hole) || 775 ((key > 0 && backing_store->is_the_hole(key - 1)) ||
717 (key + 1 < length && backing_store->get(key + 1) == hole))) { 776 (key + 1 < length && backing_store->is_the_hole(key + 1)))) {
718 int num_used = 0; 777 int num_used = 0;
719 for (int i = 0; i < backing_store->length(); ++i) { 778 for (int i = 0; i < backing_store->length(); ++i) {
720 if (backing_store->get(i) != hole) ++num_used; 779 if (!backing_store->is_the_hole(i)) ++num_used;
721 // Bail out early if more than 1/4 is used. 780 // Bail out early if more than 1/4 is used.
722 if (4 * num_used > backing_store->length()) break; 781 if (4 * num_used > backing_store->length()) break;
723 } 782 }
724 if (4 * num_used <= backing_store->length()) { 783 if (4 * num_used <= backing_store->length()) {
725 MaybeObject* result = obj->NormalizeElements(); 784 MaybeObject* result = obj->NormalizeElements();
726 if (result->IsFailure()) return result; 785 if (result->IsFailure()) return result;
727 } 786 }
728 } 787 }
729 } 788 }
730 return heap->true_value(); 789 return heap->true_value();
731 } 790 }
732 791
792 virtual MaybeObject* Delete(JSObject* obj,
793 uint32_t key,
794 JSReceiver::DeleteMode mode) {
795 return DeleteCommon(obj, key, mode);
796 }
797
798 static bool HasElementImpl(
799 Object* receiver,
800 JSObject* holder,
801 uint32_t key,
802 typename KindTraits::BackingStore* backing_store) {
803 return key < static_cast<uint32_t>(backing_store->length()) &&
804 !backing_store->is_the_hole(key);
805 }
806
807 static void ValidateContents(JSObject* holder, int length) {
808 #if DEBUG
809 FixedArrayBase* elements = holder->elements();
810 Heap* heap = elements->GetHeap();
811 Map* map = elements->map();
812 ASSERT((IsFastSmiOrObjectElementsKind(KindTraits::Kind) &&
813 (map == heap->fixed_array_map() ||
814 map == heap->fixed_cow_array_map())) ||
815 (IsFastDoubleElementsKind(KindTraits::Kind) ==
816 ((map == heap->fixed_array_map() && length == 0) ||
817 map == heap->fixed_double_array_map())));
818 for (int i = 0; i < length; i++) {
819 typename KindTraits::BackingStore* backing_store =
820 KindTraits::BackingStore::cast(elements);
821 ASSERT((!IsFastSmiElementsKind(KindTraits::Kind) ||
822 static_cast<Object*>(backing_store->get(i))->IsSmi()) ||
823 (IsFastHoleyElementsKind(KindTraits::Kind) ==
824 backing_store->is_the_hole(i)));
825 }
826 #endif
827 }
828 };
829
830
831 template<typename FastElementsAccessorSubclass,
832 typename KindTraits>
833 class FastSmiOrObjectElementsAccessor
834 : public FastElementsAccessor<FastElementsAccessorSubclass,
835 KindTraits,
836 kPointerSize> {
837 public:
838 explicit FastSmiOrObjectElementsAccessor(const char* name)
839 : FastElementsAccessor<FastElementsAccessorSubclass,
840 KindTraits,
841 kPointerSize>(name) {}
842
733 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, 843 static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
734 uint32_t from_start, 844 uint32_t from_start,
735 FixedArrayBase* to, 845 FixedArrayBase* to,
736 ElementsKind to_kind, 846 ElementsKind to_kind,
737 uint32_t to_start, 847 uint32_t to_start,
738 int copy_size) { 848 int copy_size) {
739 switch (to_kind) { 849 if (IsFastSmiOrObjectElementsKind(to_kind)) {
740 case FAST_SMI_ONLY_ELEMENTS: 850 CopyObjectToObjectElements(
741 case FAST_ELEMENTS: { 851 FixedArray::cast(from), KindTraits::Kind, from_start,
742 CopyObjectToObjectElements( 852 FixedArray::cast(to), to_kind, to_start, copy_size);
743 FixedArray::cast(from), ElementsTraits::Kind, from_start, 853 } else if (IsFastDoubleElementsKind(to_kind)) {
744 FixedArray::cast(to), to_kind, to_start, copy_size); 854 CopyObjectToDoubleElements(
745 return from; 855 FixedArray::cast(from), from_start,
746 } 856 FixedDoubleArray::cast(to), to_start, copy_size);
747 case FAST_DOUBLE_ELEMENTS: 857 } else {
748 CopyObjectToDoubleElements( 858 UNREACHABLE();
749 FixedArray::cast(from), from_start, 859 }
Jakob Kummerow 2012/05/13 21:55:27 nit: indentation
danno 2012/05/22 11:05:21 Done.
750 FixedDoubleArray::cast(to), to_start, copy_size);
751 return from;
752 default:
753 UNREACHABLE();
754 }
755 return to->GetHeap()->undefined_value(); 860 return to->GetHeap()->undefined_value();
756 } 861 }
757 862
758 863
759 static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj, 864 static MaybeObject* SetFastElementsCapacityAndLength(
760 uint32_t capacity, 865 JSObject* obj,
Jakob Kummerow 2012/05/13 21:55:27 nit: unnecessary formatting change?
danno 2012/05/22 11:05:21 Done.
761 uint32_t length) { 866 uint32_t capacity,
762 JSObject::SetFastElementsCapacityMode set_capacity_mode = 867 uint32_t length) {
763 obj->HasFastSmiOnlyElements() 868 JSObject::SetFastElementsCapacitySmiMode set_capacity_mode =
869 obj->HasFastSmiElements()
764 ? JSObject::kAllowSmiOnlyElements 870 ? JSObject::kAllowSmiOnlyElements
765 : JSObject::kDontAllowSmiOnlyElements; 871 : JSObject::kDontAllowSmiOnlyElements;
766 return obj->SetFastElementsCapacityAndLength(capacity, 872 return obj->SetFastElementsCapacityAndLength(capacity,
767 length, 873 length,
768 set_capacity_mode); 874 set_capacity_mode);
769 } 875 }
770
771 protected:
772 friend class FastElementsAccessor<FastObjectElementsAccessor,
773 ElementsKindTraits<FAST_ELEMENTS>,
774 kPointerSize>;
775
776 virtual MaybeObject* Delete(JSObject* obj,
777 uint32_t key,
778 JSReceiver::DeleteMode mode) {
779 return DeleteCommon(obj, key);
780 }
781 }; 876 };
782 877
783 878
879 class FastPackedSmiElementsAccessor
880 : public FastSmiOrObjectElementsAccessor<
881 FastPackedSmiElementsAccessor,
882 ElementsKindTraits<FAST_SMI_ELEMENTS> > {
883 public:
884 explicit FastPackedSmiElementsAccessor(const char* name)
885 : FastSmiOrObjectElementsAccessor<
886 FastPackedSmiElementsAccessor,
887 ElementsKindTraits<FAST_SMI_ELEMENTS> >(name) {}
888 };
889
Jakob Kummerow 2012/05/13 21:55:27 nit: two empty lines (several more times below)
danno 2012/05/22 11:05:21 Done.
890 class FastHoleySmiElementsAccessor
891 : public FastSmiOrObjectElementsAccessor<
892 FastHoleySmiElementsAccessor,
893 ElementsKindTraits<FAST_HOLEY_SMI_ELEMENTS> > {
894 public:
895 explicit FastHoleySmiElementsAccessor(const char* name)
896 : FastSmiOrObjectElementsAccessor<
897 FastHoleySmiElementsAccessor,
898 ElementsKindTraits<FAST_HOLEY_SMI_ELEMENTS> >(name) {}
899 };
900
901 class FastPackedObjectElementsAccessor
902 : public FastSmiOrObjectElementsAccessor<
903 FastPackedObjectElementsAccessor,
904 ElementsKindTraits<FAST_ELEMENTS> > {
905 public:
906 explicit FastPackedObjectElementsAccessor(const char* name)
907 : FastSmiOrObjectElementsAccessor<
908 FastPackedObjectElementsAccessor,
909 ElementsKindTraits<FAST_ELEMENTS> >(name) {}
910 };
911
912 class FastHoleyObjectElementsAccessor
913 : public FastSmiOrObjectElementsAccessor<
914 FastHoleyObjectElementsAccessor,
915 ElementsKindTraits<FAST_HOLEY_ELEMENTS> > {
916 public:
917 explicit FastHoleyObjectElementsAccessor(const char* name)
918 : FastSmiOrObjectElementsAccessor<
919 FastHoleyObjectElementsAccessor,
920 ElementsKindTraits<FAST_HOLEY_ELEMENTS> >(name) {}
921 };
922
923 template<typename FastElementsAccessorSubclass,
924 typename KindTraits>
784 class FastDoubleElementsAccessor 925 class FastDoubleElementsAccessor
785 : public FastElementsAccessor<FastDoubleElementsAccessor, 926 : public FastElementsAccessor<FastElementsAccessorSubclass,
786 ElementsKindTraits<FAST_DOUBLE_ELEMENTS>, 927 KindTraits,
787 kDoubleSize> { 928 kDoubleSize> {
788 public: 929 public:
789 explicit FastDoubleElementsAccessor(const char* name) 930 explicit FastDoubleElementsAccessor(const char* name)
790 : FastElementsAccessor<FastDoubleElementsAccessor, 931 : FastElementsAccessor<FastElementsAccessorSubclass,
791 ElementsKindTraits<FAST_DOUBLE_ELEMENTS>, 932 KindTraits,
792 kDoubleSize>(name) {} 933 kDoubleSize>(name) {}
793 934
794 static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj, 935 static MaybeObject* SetFastElementsCapacityAndLength(
Jakob Kummerow 2012/05/13 21:55:27 nit: yet more formatting changes
danno 2012/05/22 11:05:21 Done.
795 uint32_t capacity, 936 JSObject* obj,
796 uint32_t length) { 937 uint32_t capacity,
797 return obj->SetFastDoubleElementsCapacityAndLength(capacity, length); 938 uint32_t length) {
939 return obj->SetFastDoubleElementsCapacityAndLength(capacity,
940 length);
798 } 941 }
799 942
800 protected: 943 protected:
801 friend class ElementsAccessorBase<FastDoubleElementsAccessor,
802 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> >;
803 friend class FastElementsAccessor<FastDoubleElementsAccessor,
804 ElementsKindTraits<FAST_DOUBLE_ELEMENTS>,
805 kDoubleSize>;
806
807 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, 944 static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
808 uint32_t from_start, 945 uint32_t from_start,
809 FixedArrayBase* to, 946 FixedArrayBase* to,
810 ElementsKind to_kind, 947 ElementsKind to_kind,
811 uint32_t to_start, 948 uint32_t to_start,
812 int copy_size) { 949 int copy_size) {
813 switch (to_kind) { 950 switch (to_kind) {
814 case FAST_SMI_ONLY_ELEMENTS: 951 case FAST_SMI_ELEMENTS:
815 case FAST_ELEMENTS: 952 case FAST_ELEMENTS:
953 case FAST_HOLEY_SMI_ELEMENTS:
954 case FAST_HOLEY_ELEMENTS:
816 return CopyDoubleToObjectElements( 955 return CopyDoubleToObjectElements(
817 FixedDoubleArray::cast(from), from_start, FixedArray::cast(to), 956 FixedDoubleArray::cast(from), from_start, FixedArray::cast(to),
818 to_kind, to_start, copy_size); 957 to_kind, to_start, copy_size);
819 case FAST_DOUBLE_ELEMENTS: 958 case FAST_DOUBLE_ELEMENTS:
959 case FAST_HOLEY_DOUBLE_ELEMENTS:
820 CopyDoubleToDoubleElements(FixedDoubleArray::cast(from), from_start, 960 CopyDoubleToDoubleElements(FixedDoubleArray::cast(from), from_start,
821 FixedDoubleArray::cast(to), 961 FixedDoubleArray::cast(to),
822 to_start, copy_size); 962 to_start, copy_size);
823 return from; 963 return from;
824 default: 964 default:
825 UNREACHABLE(); 965 UNREACHABLE();
826 } 966 }
827 return to->GetHeap()->undefined_value(); 967 return to->GetHeap()->undefined_value();
828 } 968 }
829
830 virtual MaybeObject* Delete(JSObject* obj,
831 uint32_t key,
832 JSReceiver::DeleteMode mode) {
833 int length = obj->IsJSArray()
834 ? Smi::cast(JSArray::cast(obj)->length())->value()
835 : FixedDoubleArray::cast(obj->elements())->length();
836 if (key < static_cast<uint32_t>(length)) {
837 FixedDoubleArray::cast(obj->elements())->set_the_hole(key);
838 }
839 return obj->GetHeap()->true_value();
840 }
841
842 static bool HasElementImpl(Object* receiver,
843 JSObject* holder,
844 uint32_t key,
845 FixedDoubleArray* backing_store) {
846 return key < static_cast<uint32_t>(backing_store->length()) &&
847 !backing_store->is_the_hole(key);
848 }
849 }; 969 };
850 970
851 971
972 class FastPackedDoubleElementsAccessor
973 : public FastDoubleElementsAccessor<
974 FastPackedDoubleElementsAccessor,
Jakob Kummerow 2012/05/13 21:55:27 nit: indentation (same for FastHoleyDoubleElements
danno 2012/05/22 11:05:21 Done.
975 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> > {
976 public:
977 friend class ElementsAccessorBase<FastPackedDoubleElementsAccessor,
978 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> >;
979 explicit FastPackedDoubleElementsAccessor(const char* name)
980 : FastDoubleElementsAccessor<
981 FastPackedDoubleElementsAccessor,
Jakob Kummerow 2012/05/13 21:55:27 again
danno 2012/05/22 11:05:21 Done.
982 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> >(name) {}
983 };
984
985 class FastHoleyDoubleElementsAccessor
986 : public FastDoubleElementsAccessor<
987 FastHoleyDoubleElementsAccessor,
988 ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> > {
989 public:
990 friend class ElementsAccessorBase<
991 FastHoleyDoubleElementsAccessor,
992 ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> >;
993 explicit FastHoleyDoubleElementsAccessor(const char* name)
994 : FastDoubleElementsAccessor<
995 FastHoleyDoubleElementsAccessor,
996 ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> >(name) {}
997 };
998
852 // Super class for all external element arrays. 999 // Super class for all external element arrays.
853 template<typename ExternalElementsAccessorSubclass, 1000 template<typename ExternalElementsAccessorSubclass,
854 ElementsKind Kind> 1001 ElementsKind Kind>
855 class ExternalElementsAccessor 1002 class ExternalElementsAccessor
856 : public ElementsAccessorBase<ExternalElementsAccessorSubclass, 1003 : public ElementsAccessorBase<ExternalElementsAccessorSubclass,
857 ElementsKindTraits<Kind> > { 1004 ElementsKindTraits<Kind> > {
858 public: 1005 public:
859 explicit ExternalElementsAccessor(const char* name) 1006 explicit ExternalElementsAccessor(const char* name)
860 : ElementsAccessorBase<ExternalElementsAccessorSubclass, 1007 : ElementsAccessorBase<ExternalElementsAccessorSubclass,
861 ElementsKindTraits<Kind> >(name) {} 1008 ElementsKindTraits<Kind> >(name) {}
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
1102 return heap->true_value(); 1249 return heap->true_value();
1103 } 1250 }
1104 1251
1105 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, 1252 static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
1106 uint32_t from_start, 1253 uint32_t from_start,
1107 FixedArrayBase* to, 1254 FixedArrayBase* to,
1108 ElementsKind to_kind, 1255 ElementsKind to_kind,
1109 uint32_t to_start, 1256 uint32_t to_start,
1110 int copy_size) { 1257 int copy_size) {
1111 switch (to_kind) { 1258 switch (to_kind) {
1112 case FAST_SMI_ONLY_ELEMENTS: 1259 case FAST_SMI_ELEMENTS:
1113 case FAST_ELEMENTS: 1260 case FAST_ELEMENTS:
1261 case FAST_HOLEY_SMI_ELEMENTS:
1262 case FAST_HOLEY_ELEMENTS:
1114 CopyDictionaryToObjectElements( 1263 CopyDictionaryToObjectElements(
1115 SeededNumberDictionary::cast(from), from_start, 1264 SeededNumberDictionary::cast(from), from_start,
1116 FixedArray::cast(to), to_kind, to_start, copy_size); 1265 FixedArray::cast(to), to_kind, to_start, copy_size);
1117 return from; 1266 return from;
1118 case FAST_DOUBLE_ELEMENTS: 1267 case FAST_DOUBLE_ELEMENTS:
1268 case FAST_HOLEY_DOUBLE_ELEMENTS:
1119 CopyDictionaryToDoubleElements( 1269 CopyDictionaryToDoubleElements(
1120 SeededNumberDictionary::cast(from), from_start, 1270 SeededNumberDictionary::cast(from), from_start,
1121 FixedDoubleArray::cast(to), to_start, copy_size); 1271 FixedDoubleArray::cast(to), to_start, copy_size);
1122 return from; 1272 return from;
1123 default: 1273 default:
1124 UNREACHABLE(); 1274 UNREACHABLE();
1125 } 1275 }
1126 return to->GetHeap()->undefined_value(); 1276 return to->GetHeap()->undefined_value();
1127 } 1277 }
1128 1278
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 if (!probe->IsTheHole()) { 1383 if (!probe->IsTheHole()) {
1234 // TODO(kmillikin): We could check if this was the last aliased 1384 // TODO(kmillikin): We could check if this was the last aliased
1235 // parameter, and revert to normal elements in that case. That 1385 // parameter, and revert to normal elements in that case. That
1236 // would enable GC of the context. 1386 // would enable GC of the context.
1237 parameter_map->set_the_hole(key + 2); 1387 parameter_map->set_the_hole(key + 2);
1238 } else { 1388 } else {
1239 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1389 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1240 if (arguments->IsDictionary()) { 1390 if (arguments->IsDictionary()) {
1241 return DictionaryElementsAccessor::DeleteCommon(obj, key, mode); 1391 return DictionaryElementsAccessor::DeleteCommon(obj, key, mode);
1242 } else { 1392 } else {
1243 return FastObjectElementsAccessor::DeleteCommon(obj, key); 1393 // It's difficult to access the version of DeleteCommon that is declared
1394 // in the templatized super class, call the concrete implementation in
1395 // the class for the most generalized ElementsKind subclass.
1396 return FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, mode);
1244 } 1397 }
1245 } 1398 }
1246 return obj->GetHeap()->true_value(); 1399 return obj->GetHeap()->true_value();
1247 } 1400 }
1248 1401
1249 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, 1402 static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
1250 uint32_t from_start, 1403 uint32_t from_start,
1251 FixedArrayBase* to, 1404 FixedArrayBase* to,
1252 ElementsKind to_kind, 1405 ElementsKind to_kind,
1253 uint32_t to_start, 1406 uint32_t to_start,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 } 1450 }
1298 }; 1451 };
1299 1452
1300 1453
1301 ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) { 1454 ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) {
1302 switch (array->map()->instance_type()) { 1455 switch (array->map()->instance_type()) {
1303 case FIXED_ARRAY_TYPE: 1456 case FIXED_ARRAY_TYPE:
1304 if (array->IsDictionary()) { 1457 if (array->IsDictionary()) {
1305 return elements_accessors_[DICTIONARY_ELEMENTS]; 1458 return elements_accessors_[DICTIONARY_ELEMENTS];
1306 } else { 1459 } else {
1307 return elements_accessors_[FAST_ELEMENTS]; 1460 return elements_accessors_[FAST_HOLEY_ELEMENTS];
1308 } 1461 }
1309 case EXTERNAL_BYTE_ARRAY_TYPE: 1462 case EXTERNAL_BYTE_ARRAY_TYPE:
1310 return elements_accessors_[EXTERNAL_BYTE_ELEMENTS]; 1463 return elements_accessors_[EXTERNAL_BYTE_ELEMENTS];
1311 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: 1464 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
1312 return elements_accessors_[EXTERNAL_UNSIGNED_BYTE_ELEMENTS]; 1465 return elements_accessors_[EXTERNAL_UNSIGNED_BYTE_ELEMENTS];
1313 case EXTERNAL_SHORT_ARRAY_TYPE: 1466 case EXTERNAL_SHORT_ARRAY_TYPE:
1314 return elements_accessors_[EXTERNAL_SHORT_ELEMENTS]; 1467 return elements_accessors_[EXTERNAL_SHORT_ELEMENTS];
1315 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE: 1468 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
1316 return elements_accessors_[EXTERNAL_UNSIGNED_SHORT_ELEMENTS]; 1469 return elements_accessors_[EXTERNAL_UNSIGNED_SHORT_ELEMENTS];
1317 case EXTERNAL_INT_ARRAY_TYPE: 1470 case EXTERNAL_INT_ARRAY_TYPE:
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1408 if (!maybe_obj->To(&new_backing_store)) return maybe_obj; 1561 if (!maybe_obj->To(&new_backing_store)) return maybe_obj;
1409 new_backing_store->set(0, length); 1562 new_backing_store->set(0, length);
1410 { MaybeObject* result = array->SetContent(new_backing_store); 1563 { MaybeObject* result = array->SetContent(new_backing_store);
1411 if (result->IsFailure()) return result; 1564 if (result->IsFailure()) return result;
1412 } 1565 }
1413 return array; 1566 return array;
1414 } 1567 }
1415 1568
1416 1569
1417 } } // namespace v8::internal 1570 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698