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

Side by Side Diff: src/elements.cc

Issue 9638014: Implement efficient element copying in ElementsAccessors. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback Created 8 years, 9 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 | « src/elements.h ('k') | src/objects.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 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 // - ExternalDoubleElementsAccessor 52 // - ExternalDoubleElementsAccessor
53 // - PixelElementsAccessor 53 // - PixelElementsAccessor
54 // - DictionaryElementsAccessor 54 // - DictionaryElementsAccessor
55 // - NonStrictArgumentsElementsAccessor 55 // - NonStrictArgumentsElementsAccessor
56 56
57 57
58 namespace v8 { 58 namespace v8 {
59 namespace internal { 59 namespace internal {
60 60
61 61
62 // 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
64 // 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
66 // the |accessor_array[]| below to work.
67 #define ELEMENTS_LIST(V) \
68 V(FastObjectElementsAccessor, FAST_SMI_ONLY_ELEMENTS, FixedArray) \
69 V(FastObjectElementsAccessor, FAST_ELEMENTS, FixedArray) \
70 V(FastDoubleElementsAccessor, FAST_DOUBLE_ELEMENTS, FixedDoubleArray) \
71 V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS, \
72 SeededNumberDictionary) \
73 V(NonStrictArgumentsElementsAccessor, NON_STRICT_ARGUMENTS_ELEMENTS, \
74 FixedArray) \
75 V(ExternalByteElementsAccessor, EXTERNAL_BYTE_ELEMENTS, \
76 ExternalByteArray) \
77 V(ExternalUnsignedByteElementsAccessor, \
78 EXTERNAL_UNSIGNED_BYTE_ELEMENTS, ExternalUnsignedByteArray) \
79 V(ExternalShortElementsAccessor, EXTERNAL_SHORT_ELEMENTS, \
80 ExternalShortArray) \
81 V(ExternalUnsignedShortElementsAccessor, \
82 EXTERNAL_UNSIGNED_SHORT_ELEMENTS, ExternalUnsignedShortArray) \
83 V(ExternalIntElementsAccessor, EXTERNAL_INT_ELEMENTS, \
84 ExternalIntArray) \
85 V(ExternalUnsignedIntElementsAccessor, \
86 EXTERNAL_UNSIGNED_INT_ELEMENTS, ExternalUnsignedIntArray) \
87 V(ExternalFloatElementsAccessor, \
88 EXTERNAL_FLOAT_ELEMENTS, ExternalFloatArray) \
89 V(ExternalDoubleElementsAccessor, \
90 EXTERNAL_DOUBLE_ELEMENTS, ExternalDoubleArray) \
91 V(PixelElementsAccessor, EXTERNAL_PIXEL_ELEMENTS, ExternalPixelArray)
92
93
94 template<ElementsKind Kind> class ElementsKindTraits {
95 public:
96 typedef FixedArrayBase BackingStore;
97 };
98
99 #define ELEMENTS_TRAITS(Class, KindParam, Store) \
100 template<> class ElementsKindTraits<KindParam> { \
101 public: \
102 static const ElementsKind Kind = KindParam; \
103 typedef Store BackingStore; \
104 };
105 ELEMENTS_LIST(ELEMENTS_TRAITS)
106 #undef ELEMENTS_TRAITS
107
108
62 ElementsAccessor** ElementsAccessor::elements_accessors_; 109 ElementsAccessor** ElementsAccessor::elements_accessors_;
63 110
64 111
65 static bool HasKey(FixedArray* array, Object* key) { 112 static bool HasKey(FixedArray* array, Object* key) {
66 int len0 = array->length(); 113 int len0 = array->length();
67 for (int i = 0; i < len0; i++) { 114 for (int i = 0; i < len0; i++) {
68 Object* element = array->get(i); 115 Object* element = array->get(i);
69 if (element->IsSmi() && element == key) return true; 116 if (element->IsSmi() && element == key) return true;
70 if (element->IsString() && 117 if (element->IsString() &&
71 key->IsString() && String::cast(element)->Equals(String::cast(key))) { 118 key->IsString() && String::cast(element)->Equals(String::cast(key))) {
72 return true; 119 return true;
73 } 120 }
74 } 121 }
75 return false; 122 return false;
76 } 123 }
77 124
78 125
79 static Failure* ThrowArrayLengthRangeError(Heap* heap) { 126 static Failure* ThrowArrayLengthRangeError(Heap* heap) {
80 HandleScope scope(heap->isolate()); 127 HandleScope scope(heap->isolate());
81 return heap->isolate()->Throw( 128 return heap->isolate()->Throw(
82 *heap->isolate()->factory()->NewRangeError("invalid_array_length", 129 *heap->isolate()->factory()->NewRangeError("invalid_array_length",
83 HandleVector<Object>(NULL, 0))); 130 HandleVector<Object>(NULL, 0)));
84 } 131 }
85 132
86 133
134 void CopyObjectToObjectElements(AssertNoAllocation* no_gc,
135 FixedArray* from_obj,
136 ElementsKind from_kind,
137 uint32_t from_start,
138 FixedArray* to_obj,
139 ElementsKind to_kind,
140 uint32_t to_start,
141 int copy_size) {
142 ASSERT(to_obj->map() != HEAP->fixed_cow_array_map());
143 ASSERT(from_kind == FAST_ELEMENTS || from_kind == FAST_SMI_ONLY_ELEMENTS);
144 ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS);
145 if (copy_size == -1) copy_size = from_obj->length() - from_start;
146 ASSERT(((copy_size + static_cast<int>(to_start)) <= to_obj->length() &&
147 (copy_size + static_cast<int>(from_start)) <= from_obj->length()));
148 if (copy_size == 0) return;
149 Address to = to_obj->address() + FixedArray::kHeaderSize;
150 Address from = from_obj->address() + FixedArray::kHeaderSize;
151 CopyWords(reinterpret_cast<Object**>(to) + to_start,
152 reinterpret_cast<Object**>(from) + from_start,
153 copy_size);
154 if (from_kind == FAST_ELEMENTS && to_kind == FAST_ELEMENTS) {
155 Heap* heap = from_obj->GetHeap();
156 WriteBarrierMode mode = to_obj->GetWriteBarrierMode(*no_gc);
157 if (mode == UPDATE_WRITE_BARRIER) {
158 heap->RecordWrites(to_obj->address(),
159 to_obj->OffsetOfElementAt(to_start),
160 copy_size);
161 }
162 heap->incremental_marking()->RecordWrites(to_obj);
163 }
164 }
165
166
167
168
169 static void CopyDictionaryToObjectElements(SeededNumberDictionary* from,
170 uint32_t from_start,
171 FixedArray* to,
172 ElementsKind to_kind,
173 uint32_t to_start,
174 int copy_size) {
175 ASSERT(to != from);
176 ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS);
177 ASSERT(copy_size == -1 ||
178 (copy_size + static_cast<int>(to_start)) <= to->length());
179 WriteBarrierMode mode = to_kind == FAST_ELEMENTS
180 ? UPDATE_WRITE_BARRIER
181 : SKIP_WRITE_BARRIER;
182 for (int i = 0; i < from->Capacity(); ++i) {
183 Object* key = from->KeyAt(i);
184 if (key->IsNumber()) {
185 uint32_t entry = static_cast<uint32_t>(key->Number());
186 if ((entry >= to_start) &&
187 (entry < to_start + copy_size || copy_size == -1)) {
188 Object* value = from->ValueAt(i);
189 ASSERT(to_kind == FAST_ELEMENTS || value->IsSmi());
190 to->set(entry, value, mode);
191 }
192 }
193 }
194 }
195
196
197 MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements(
198 FixedDoubleArray* from_obj,
199 uint32_t from_start,
200 FixedArray* to_obj,
201 ElementsKind to_kind,
202 uint32_t to_start,
203 int copy_size) {
204 ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS);
205 if (copy_size == -1) copy_size = from_obj->length() - from_start;
206 ASSERT(((copy_size + static_cast<int>(to_start)) <= to_obj->length() &&
207 (copy_size + static_cast<int>(from_start)) <= from_obj->length()));
208 if (copy_size == 0) return from_obj;
209 for (int i = 0; i < copy_size; ++i) {
210 if (to_kind == FAST_SMI_ONLY_ELEMENTS) {
211 UNIMPLEMENTED();
212 return Failure::Exception();
213 } else {
214 MaybeObject* maybe_value = from_obj->get(i + from_start);
215 Object* value;
216 ASSERT(to_kind == FAST_ELEMENTS);
217 // Because FAST_DOUBLE_ELEMENTS -> FAST_ELEMENT allocate HeapObjects
218 // iteratively, the allocate must succeed within a single GC cycle,
219 // otherwise the retry after the GC will also fail. In order to ensure
220 // that no GC is triggered, allocate HeapNumbers from old space if they
221 // can't be taken from new space.
222 if (!maybe_value->ToObject(&value)) {
Michael Starzinger 2012/03/09 12:34:32 If you are sure that this can only fail because of
danno 2012/03/09 13:21:07 Done.
223 Heap* heap = from_obj->GetHeap();
224 MaybeObject* maybe_value_object =
225 heap->AllocateHeapNumber(from_obj->get_scalar(i), TENURED);
Michael Starzinger 2012/03/09 12:34:32 Shouldn't this be "get_scalar(i + from_start)" her
danno 2012/03/09 13:21:07 Done.
226 if (!maybe_value_object->ToObject(&value)) return maybe_value_object;
227 }
228 to_obj->set(i + to_start, value, UPDATE_WRITE_BARRIER);
229 }
230 }
231 return to_obj;
232 }
233
234
235 static void CopyDoubleToDoubleElements(FixedDoubleArray* from_obj,
236 uint32_t from_start,
237 FixedDoubleArray* to_obj,
238 uint32_t to_start,
239 int copy_size) {
240 if (copy_size == -1) copy_size = from_obj->length() - from_start;
241 ASSERT(((copy_size + static_cast<int>(to_start)) <= to_obj->length() &&
242 (copy_size + static_cast<int>(from_start)) <= from_obj->length()));
243 if (copy_size == 0) return;
244 Address to = to_obj->address() + FixedDoubleArray::kHeaderSize;
245 Address from = from_obj->address() + FixedDoubleArray::kHeaderSize;
246 to += kDoubleSize * to_start;
247 from += kDoubleSize * from_start;
248 int words_per_double = (kDoubleSize / kPointerSize);
249 CopyWords(reinterpret_cast<Object**>(to),
250 reinterpret_cast<Object**>(from),
251 words_per_double * copy_size);
252 }
253
254
87 // Base class for element handler implementations. Contains the 255 // Base class for element handler implementations. Contains the
88 // the common logic for objects with different ElementsKinds. 256 // the common logic for objects with different ElementsKinds.
89 // Subclasses must specialize method for which the element 257 // Subclasses must specialize method for which the element
90 // implementation differs from the base class implementation. 258 // implementation differs from the base class implementation.
91 // 259 //
92 // This class is intended to be used in the following way: 260 // This class is intended to be used in the following way:
93 // 261 //
94 // class SomeElementsAccessor : 262 // class SomeElementsAccessor :
95 // public ElementsAccessorBase<SomeElementsAccessor, 263 // public ElementsAccessorBase<SomeElementsAccessor,
96 // BackingStoreClass> { 264 // BackingStoreClass> {
97 // ... 265 // ...
98 // } 266 // }
99 // 267 //
100 // This is an example of the Curiously Recurring Template Pattern (see 268 // This is an example of the Curiously Recurring Template Pattern (see
101 // http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). We use 269 // http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). We use
102 // CRTP to guarantee aggressive compile time optimizations (i.e. inlining and 270 // CRTP to guarantee aggressive compile time optimizations (i.e. inlining and
103 // specialization of SomeElementsAccessor methods). 271 // specialization of SomeElementsAccessor methods).
104 template <typename ElementsAccessorSubclass, typename BackingStoreClass> 272 template <typename ElementsAccessorSubclass,
273 typename ElementsTraitsParam>
105 class ElementsAccessorBase : public ElementsAccessor { 274 class ElementsAccessorBase : public ElementsAccessor {
106 protected: 275 protected:
107 explicit ElementsAccessorBase(const char* name) : ElementsAccessor(name) { } 276 explicit ElementsAccessorBase(const char* name)
277 : ElementsAccessor(name) { }
278
279 typedef ElementsTraitsParam ElementsTraits;
280 typedef typename ElementsTraitsParam::BackingStore BackingStore;
281
282 virtual ElementsKind kind() const { return ElementsTraits::Kind; }
108 283
109 static bool HasElementImpl(Object* receiver, 284 static bool HasElementImpl(Object* receiver,
110 JSObject* holder, 285 JSObject* holder,
111 uint32_t key, 286 uint32_t key,
112 BackingStoreClass* backing_store) { 287 BackingStore* backing_store) {
113 MaybeObject* element = 288 MaybeObject* element =
114 ElementsAccessorSubclass::GetImpl(receiver, holder, key, backing_store); 289 ElementsAccessorSubclass::GetImpl(receiver, holder, key, backing_store);
115 return !element->IsTheHole(); 290 return !element->IsTheHole();
116 } 291 }
117 292
118 virtual bool HasElement(Object* receiver, 293 virtual bool HasElement(Object* receiver,
119 JSObject* holder, 294 JSObject* holder,
120 uint32_t key, 295 uint32_t key,
121 FixedArrayBase* backing_store) { 296 FixedArrayBase* backing_store) {
122 if (backing_store == NULL) { 297 if (backing_store == NULL) {
123 backing_store = holder->elements(); 298 backing_store = holder->elements();
124 } 299 }
125 return ElementsAccessorSubclass::HasElementImpl( 300 return ElementsAccessorSubclass::HasElementImpl(
126 receiver, holder, key, BackingStoreClass::cast(backing_store)); 301 receiver, holder, key, BackingStore::cast(backing_store));
127 } 302 }
128 303
129 virtual MaybeObject* Get(Object* receiver, 304 virtual MaybeObject* Get(Object* receiver,
130 JSObject* holder, 305 JSObject* holder,
131 uint32_t key, 306 uint32_t key,
132 FixedArrayBase* backing_store) { 307 FixedArrayBase* backing_store) {
133 if (backing_store == NULL) { 308 if (backing_store == NULL) {
134 backing_store = holder->elements(); 309 backing_store = holder->elements();
135 } 310 }
136 return ElementsAccessorSubclass::GetImpl( 311 return ElementsAccessorSubclass::GetImpl(
137 receiver, holder, key, BackingStoreClass::cast(backing_store)); 312 receiver, holder, key, BackingStore::cast(backing_store));
138 } 313 }
139 314
140 static MaybeObject* GetImpl(Object* receiver, 315 static MaybeObject* GetImpl(Object* receiver,
141 JSObject* obj, 316 JSObject* obj,
142 uint32_t key, 317 uint32_t key,
143 BackingStoreClass* backing_store) { 318 BackingStore* backing_store) {
144 return (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store)) 319 return (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store))
145 ? backing_store->get(key) 320 ? backing_store->get(key)
146 : backing_store->GetHeap()->the_hole_value(); 321 : backing_store->GetHeap()->the_hole_value();
147 } 322 }
148 323
149 virtual MaybeObject* SetLength(JSArray* array, 324 virtual MaybeObject* SetLength(JSArray* array,
150 Object* length) { 325 Object* length) {
151 return ElementsAccessorSubclass::SetLengthImpl( 326 return ElementsAccessorSubclass::SetLengthImpl(
152 array, length, BackingStoreClass::cast(array->elements())); 327 array, length, BackingStore::cast(array->elements()));
153 } 328 }
154 329
155 static MaybeObject* SetLengthImpl(JSObject* obj, 330 static MaybeObject* SetLengthImpl(JSObject* obj,
156 Object* length, 331 Object* length,
157 BackingStoreClass* backing_store); 332 BackingStore* backing_store);
158 333
159 virtual MaybeObject* SetCapacityAndLength(JSArray* array, 334 virtual MaybeObject* SetCapacityAndLength(JSArray* array,
160 int capacity, 335 int capacity,
161 int length) { 336 int length) {
162 return ElementsAccessorSubclass::SetFastElementsCapacityAndLength( 337 return ElementsAccessorSubclass::SetFastElementsCapacityAndLength(
163 array, 338 array,
164 capacity, 339 capacity,
165 length); 340 length);
166 } 341 }
167 342
168 static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj, 343 static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj,
169 int capacity, 344 int capacity,
170 int length) { 345 int length) {
171 UNIMPLEMENTED(); 346 UNIMPLEMENTED();
172 return obj; 347 return obj;
173 } 348 }
174 349
175 virtual MaybeObject* Delete(JSObject* obj, 350 virtual MaybeObject* Delete(JSObject* obj,
176 uint32_t key, 351 uint32_t key,
177 JSReceiver::DeleteMode mode) = 0; 352 JSReceiver::DeleteMode mode) = 0;
178 353
354 static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
355 uint32_t from_start,
356 FixedArrayBase* to,
357 ElementsKind to_kind,
358 uint32_t to_start,
359 int copy_size) {
360 UNREACHABLE();
361 return NULL;
362 }
363
364 virtual MaybeObject* CopyElements(JSObject* from_holder,
365 uint32_t from_start,
366 FixedArrayBase* to,
367 ElementsKind to_kind,
368 uint32_t to_start,
369 int copy_size,
370 FixedArrayBase* from) {
371 if (from == NULL) {
372 from = from_holder->elements();
373 }
374 return ElementsAccessorSubclass::CopyElementsImpl(
375 from, from_start, to, to_kind, to_start, copy_size);
376 }
377
179 virtual MaybeObject* AddElementsToFixedArray(Object* receiver, 378 virtual MaybeObject* AddElementsToFixedArray(Object* receiver,
180 JSObject* holder, 379 JSObject* holder,
181 FixedArray* to, 380 FixedArray* to,
182 FixedArrayBase* from) { 381 FixedArrayBase* from) {
183 int len0 = to->length(); 382 int len0 = to->length();
184 #ifdef DEBUG 383 #ifdef DEBUG
185 if (FLAG_enable_slow_asserts) { 384 if (FLAG_enable_slow_asserts) {
186 for (int i = 0; i < len0; i++) { 385 for (int i = 0; i < len0; i++) {
187 ASSERT(!to->get(i)->IsTheHole()); 386 ASSERT(!to->get(i)->IsTheHole());
188 } 387 }
189 } 388 }
190 #endif 389 #endif
191 if (from == NULL) { 390 if (from == NULL) {
192 from = holder->elements(); 391 from = holder->elements();
193 } 392 }
194 BackingStoreClass* backing_store = BackingStoreClass::cast(from); 393 BackingStore* backing_store = BackingStore::cast(from);
195 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(backing_store); 394 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(backing_store);
196 395
197 // Optimize if 'other' is empty. 396 // Optimize if 'other' is empty.
198 // We cannot optimize if 'this' is empty, as other may have holes. 397 // We cannot optimize if 'this' is empty, as other may have holes.
199 if (len1 == 0) return to; 398 if (len1 == 0) return to;
200 399
201 // Compute how many elements are not in other. 400 // Compute how many elements are not in other.
202 uint32_t extra = 0; 401 uint32_t extra = 0;
203 for (uint32_t y = 0; y < len1; y++) { 402 for (uint32_t y = 0; y < len1; y++) {
204 uint32_t key = 403 uint32_t key =
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 result->set(len0 + index, value); 450 result->set(len0 + index, value);
252 index++; 451 index++;
253 } 452 }
254 } 453 }
255 } 454 }
256 ASSERT(extra == index); 455 ASSERT(extra == index);
257 return result; 456 return result;
258 } 457 }
259 458
260 protected: 459 protected:
261 static uint32_t GetCapacityImpl(BackingStoreClass* backing_store) { 460 static uint32_t GetCapacityImpl(BackingStore* backing_store) {
262 return backing_store->length(); 461 return backing_store->length();
263 } 462 }
264 463
265 virtual uint32_t GetCapacity(FixedArrayBase* backing_store) { 464 virtual uint32_t GetCapacity(FixedArrayBase* backing_store) {
266 return ElementsAccessorSubclass::GetCapacityImpl( 465 return ElementsAccessorSubclass::GetCapacityImpl(
267 BackingStoreClass::cast(backing_store)); 466 BackingStore::cast(backing_store));
268 } 467 }
269 468
270 static uint32_t GetKeyForIndexImpl(BackingStoreClass* backing_store, 469 static uint32_t GetKeyForIndexImpl(BackingStore* backing_store,
271 uint32_t index) { 470 uint32_t index) {
272 return index; 471 return index;
273 } 472 }
274 473
275 virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store, 474 virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store,
276 uint32_t index) { 475 uint32_t index) {
277 return ElementsAccessorSubclass::GetKeyForIndexImpl( 476 return ElementsAccessorSubclass::GetKeyForIndexImpl(
278 BackingStoreClass::cast(backing_store), index); 477 BackingStore::cast(backing_store), index);
279 } 478 }
280 479
281 private: 480 private:
282 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); 481 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase);
283 }; 482 };
284 483
285 484
286 // Super class for all fast element arrays. 485 // Super class for all fast element arrays.
287 template<typename FastElementsAccessorSubclass, 486 template<typename FastElementsAccessorSubclass,
288 typename BackingStore, 487 typename KindTraits,
289 int ElementSize> 488 int ElementSize>
290 class FastElementsAccessor 489 class FastElementsAccessor
291 : public ElementsAccessorBase<FastElementsAccessorSubclass, BackingStore> { 490 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> {
292 public: 491 public:
293 explicit FastElementsAccessor(const char* name) 492 explicit FastElementsAccessor(const char* name)
294 : ElementsAccessorBase<FastElementsAccessorSubclass, 493 : ElementsAccessorBase<FastElementsAccessorSubclass,
295 BackingStore>(name) {} 494 KindTraits>(name) {}
296 protected: 495 protected:
297 friend class ElementsAccessorBase<FastElementsAccessorSubclass, BackingStore>; 496 friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>;
497
498 typedef typename KindTraits::BackingStore BackingStore;
298 499
299 // Adjusts the length of the fast backing store or returns the new length or 500 // Adjusts the length of the fast backing store or returns the new length or
300 // undefined in case conversion to a slow backing store should be performed. 501 // undefined in case conversion to a slow backing store should be performed.
301 static MaybeObject* SetLengthWithoutNormalize(BackingStore* backing_store, 502 static MaybeObject* SetLengthWithoutNormalize(BackingStore* backing_store,
302 JSArray* array, 503 JSArray* array,
303 Object* length_object, 504 Object* length_object,
304 uint32_t length) { 505 uint32_t length) {
305 uint32_t old_capacity = backing_store->length(); 506 uint32_t old_capacity = backing_store->length();
306 507
307 // Check whether the backing store should be shrunk. 508 // Check whether the backing store should be shrunk.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 } 543 }
343 544
344 // Request conversion to slow elements. 545 // Request conversion to slow elements.
345 return array->GetHeap()->undefined_value(); 546 return array->GetHeap()->undefined_value();
346 } 547 }
347 }; 548 };
348 549
349 550
350 class FastObjectElementsAccessor 551 class FastObjectElementsAccessor
351 : public FastElementsAccessor<FastObjectElementsAccessor, 552 : public FastElementsAccessor<FastObjectElementsAccessor,
352 FixedArray, 553 ElementsKindTraits<FAST_ELEMENTS>,
353 kPointerSize> { 554 kPointerSize> {
354 public: 555 public:
355 explicit FastObjectElementsAccessor(const char* name) 556 explicit FastObjectElementsAccessor(const char* name)
356 : FastElementsAccessor<FastObjectElementsAccessor, 557 : FastElementsAccessor<FastObjectElementsAccessor,
357 FixedArray, 558 ElementsKindTraits<FAST_ELEMENTS>,
358 kPointerSize>(name) {} 559 kPointerSize>(name) {}
359 560
360 static MaybeObject* DeleteCommon(JSObject* obj, 561 static MaybeObject* DeleteCommon(JSObject* obj,
361 uint32_t key) { 562 uint32_t key) {
362 ASSERT(obj->HasFastElements() || 563 ASSERT(obj->HasFastElements() ||
363 obj->HasFastSmiOnlyElements() || 564 obj->HasFastSmiOnlyElements() ||
364 obj->HasFastArgumentsElements()); 565 obj->HasFastArgumentsElements());
365 Heap* heap = obj->GetHeap(); 566 Heap* heap = obj->GetHeap();
366 FixedArray* backing_store = FixedArray::cast(obj->elements()); 567 FixedArray* backing_store = FixedArray::cast(obj->elements());
367 if (backing_store->map() == heap->non_strict_arguments_elements_map()) { 568 if (backing_store->map() == heap->non_strict_arguments_elements_map()) {
(...skipping 28 matching lines...) Expand all
396 } 597 }
397 if (4 * num_used <= backing_store->length()) { 598 if (4 * num_used <= backing_store->length()) {
398 MaybeObject* result = obj->NormalizeElements(); 599 MaybeObject* result = obj->NormalizeElements();
399 if (result->IsFailure()) return result; 600 if (result->IsFailure()) return result;
400 } 601 }
401 } 602 }
402 } 603 }
403 return heap->true_value(); 604 return heap->true_value();
404 } 605 }
405 606
607 static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
608 uint32_t from_start,
609 FixedArrayBase* to,
610 ElementsKind to_kind,
611 uint32_t to_start,
612 int copy_size) {
613 switch (to_kind) {
614 case FAST_SMI_ONLY_ELEMENTS:
615 case FAST_ELEMENTS: {
616 AssertNoAllocation no_gc;
617 CopyObjectToObjectElements(
618 &no_gc, FixedArray::cast(from), ElementsTraits::Kind, from_start,
619 FixedArray::cast(to), to_kind, to_start, copy_size);
620 return from;
621 }
622 default:
623 UNREACHABLE();
624 }
625 return to->GetHeap()->undefined_value();
626 }
627
628
406 static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj, 629 static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj,
407 uint32_t capacity, 630 uint32_t capacity,
408 uint32_t length) { 631 uint32_t length) {
409 JSObject::SetFastElementsCapacityMode set_capacity_mode = 632 JSObject::SetFastElementsCapacityMode set_capacity_mode =
410 obj->HasFastSmiOnlyElements() 633 obj->HasFastSmiOnlyElements()
411 ? JSObject::kAllowSmiOnlyElements 634 ? JSObject::kAllowSmiOnlyElements
412 : JSObject::kDontAllowSmiOnlyElements; 635 : JSObject::kDontAllowSmiOnlyElements;
413 return obj->SetFastElementsCapacityAndLength(capacity, 636 return obj->SetFastElementsCapacityAndLength(capacity,
414 length, 637 length,
415 set_capacity_mode); 638 set_capacity_mode);
416 } 639 }
417 640
418 protected: 641 protected:
419 friend class FastElementsAccessor<FastObjectElementsAccessor, 642 friend class FastElementsAccessor<FastObjectElementsAccessor,
420 FixedArray, 643 ElementsKindTraits<FAST_ELEMENTS>,
421 kPointerSize>; 644 kPointerSize>;
422 645
423 virtual MaybeObject* Delete(JSObject* obj, 646 virtual MaybeObject* Delete(JSObject* obj,
424 uint32_t key, 647 uint32_t key,
425 JSReceiver::DeleteMode mode) { 648 JSReceiver::DeleteMode mode) {
426 return DeleteCommon(obj, key); 649 return DeleteCommon(obj, key);
427 } 650 }
428 }; 651 };
429 652
430 653
431 class FastDoubleElementsAccessor 654 class FastDoubleElementsAccessor
432 : public FastElementsAccessor<FastDoubleElementsAccessor, 655 : public FastElementsAccessor<FastDoubleElementsAccessor,
433 FixedDoubleArray, 656 ElementsKindTraits<FAST_DOUBLE_ELEMENTS>,
434 kDoubleSize> { 657 kDoubleSize> {
435 public: 658 public:
436 explicit FastDoubleElementsAccessor(const char* name) 659 explicit FastDoubleElementsAccessor(const char* name)
437 : FastElementsAccessor<FastDoubleElementsAccessor, 660 : FastElementsAccessor<FastDoubleElementsAccessor,
438 FixedDoubleArray, 661 ElementsKindTraits<FAST_DOUBLE_ELEMENTS>,
439 kDoubleSize>(name) {} 662 kDoubleSize>(name) {}
440 663
441 static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj, 664 static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj,
442 uint32_t capacity, 665 uint32_t capacity,
443 uint32_t length) { 666 uint32_t length) {
444 return obj->SetFastDoubleElementsCapacityAndLength(capacity, length); 667 return obj->SetFastDoubleElementsCapacityAndLength(capacity, length);
445 } 668 }
446 669
447 protected: 670 protected:
448 friend class ElementsAccessorBase<FastDoubleElementsAccessor, 671 friend class ElementsAccessorBase<FastDoubleElementsAccessor,
449 FixedDoubleArray>; 672 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> >;
450 friend class FastElementsAccessor<FastDoubleElementsAccessor, 673 friend class FastElementsAccessor<FastDoubleElementsAccessor,
451 FixedDoubleArray, 674 ElementsKindTraits<FAST_DOUBLE_ELEMENTS>,
452 kDoubleSize>; 675 kDoubleSize>;
453 676
677 static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
678 uint32_t from_start,
679 FixedArrayBase* to,
680 ElementsKind to_kind,
681 uint32_t to_start,
682 int copy_size) {
683 switch (to_kind) {
684 case FAST_SMI_ONLY_ELEMENTS:
685 case FAST_ELEMENTS:
686 return CopyDoubleToObjectElements(
687 FixedDoubleArray::cast(from), from_start, FixedArray::cast(to),
688 to_kind, to_start, copy_size);
689 case FAST_DOUBLE_ELEMENTS:
690 CopyDoubleToDoubleElements(FixedDoubleArray::cast(from), from_start,
691 FixedDoubleArray::cast(to),
692 to_start, copy_size);
693 return from;
694 default:
695 UNREACHABLE();
696 }
697 return to->GetHeap()->undefined_value();
698 }
699
454 virtual MaybeObject* Delete(JSObject* obj, 700 virtual MaybeObject* Delete(JSObject* obj,
455 uint32_t key, 701 uint32_t key,
456 JSReceiver::DeleteMode mode) { 702 JSReceiver::DeleteMode mode) {
457 int length = obj->IsJSArray() 703 int length = obj->IsJSArray()
458 ? Smi::cast(JSArray::cast(obj)->length())->value() 704 ? Smi::cast(JSArray::cast(obj)->length())->value()
459 : FixedDoubleArray::cast(obj->elements())->length(); 705 : FixedDoubleArray::cast(obj->elements())->length();
460 if (key < static_cast<uint32_t>(length)) { 706 if (key < static_cast<uint32_t>(length)) {
461 FixedDoubleArray::cast(obj->elements())->set_the_hole(key); 707 FixedDoubleArray::cast(obj->elements())->set_the_hole(key);
462 } 708 }
463 return obj->GetHeap()->true_value(); 709 return obj->GetHeap()->true_value();
464 } 710 }
465 711
466 static bool HasElementImpl(Object* receiver, 712 static bool HasElementImpl(Object* receiver,
467 JSObject* holder, 713 JSObject* holder,
468 uint32_t key, 714 uint32_t key,
469 FixedDoubleArray* backing_store) { 715 FixedDoubleArray* backing_store) {
470 return !backing_store->is_the_hole(key); 716 return !backing_store->is_the_hole(key);
471 } 717 }
472 }; 718 };
473 719
474 720
475 // Super class for all external element arrays. 721 // Super class for all external element arrays.
476 template<typename ExternalElementsAccessorSubclass, 722 template<typename ExternalElementsAccessorSubclass,
477 typename ExternalArray> 723 ElementsKind Kind>
478 class ExternalElementsAccessor 724 class ExternalElementsAccessor
479 : public ElementsAccessorBase<ExternalElementsAccessorSubclass, 725 : public ElementsAccessorBase<ExternalElementsAccessorSubclass,
480 ExternalArray> { 726 ElementsKindTraits<Kind> > {
481 public: 727 public:
482 explicit ExternalElementsAccessor(const char* name) 728 explicit ExternalElementsAccessor(const char* name)
483 : ElementsAccessorBase<ExternalElementsAccessorSubclass, 729 : ElementsAccessorBase<ExternalElementsAccessorSubclass,
484 ExternalArray>(name) {} 730 ElementsKindTraits<Kind> >(name) {}
485 731
486 protected: 732 protected:
733 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore;
734
487 friend class ElementsAccessorBase<ExternalElementsAccessorSubclass, 735 friend class ElementsAccessorBase<ExternalElementsAccessorSubclass,
488 ExternalArray>; 736 ElementsKindTraits<Kind> >;
489 737
490 static MaybeObject* GetImpl(Object* receiver, 738 static MaybeObject* GetImpl(Object* receiver,
491 JSObject* obj, 739 JSObject* obj,
492 uint32_t key, 740 uint32_t key,
493 ExternalArray* backing_store) { 741 BackingStore* backing_store) {
494 return 742 return
495 key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store) 743 key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store)
496 ? backing_store->get(key) 744 ? backing_store->get(key)
497 : backing_store->GetHeap()->undefined_value(); 745 : backing_store->GetHeap()->undefined_value();
498 } 746 }
499 747
500 static MaybeObject* SetLengthImpl(JSObject* obj, 748 static MaybeObject* SetLengthImpl(JSObject* obj,
501 Object* length, 749 Object* length,
502 ExternalArray* backing_store) { 750 BackingStore* backing_store) {
503 // External arrays do not support changing their length. 751 // External arrays do not support changing their length.
504 UNREACHABLE(); 752 UNREACHABLE();
505 return obj; 753 return obj;
506 } 754 }
507 755
508 virtual MaybeObject* Delete(JSObject* obj, 756 virtual MaybeObject* Delete(JSObject* obj,
509 uint32_t key, 757 uint32_t key,
510 JSReceiver::DeleteMode mode) { 758 JSReceiver::DeleteMode mode) {
511 // External arrays always ignore deletes. 759 // External arrays always ignore deletes.
512 return obj->GetHeap()->true_value(); 760 return obj->GetHeap()->true_value();
513 } 761 }
514 762
515 static bool HasElementImpl(Object* receiver, 763 static bool HasElementImpl(Object* receiver,
516 JSObject* holder, 764 JSObject* holder,
517 uint32_t key, 765 uint32_t key,
518 ExternalArray* backing_store) { 766 BackingStore* backing_store) {
519 uint32_t capacity = 767 uint32_t capacity =
520 ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store); 768 ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store);
521 return key < capacity; 769 return key < capacity;
522 } 770 }
523 }; 771 };
524 772
525 773
526 class ExternalByteElementsAccessor 774 class ExternalByteElementsAccessor
527 : public ExternalElementsAccessor<ExternalByteElementsAccessor, 775 : public ExternalElementsAccessor<ExternalByteElementsAccessor,
528 ExternalByteArray> { 776 EXTERNAL_BYTE_ELEMENTS> {
529 public: 777 public:
530 explicit ExternalByteElementsAccessor(const char* name) 778 explicit ExternalByteElementsAccessor(const char* name)
531 : ExternalElementsAccessor<ExternalByteElementsAccessor, 779 : ExternalElementsAccessor<ExternalByteElementsAccessor,
532 ExternalByteArray>(name) {} 780 EXTERNAL_BYTE_ELEMENTS>(name) {}
533 }; 781 };
534 782
535 783
536 class ExternalUnsignedByteElementsAccessor 784 class ExternalUnsignedByteElementsAccessor
537 : public ExternalElementsAccessor<ExternalUnsignedByteElementsAccessor, 785 : public ExternalElementsAccessor<ExternalUnsignedByteElementsAccessor,
538 ExternalUnsignedByteArray> { 786 EXTERNAL_UNSIGNED_BYTE_ELEMENTS> {
539 public: 787 public:
540 explicit ExternalUnsignedByteElementsAccessor(const char* name) 788 explicit ExternalUnsignedByteElementsAccessor(const char* name)
541 : ExternalElementsAccessor<ExternalUnsignedByteElementsAccessor, 789 : ExternalElementsAccessor<ExternalUnsignedByteElementsAccessor,
542 ExternalUnsignedByteArray>(name) {} 790 EXTERNAL_UNSIGNED_BYTE_ELEMENTS>(name) {}
543 }; 791 };
544 792
545 793
546 class ExternalShortElementsAccessor 794 class ExternalShortElementsAccessor
547 : public ExternalElementsAccessor<ExternalShortElementsAccessor, 795 : public ExternalElementsAccessor<ExternalShortElementsAccessor,
548 ExternalShortArray> { 796 EXTERNAL_SHORT_ELEMENTS> {
549 public: 797 public:
550 explicit ExternalShortElementsAccessor(const char* name) 798 explicit ExternalShortElementsAccessor(const char* name)
551 : ExternalElementsAccessor<ExternalShortElementsAccessor, 799 : ExternalElementsAccessor<ExternalShortElementsAccessor,
552 ExternalShortArray>(name) {} 800 EXTERNAL_SHORT_ELEMENTS>(name) {}
553 }; 801 };
554 802
555 803
556 class ExternalUnsignedShortElementsAccessor 804 class ExternalUnsignedShortElementsAccessor
557 : public ExternalElementsAccessor<ExternalUnsignedShortElementsAccessor, 805 : public ExternalElementsAccessor<ExternalUnsignedShortElementsAccessor,
558 ExternalUnsignedShortArray> { 806 EXTERNAL_UNSIGNED_SHORT_ELEMENTS> {
559 public: 807 public:
560 explicit ExternalUnsignedShortElementsAccessor(const char* name) 808 explicit ExternalUnsignedShortElementsAccessor(const char* name)
561 : ExternalElementsAccessor<ExternalUnsignedShortElementsAccessor, 809 : ExternalElementsAccessor<ExternalUnsignedShortElementsAccessor,
562 ExternalUnsignedShortArray>(name) {} 810 EXTERNAL_UNSIGNED_SHORT_ELEMENTS>(name) {}
563 }; 811 };
564 812
565 813
566 class ExternalIntElementsAccessor 814 class ExternalIntElementsAccessor
567 : public ExternalElementsAccessor<ExternalIntElementsAccessor, 815 : public ExternalElementsAccessor<ExternalIntElementsAccessor,
568 ExternalIntArray> { 816 EXTERNAL_INT_ELEMENTS> {
569 public: 817 public:
570 explicit ExternalIntElementsAccessor(const char* name) 818 explicit ExternalIntElementsAccessor(const char* name)
571 : ExternalElementsAccessor<ExternalIntElementsAccessor, 819 : ExternalElementsAccessor<ExternalIntElementsAccessor,
572 ExternalIntArray>(name) {} 820 EXTERNAL_INT_ELEMENTS>(name) {}
573 }; 821 };
574 822
575 823
576 class ExternalUnsignedIntElementsAccessor 824 class ExternalUnsignedIntElementsAccessor
577 : public ExternalElementsAccessor<ExternalUnsignedIntElementsAccessor, 825 : public ExternalElementsAccessor<ExternalUnsignedIntElementsAccessor,
578 ExternalUnsignedIntArray> { 826 EXTERNAL_UNSIGNED_INT_ELEMENTS> {
579 public: 827 public:
580 explicit ExternalUnsignedIntElementsAccessor(const char* name) 828 explicit ExternalUnsignedIntElementsAccessor(const char* name)
581 : ExternalElementsAccessor<ExternalUnsignedIntElementsAccessor, 829 : ExternalElementsAccessor<ExternalUnsignedIntElementsAccessor,
582 ExternalUnsignedIntArray>(name) {} 830 EXTERNAL_UNSIGNED_INT_ELEMENTS>(name) {}
583 }; 831 };
584 832
585 833
586 class ExternalFloatElementsAccessor 834 class ExternalFloatElementsAccessor
587 : public ExternalElementsAccessor<ExternalFloatElementsAccessor, 835 : public ExternalElementsAccessor<ExternalFloatElementsAccessor,
588 ExternalFloatArray> { 836 EXTERNAL_FLOAT_ELEMENTS> {
589 public: 837 public:
590 explicit ExternalFloatElementsAccessor(const char* name) 838 explicit ExternalFloatElementsAccessor(const char* name)
591 : ExternalElementsAccessor<ExternalFloatElementsAccessor, 839 : ExternalElementsAccessor<ExternalFloatElementsAccessor,
592 ExternalFloatArray>(name) {} 840 EXTERNAL_FLOAT_ELEMENTS>(name) {}
593 }; 841 };
594 842
595 843
596 class ExternalDoubleElementsAccessor 844 class ExternalDoubleElementsAccessor
597 : public ExternalElementsAccessor<ExternalDoubleElementsAccessor, 845 : public ExternalElementsAccessor<ExternalDoubleElementsAccessor,
598 ExternalDoubleArray> { 846 EXTERNAL_DOUBLE_ELEMENTS> {
599 public: 847 public:
600 explicit ExternalDoubleElementsAccessor(const char* name) 848 explicit ExternalDoubleElementsAccessor(const char* name)
601 : ExternalElementsAccessor<ExternalDoubleElementsAccessor, 849 : ExternalElementsAccessor<ExternalDoubleElementsAccessor,
602 ExternalDoubleArray>(name) {} 850 EXTERNAL_DOUBLE_ELEMENTS>(name) {}
603 }; 851 };
604 852
605 853
606 class PixelElementsAccessor 854 class PixelElementsAccessor
607 : public ExternalElementsAccessor<PixelElementsAccessor, 855 : public ExternalElementsAccessor<PixelElementsAccessor,
608 ExternalPixelArray> { 856 EXTERNAL_PIXEL_ELEMENTS> {
609 public: 857 public:
610 explicit PixelElementsAccessor(const char* name) 858 explicit PixelElementsAccessor(const char* name)
611 : ExternalElementsAccessor<PixelElementsAccessor, 859 : ExternalElementsAccessor<PixelElementsAccessor,
612 ExternalPixelArray>(name) {} 860 EXTERNAL_PIXEL_ELEMENTS>(name) {}
613 }; 861 };
614 862
615 863
616 class DictionaryElementsAccessor 864 class DictionaryElementsAccessor
617 : public ElementsAccessorBase<DictionaryElementsAccessor, 865 : public ElementsAccessorBase<DictionaryElementsAccessor,
618 SeededNumberDictionary> { 866 ElementsKindTraits<DICTIONARY_ELEMENTS> > {
619 public: 867 public:
620 explicit DictionaryElementsAccessor(const char* name) 868 explicit DictionaryElementsAccessor(const char* name)
621 : ElementsAccessorBase<DictionaryElementsAccessor, 869 : ElementsAccessorBase<DictionaryElementsAccessor,
622 SeededNumberDictionary>(name) {} 870 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {}
623 871
624 // Adjusts the length of the dictionary backing store and returns the new 872 // Adjusts the length of the dictionary backing store and returns the new
625 // length according to ES5 section 15.4.5.2 behavior. 873 // length according to ES5 section 15.4.5.2 behavior.
626 static MaybeObject* SetLengthWithoutNormalize(SeededNumberDictionary* dict, 874 static MaybeObject* SetLengthWithoutNormalize(SeededNumberDictionary* dict,
627 JSArray* array, 875 JSArray* array,
628 Object* length_object, 876 Object* length_object,
629 uint32_t length) { 877 uint32_t length) {
630 if (length == 0) { 878 if (length == 0) {
631 // If the length of a slow array is reset to zero, we clear 879 // If the length of a slow array is reset to zero, we clear
632 // the array and flush backing storage. This has the added 880 // the array and flush backing storage. This has the added
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 Handle<Object> args[2] = { name, holder }; 964 Handle<Object> args[2] = { name, holder };
717 Handle<Object> error = 965 Handle<Object> error =
718 isolate->factory()->NewTypeError("strict_delete_property", 966 isolate->factory()->NewTypeError("strict_delete_property",
719 HandleVector(args, 2)); 967 HandleVector(args, 2));
720 return isolate->Throw(*error); 968 return isolate->Throw(*error);
721 } 969 }
722 } 970 }
723 return heap->true_value(); 971 return heap->true_value();
724 } 972 }
725 973
974 static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
975 uint32_t from_start,
976 FixedArrayBase* to,
977 ElementsKind to_kind,
978 uint32_t to_start,
979 int copy_size) {
980 switch (to_kind) {
981 case FAST_SMI_ONLY_ELEMENTS:
982 case FAST_ELEMENTS:
983 CopyDictionaryToObjectElements(
984 SeededNumberDictionary::cast(from), from_start,
985 FixedArray::cast(to), to_kind, to_start, copy_size);
986 return from;
987 default:
988 UNREACHABLE();
989 }
990 return to->GetHeap()->undefined_value();
991 }
992
993
726 protected: 994 protected:
727 friend class ElementsAccessorBase<DictionaryElementsAccessor, 995 friend class ElementsAccessorBase<DictionaryElementsAccessor,
728 SeededNumberDictionary>; 996 ElementsKindTraits<DICTIONARY_ELEMENTS> >;
729 997
730 virtual MaybeObject* Delete(JSObject* obj, 998 virtual MaybeObject* Delete(JSObject* obj,
731 uint32_t key, 999 uint32_t key,
732 JSReceiver::DeleteMode mode) { 1000 JSReceiver::DeleteMode mode) {
733 return DeleteCommon(obj, key, mode); 1001 return DeleteCommon(obj, key, mode);
734 } 1002 }
735 1003
736 static MaybeObject* GetImpl(Object* receiver, 1004 static MaybeObject* GetImpl(Object* receiver,
737 JSObject* obj, 1005 JSObject* obj,
738 uint32_t key, 1006 uint32_t key,
(...skipping 23 matching lines...) Expand all
762 } 1030 }
763 1031
764 static uint32_t GetKeyForIndexImpl(SeededNumberDictionary* dict, 1032 static uint32_t GetKeyForIndexImpl(SeededNumberDictionary* dict,
765 uint32_t index) { 1033 uint32_t index) {
766 Object* key = dict->KeyAt(index); 1034 Object* key = dict->KeyAt(index);
767 return Smi::cast(key)->value(); 1035 return Smi::cast(key)->value();
768 } 1036 }
769 }; 1037 };
770 1038
771 1039
772 class NonStrictArgumentsElementsAccessor 1040 class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase<
773 : public ElementsAccessorBase<NonStrictArgumentsElementsAccessor, 1041 NonStrictArgumentsElementsAccessor,
774 FixedArray> { 1042 ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> > {
775 public: 1043 public:
776 explicit NonStrictArgumentsElementsAccessor(const char* name) 1044 explicit NonStrictArgumentsElementsAccessor(const char* name)
777 : ElementsAccessorBase<NonStrictArgumentsElementsAccessor, 1045 : ElementsAccessorBase<
778 FixedArray>(name) {} 1046 NonStrictArgumentsElementsAccessor,
1047 ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> >(name) {}
779 protected: 1048 protected:
780 friend class ElementsAccessorBase<NonStrictArgumentsElementsAccessor, 1049 friend class ElementsAccessorBase<
781 FixedArray>; 1050 NonStrictArgumentsElementsAccessor,
1051 ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> >;
782 1052
783 static MaybeObject* GetImpl(Object* receiver, 1053 static MaybeObject* GetImpl(Object* receiver,
784 JSObject* obj, 1054 JSObject* obj,
785 uint32_t key, 1055 uint32_t key,
786 FixedArray* parameter_map) { 1056 FixedArray* parameter_map) {
787 Object* probe = GetParameterMapArg(obj, parameter_map, key); 1057 Object* probe = GetParameterMapArg(obj, parameter_map, key);
788 if (!probe->IsTheHole()) { 1058 if (!probe->IsTheHole()) {
789 Context* context = Context::cast(parameter_map->get(0)); 1059 Context* context = Context::cast(parameter_map->get(0));
790 int context_index = Smi::cast(probe)->value(); 1060 int context_index = Smi::cast(probe)->value();
791 ASSERT(!context->get(context_index)->IsTheHole()); 1061 ASSERT(!context->get(context_index)->IsTheHole());
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
833 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1103 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
834 if (arguments->IsDictionary()) { 1104 if (arguments->IsDictionary()) {
835 return DictionaryElementsAccessor::DeleteCommon(obj, key, mode); 1105 return DictionaryElementsAccessor::DeleteCommon(obj, key, mode);
836 } else { 1106 } else {
837 return FastObjectElementsAccessor::DeleteCommon(obj, key); 1107 return FastObjectElementsAccessor::DeleteCommon(obj, key);
838 } 1108 }
839 } 1109 }
840 return obj->GetHeap()->true_value(); 1110 return obj->GetHeap()->true_value();
841 } 1111 }
842 1112
1113 static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
1114 uint32_t from_start,
1115 FixedArrayBase* to,
1116 ElementsKind to_kind,
1117 uint32_t to_start,
1118 int copy_size) {
1119 FixedArray* parameter_map = FixedArray::cast(from);
1120 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1121 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments);
1122 return accessor->CopyElements(NULL, from_start, to, to_kind,
1123 to_start, copy_size, arguments);
1124 }
1125
843 static uint32_t GetCapacityImpl(FixedArray* parameter_map) { 1126 static uint32_t GetCapacityImpl(FixedArray* parameter_map) {
844 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 1127 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
845 return Max(static_cast<uint32_t>(parameter_map->length() - 2), 1128 return Max(static_cast<uint32_t>(parameter_map->length() - 2),
846 ForArray(arguments)->GetCapacity(arguments)); 1129 ForArray(arguments)->GetCapacity(arguments));
847 } 1130 }
848 1131
849 static uint32_t GetKeyForIndexImpl(FixedArray* dict, 1132 static uint32_t GetKeyForIndexImpl(FixedArray* dict,
850 uint32_t index) { 1133 uint32_t index) {
851 return index; 1134 return index;
852 } 1135 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 case EXTERNAL_PIXEL_ARRAY_TYPE: 1189 case EXTERNAL_PIXEL_ARRAY_TYPE:
907 return elements_accessors_[EXTERNAL_PIXEL_ELEMENTS]; 1190 return elements_accessors_[EXTERNAL_PIXEL_ELEMENTS];
908 default: 1191 default:
909 UNREACHABLE(); 1192 UNREACHABLE();
910 return NULL; 1193 return NULL;
911 } 1194 }
912 } 1195 }
913 1196
914 1197
915 void ElementsAccessor::InitializeOncePerProcess() { 1198 void ElementsAccessor::InitializeOncePerProcess() {
916 // First argument in list is the accessor class, the second argument is can
917 // be any arbitrary unique identifier, in this case chosen to be the
918 // corresponding enum. Use the fast element handler for smi-only arrays.
919 // The implementation is currently identical. Note that the order must match
920 // that of the ElementsKind enum for the |accessor_array[]| below to work.
921 #define ELEMENTS_LIST(V) \
922 V(FastObjectElementsAccessor, FAST_SMI_ONLY_ELEMENTS) \
923 V(FastObjectElementsAccessor, FAST_ELEMENTS) \
924 V(FastDoubleElementsAccessor, FAST_DOUBLE_ELEMENTS) \
925 V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS) \
926 V(NonStrictArgumentsElementsAccessor, NON_STRICT_ARGUMENTS_ELEMENTS) \
927 V(ExternalByteElementsAccessor, EXTERNAL_BYTE_ELEMENTS) \
928 V(ExternalUnsignedByteElementsAccessor, EXTERNAL_UNSIGNED_BYTE_ELEMENTS) \
929 V(ExternalShortElementsAccessor, EXTERNAL_SHORT_ELEMENTS) \
930 V(ExternalUnsignedShortElementsAccessor, EXTERNAL_UNSIGNED_SHORT_ELEMENTS) \
931 V(ExternalIntElementsAccessor, EXTERNAL_INT_ELEMENTS) \
932 V(ExternalUnsignedIntElementsAccessor, EXTERNAL_UNSIGNED_INT_ELEMENTS) \
933 V(ExternalFloatElementsAccessor, EXTERNAL_FLOAT_ELEMENTS) \
934 V(ExternalDoubleElementsAccessor, EXTERNAL_DOUBLE_ELEMENTS) \
935 V(PixelElementsAccessor, EXTERNAL_PIXEL_ELEMENTS)
936
937 static struct ConcreteElementsAccessors { 1199 static struct ConcreteElementsAccessors {
938 #define ACCESSOR_STRUCT(Class, Name) Class* Name##_handler; 1200 #define ACCESSOR_STRUCT(Class, Kind, Store) Class* Kind##_handler;
939 ELEMENTS_LIST(ACCESSOR_STRUCT) 1201 ELEMENTS_LIST(ACCESSOR_STRUCT)
940 #undef ACCESSOR_STRUCT 1202 #undef ACCESSOR_STRUCT
941 } element_accessors = { 1203 } element_accessors = {
942 #define ACCESSOR_INIT(Class, Name) new Class(#Name), 1204 #define ACCESSOR_INIT(Class, Kind, Store) new Class(#Kind),
943 ELEMENTS_LIST(ACCESSOR_INIT) 1205 ELEMENTS_LIST(ACCESSOR_INIT)
944 #undef ACCESSOR_INIT 1206 #undef ACCESSOR_INIT
945 }; 1207 };
946 1208
947 static ElementsAccessor* accessor_array[] = { 1209 static ElementsAccessor* accessor_array[] = {
948 #define ACCESSOR_ARRAY(Class, Name) element_accessors.Name##_handler, 1210 #define ACCESSOR_ARRAY(Class, Kind, Store) element_accessors.Kind##_handler,
949 ELEMENTS_LIST(ACCESSOR_ARRAY) 1211 ELEMENTS_LIST(ACCESSOR_ARRAY)
950 #undef ACCESSOR_ARRAY 1212 #undef ACCESSOR_ARRAY
951 }; 1213 };
952 1214
953 #undef ELEMENTS_LIST
954
955 STATIC_ASSERT((sizeof(accessor_array) / sizeof(*accessor_array)) == 1215 STATIC_ASSERT((sizeof(accessor_array) / sizeof(*accessor_array)) ==
956 kElementsKindCount); 1216 kElementsKindCount);
957 1217
958 elements_accessors_ = accessor_array; 1218 elements_accessors_ = accessor_array;
959 } 1219 }
960 1220
961 1221
962 template <typename ElementsAccessorSubclass, typename BackingStoreClass> 1222 template <typename ElementsAccessorSubclass, typename ElementsKindTraits>
963 MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass, BackingStoreClass>:: 1223 MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass,
1224 ElementsKindTraits>::
964 SetLengthImpl(JSObject* obj, 1225 SetLengthImpl(JSObject* obj,
965 Object* length, 1226 Object* length,
966 BackingStoreClass* backing_store) { 1227 typename ElementsKindTraits::BackingStore* backing_store) {
967 JSArray* array = JSArray::cast(obj); 1228 JSArray* array = JSArray::cast(obj);
968 1229
969 // Fast case: The new length fits into a Smi. 1230 // Fast case: The new length fits into a Smi.
970 MaybeObject* maybe_smi_length = length->ToSmi(); 1231 MaybeObject* maybe_smi_length = length->ToSmi();
971 Object* smi_length = Smi::FromInt(0); 1232 Object* smi_length = Smi::FromInt(0);
972 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { 1233 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) {
973 const int value = Smi::cast(smi_length)->value(); 1234 const int value = Smi::cast(smi_length)->value();
974 if (value >= 0) { 1235 if (value >= 0) {
975 Object* new_length; 1236 Object* new_length;
976 MaybeObject* result = ElementsAccessorSubclass:: 1237 MaybeObject* result = ElementsAccessorSubclass::
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 if (!maybe_obj->To(&new_backing_store)) return maybe_obj; 1274 if (!maybe_obj->To(&new_backing_store)) return maybe_obj;
1014 new_backing_store->set(0, length); 1275 new_backing_store->set(0, length);
1015 { MaybeObject* result = array->SetContent(new_backing_store); 1276 { MaybeObject* result = array->SetContent(new_backing_store);
1016 if (result->IsFailure()) return result; 1277 if (result->IsFailure()) return result;
1017 } 1278 }
1018 return array; 1279 return array;
1019 } 1280 }
1020 1281
1021 1282
1022 } } // namespace v8::internal 1283 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/elements.h ('k') | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698