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

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

Powered by Google App Engine
This is Rietveld 408576698