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

Side by Side Diff: src/elements.cc

Issue 9416057: Merge r10739 into 3.6 branch. (Closed) Base URL: https://v8.googlecode.com/svn/branches/3.6
Patch Set: Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/objects.h » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 // CRTP to guarantee aggressive compile time optimizations (i.e. inlining and 70 // CRTP to guarantee aggressive compile time optimizations (i.e. inlining and
71 // specialization of SomeElementsAccessor methods). 71 // specialization of SomeElementsAccessor methods).
72 template <typename ElementsAccessorSubclass, typename BackingStoreClass> 72 template <typename ElementsAccessorSubclass, typename BackingStoreClass>
73 class ElementsAccessorBase : public ElementsAccessor { 73 class ElementsAccessorBase : public ElementsAccessor {
74 protected: 74 protected:
75 ElementsAccessorBase() { } 75 ElementsAccessorBase() { }
76 virtual MaybeObject* Get(FixedArrayBase* backing_store, 76 virtual MaybeObject* Get(FixedArrayBase* backing_store,
77 uint32_t key, 77 uint32_t key,
78 JSObject* obj, 78 JSObject* obj,
79 Object* receiver) { 79 Object* receiver) {
80 return ElementsAccessorSubclass::Get( 80 return ElementsAccessorSubclass::GetImpl(
81 BackingStoreClass::cast(backing_store), key, obj, receiver); 81 BackingStoreClass::cast(backing_store), key, obj, receiver);
82 } 82 }
83 83
84 static MaybeObject* Get(BackingStoreClass* backing_store, 84 static MaybeObject* GetImpl(BackingStoreClass* backing_store,
85 uint32_t key, 85 uint32_t key,
86 JSObject* obj, 86 JSObject* obj,
87 Object* receiver) { 87 Object* receiver) {
88 if (key < ElementsAccessorSubclass::GetCapacity(backing_store)) { 88 return (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store))
89 return backing_store->get(key); 89 ? backing_store->get(key)
90 } 90 : backing_store->GetHeap()->the_hole_value();
91 return backing_store->GetHeap()->the_hole_value();
92 } 91 }
93 92
94 virtual MaybeObject* Delete(JSObject* obj, 93 virtual MaybeObject* Delete(JSObject* obj,
95 uint32_t key, 94 uint32_t key,
96 JSReceiver::DeleteMode mode) = 0; 95 JSReceiver::DeleteMode mode) = 0;
97 96
98 virtual MaybeObject* AddElementsToFixedArray(FixedArrayBase* from, 97 virtual MaybeObject* AddElementsToFixedArray(FixedArrayBase* from,
99 FixedArray* to, 98 FixedArray* to,
100 JSObject* holder, 99 JSObject* holder,
101 Object* receiver) { 100 Object* receiver) {
102 int len0 = to->length(); 101 int len0 = to->length();
103 #ifdef DEBUG 102 #ifdef DEBUG
104 if (FLAG_enable_slow_asserts) { 103 if (FLAG_enable_slow_asserts) {
105 for (int i = 0; i < len0; i++) { 104 for (int i = 0; i < len0; i++) {
106 ASSERT(!to->get(i)->IsTheHole()); 105 ASSERT(!to->get(i)->IsTheHole());
107 } 106 }
108 } 107 }
109 #endif 108 #endif
110 BackingStoreClass* backing_store = BackingStoreClass::cast(from); 109 BackingStoreClass* backing_store = BackingStoreClass::cast(from);
111 uint32_t len1 = ElementsAccessorSubclass::GetCapacity(backing_store); 110 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(backing_store);
112 111
113 // Optimize if 'other' is empty. 112 // Optimize if 'other' is empty.
114 // We cannot optimize if 'this' is empty, as other may have holes. 113 // We cannot optimize if 'this' is empty, as other may have holes.
115 if (len1 == 0) return to; 114 if (len1 == 0) return to;
116 115
117 // Compute how many elements are not in other. 116 // Compute how many elements are not in other.
118 int extra = 0; 117 int extra = 0;
119 for (uint32_t y = 0; y < len1; y++) { 118 for (uint32_t y = 0; y < len1; y++) {
120 if (ElementsAccessorSubclass::HasElementAtIndex(backing_store, 119 if (ElementsAccessorSubclass::HasElementAtIndexImpl(
121 y, 120 backing_store, y, holder, receiver)) {
122 holder,
123 receiver)) {
124 uint32_t key = 121 uint32_t key =
125 ElementsAccessorSubclass::GetKeyForIndex(backing_store, y); 122 ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y);
126 MaybeObject* maybe_value = 123 MaybeObject* maybe_value =
127 ElementsAccessorSubclass::Get(backing_store, key, holder, receiver); 124 ElementsAccessorSubclass::GetImpl(backing_store, key,
125 holder, receiver);
128 Object* value; 126 Object* value;
129 if (!maybe_value->ToObject(&value)) return maybe_value; 127 if (!maybe_value->ToObject(&value)) return maybe_value;
130 ASSERT(!value->IsTheHole()); 128 ASSERT(!value->IsTheHole());
131 if (!HasKey(to, value)) { 129 if (!HasKey(to, value)) {
132 extra++; 130 extra++;
133 } 131 }
134 } 132 }
135 } 133 }
136 134
137 if (extra == 0) return to; 135 if (extra == 0) return to;
(...skipping 10 matching lines...) Expand all
148 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); 146 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
149 for (int i = 0; i < len0; i++) { 147 for (int i = 0; i < len0; i++) {
150 Object* e = to->get(i); 148 Object* e = to->get(i);
151 ASSERT(e->IsString() || e->IsNumber()); 149 ASSERT(e->IsString() || e->IsNumber());
152 result->set(i, e, mode); 150 result->set(i, e, mode);
153 } 151 }
154 } 152 }
155 // Fill in the extra values. 153 // Fill in the extra values.
156 int index = 0; 154 int index = 0;
157 for (uint32_t y = 0; y < len1; y++) { 155 for (uint32_t y = 0; y < len1; y++) {
158 if (ElementsAccessorSubclass::HasElementAtIndex(backing_store, 156 if (ElementsAccessorSubclass::HasElementAtIndexImpl(
159 y, 157 backing_store, y, holder, receiver)) {
160 holder,
161 receiver)) {
162 uint32_t key = 158 uint32_t key =
163 ElementsAccessorSubclass::GetKeyForIndex(backing_store, y); 159 ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y);
164 MaybeObject* maybe_value = 160 MaybeObject* maybe_value =
165 ElementsAccessorSubclass::Get(backing_store, key, holder, receiver); 161 ElementsAccessorSubclass::GetImpl(backing_store, key,
162 holder, receiver);
166 Object* value; 163 Object* value;
167 if (!maybe_value->ToObject(&value)) return maybe_value; 164 if (!maybe_value->ToObject(&value)) return maybe_value;
168 if (!value->IsTheHole() && !HasKey(to, value)) { 165 if (!value->IsTheHole() && !HasKey(to, value)) {
169 result->set(len0 + index, value); 166 result->set(len0 + index, value);
170 index++; 167 index++;
171 } 168 }
172 } 169 }
173 } 170 }
174 ASSERT(extra == index); 171 ASSERT(extra == index);
175 return result; 172 return result;
176 } 173 }
177 174
178 protected: 175 protected:
179 static uint32_t GetCapacity(BackingStoreClass* backing_store) { 176 static uint32_t GetCapacityImpl(BackingStoreClass* backing_store) {
180 return backing_store->length(); 177 return backing_store->length();
181 } 178 }
182 179
183 virtual uint32_t GetCapacity(FixedArrayBase* backing_store) { 180 virtual uint32_t GetCapacity(FixedArrayBase* backing_store) {
184 return ElementsAccessorSubclass::GetCapacity( 181 return ElementsAccessorSubclass::GetCapacityImpl(
185 BackingStoreClass::cast(backing_store)); 182 BackingStoreClass::cast(backing_store));
186 } 183 }
187 184
188 static bool HasElementAtIndex(BackingStoreClass* backing_store, 185 static bool HasElementAtIndexImpl(BackingStoreClass* backing_store,
189 uint32_t index, 186 uint32_t index,
190 JSObject* holder, 187 JSObject* holder,
191 Object* receiver) { 188 Object* receiver) {
192 uint32_t key = 189 uint32_t key =
193 ElementsAccessorSubclass::GetKeyForIndex(backing_store, index); 190 ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index);
194 MaybeObject* element = ElementsAccessorSubclass::Get(backing_store, 191 MaybeObject* element =
195 key, 192 ElementsAccessorSubclass::GetImpl(backing_store, key, holder, receiver);
196 holder,
197 receiver);
198 return !element->IsTheHole(); 193 return !element->IsTheHole();
199 } 194 }
200 195
201 virtual bool HasElementAtIndex(FixedArrayBase* backing_store, 196 virtual bool HasElementAtIndex(FixedArrayBase* backing_store,
202 uint32_t index, 197 uint32_t index,
203 JSObject* holder, 198 JSObject* holder,
204 Object* receiver) { 199 Object* receiver) {
205 return ElementsAccessorSubclass::HasElementAtIndex( 200 return ElementsAccessorSubclass::HasElementAtIndexImpl(
206 BackingStoreClass::cast(backing_store), index, holder, receiver); 201 BackingStoreClass::cast(backing_store), index, holder, receiver);
207 } 202 }
208 203
209 static uint32_t GetKeyForIndex(BackingStoreClass* backing_store, 204 static uint32_t GetKeyForIndexImpl(BackingStoreClass* backing_store,
210 uint32_t index) { 205 uint32_t index) {
211 return index; 206 return index;
212 } 207 }
213 208
214 virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store, 209 virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store,
215 uint32_t index) { 210 uint32_t index) {
216 return ElementsAccessorSubclass::GetKeyForIndex( 211 return ElementsAccessorSubclass::GetKeyForIndexImpl(
217 BackingStoreClass::cast(backing_store), index); 212 BackingStoreClass::cast(backing_store), index);
218 } 213 }
219 214
220 private: 215 private:
221 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); 216 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase);
222 }; 217 };
223 218
224 219
225 class FastElementsAccessor 220 class FastElementsAccessor
226 : public ElementsAccessorBase<FastElementsAccessor, FixedArray> { 221 : public ElementsAccessorBase<FastElementsAccessor, FixedArray> {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 JSReceiver::DeleteMode mode) { 285 JSReceiver::DeleteMode mode) {
291 int length = obj->IsJSArray() 286 int length = obj->IsJSArray()
292 ? Smi::cast(JSArray::cast(obj)->length())->value() 287 ? Smi::cast(JSArray::cast(obj)->length())->value()
293 : FixedDoubleArray::cast(obj->elements())->length(); 288 : FixedDoubleArray::cast(obj->elements())->length();
294 if (key < static_cast<uint32_t>(length)) { 289 if (key < static_cast<uint32_t>(length)) {
295 FixedDoubleArray::cast(obj->elements())->set_the_hole(key); 290 FixedDoubleArray::cast(obj->elements())->set_the_hole(key);
296 } 291 }
297 return obj->GetHeap()->true_value(); 292 return obj->GetHeap()->true_value();
298 } 293 }
299 294
300 static bool HasElementAtIndex(FixedDoubleArray* backing_store, 295 static bool HasElementAtIndexImpl(FixedDoubleArray* backing_store,
301 uint32_t index, 296 uint32_t index,
302 JSObject* holder, 297 JSObject* holder,
303 Object* receiver) { 298 Object* receiver) {
304 return !backing_store->is_the_hole(index); 299 return !backing_store->is_the_hole(index);
305 } 300 }
306 }; 301 };
307 302
308 303
309 // Super class for all external element arrays. 304 // Super class for all external element arrays.
310 template<typename ExternalElementsAccessorSubclass, 305 template<typename ExternalElementsAccessorSubclass,
311 typename ExternalArray> 306 typename ExternalArray>
312 class ExternalElementsAccessor 307 class ExternalElementsAccessor
313 : public ElementsAccessorBase<ExternalElementsAccessorSubclass, 308 : public ElementsAccessorBase<ExternalElementsAccessorSubclass,
314 ExternalArray> { 309 ExternalArray> {
315 protected: 310 protected:
316 friend class ElementsAccessorBase<ExternalElementsAccessorSubclass, 311 friend class ElementsAccessorBase<ExternalElementsAccessorSubclass,
317 ExternalArray>; 312 ExternalArray>;
318 313
319 static MaybeObject* Get(ExternalArray* backing_store, 314 static MaybeObject* GetImpl(ExternalArray* backing_store,
320 uint32_t key, 315 uint32_t key,
321 JSObject* obj, 316 JSObject* obj,
322 Object* receiver) { 317 Object* receiver) {
323 if (key < ExternalElementsAccessorSubclass::GetCapacity(backing_store)) { 318 return
324 return backing_store->get(key); 319 key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store)
325 } else { 320 ? backing_store->get(key)
326 return backing_store->GetHeap()->undefined_value(); 321 : backing_store->GetHeap()->undefined_value();
327 }
328 } 322 }
329 323
330 virtual MaybeObject* Delete(JSObject* obj, 324 virtual MaybeObject* Delete(JSObject* obj,
331 uint32_t key, 325 uint32_t key,
332 JSReceiver::DeleteMode mode) { 326 JSReceiver::DeleteMode mode) {
333 // External arrays always ignore deletes. 327 // External arrays always ignore deletes.
334 return obj->GetHeap()->true_value(); 328 return obj->GetHeap()->true_value();
335 } 329 }
336 }; 330 };
337 331
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 protected: 436 protected:
443 friend class ElementsAccessorBase<DictionaryElementsAccessor, 437 friend class ElementsAccessorBase<DictionaryElementsAccessor,
444 SeededNumberDictionary>; 438 SeededNumberDictionary>;
445 439
446 virtual MaybeObject* Delete(JSObject* obj, 440 virtual MaybeObject* Delete(JSObject* obj,
447 uint32_t key, 441 uint32_t key,
448 JSReceiver::DeleteMode mode) { 442 JSReceiver::DeleteMode mode) {
449 return DeleteCommon(obj, key, mode); 443 return DeleteCommon(obj, key, mode);
450 } 444 }
451 445
452 static MaybeObject* Get(SeededNumberDictionary* backing_store, 446 static MaybeObject* GetImpl(SeededNumberDictionary* backing_store,
453 uint32_t key, 447 uint32_t key,
454 JSObject* obj, 448 JSObject* obj,
455 Object* receiver) { 449 Object* receiver) {
456 int entry = backing_store->FindEntry(key); 450 int entry = backing_store->FindEntry(key);
457 if (entry != SeededNumberDictionary::kNotFound) { 451 if (entry != SeededNumberDictionary::kNotFound) {
458 Object* element = backing_store->ValueAt(entry); 452 Object* element = backing_store->ValueAt(entry);
459 PropertyDetails details = backing_store->DetailsAt(entry); 453 PropertyDetails details = backing_store->DetailsAt(entry);
460 if (details.type() == CALLBACKS) { 454 if (details.type() == CALLBACKS) {
461 return obj->GetElementWithCallback(receiver, 455 return obj->GetElementWithCallback(receiver,
462 element, 456 element,
463 key, 457 key,
464 obj); 458 obj);
465 } else { 459 } else {
466 return element; 460 return element;
467 } 461 }
468 } 462 }
469 return obj->GetHeap()->the_hole_value(); 463 return obj->GetHeap()->the_hole_value();
470 } 464 }
471 465
472 static uint32_t GetKeyForIndex(SeededNumberDictionary* dict, 466 static uint32_t GetKeyForIndexImpl(SeededNumberDictionary* dict,
473 uint32_t index) { 467 uint32_t index) {
474 Object* key = dict->KeyAt(index); 468 Object* key = dict->KeyAt(index);
475 return Smi::cast(key)->value(); 469 return Smi::cast(key)->value();
476 } 470 }
477 }; 471 };
478 472
479 473
480 class NonStrictArgumentsElementsAccessor 474 class NonStrictArgumentsElementsAccessor
481 : public ElementsAccessorBase<NonStrictArgumentsElementsAccessor, 475 : public ElementsAccessorBase<NonStrictArgumentsElementsAccessor,
482 FixedArray> { 476 FixedArray> {
483 protected: 477 protected:
484 friend class ElementsAccessorBase<NonStrictArgumentsElementsAccessor, 478 friend class ElementsAccessorBase<NonStrictArgumentsElementsAccessor,
485 FixedArray>; 479 FixedArray>;
486 480
487 static MaybeObject* Get(FixedArray* parameter_map, 481 static MaybeObject* GetImpl(FixedArray* parameter_map,
488 uint32_t key, 482 uint32_t key,
489 JSObject* obj, 483 JSObject* obj,
490 Object* receiver) { 484 Object* receiver) {
491 Object* probe = GetParameterMapArg(parameter_map, key); 485 Object* probe = GetParameterMapArg(parameter_map, key);
492 if (!probe->IsTheHole()) { 486 if (!probe->IsTheHole()) {
493 Context* context = Context::cast(parameter_map->get(0)); 487 Context* context = Context::cast(parameter_map->get(0));
494 int context_index = Smi::cast(probe)->value(); 488 int context_index = Smi::cast(probe)->value();
495 ASSERT(!context->get(context_index)->IsTheHole()); 489 ASSERT(!context->get(context_index)->IsTheHole());
496 return context->get(context_index); 490 return context->get(context_index);
497 } else { 491 } else {
498 // Object is not mapped, defer to the arguments. 492 // Object is not mapped, defer to the arguments.
499 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 493 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
500 return ElementsAccessor::ForArray(arguments)->Get(arguments, 494 return ElementsAccessor::ForArray(arguments)->Get(arguments,
(...skipping 18 matching lines...) Expand all
519 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 513 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
520 if (arguments->IsDictionary()) { 514 if (arguments->IsDictionary()) {
521 return DictionaryElementsAccessor::DeleteCommon(obj, key, mode); 515 return DictionaryElementsAccessor::DeleteCommon(obj, key, mode);
522 } else { 516 } else {
523 return FastElementsAccessor::DeleteCommon(obj, key); 517 return FastElementsAccessor::DeleteCommon(obj, key);
524 } 518 }
525 } 519 }
526 return obj->GetHeap()->true_value(); 520 return obj->GetHeap()->true_value();
527 } 521 }
528 522
529 static uint32_t GetCapacity(FixedArray* parameter_map) { 523 static uint32_t GetCapacityImpl(FixedArray* parameter_map) {
530 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 524 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
531 return Max(static_cast<uint32_t>(parameter_map->length() - 2), 525 return Max(static_cast<uint32_t>(parameter_map->length() - 2),
532 ForArray(arguments)->GetCapacity(arguments)); 526 ForArray(arguments)->GetCapacity(arguments));
533 } 527 }
534 528
535 static uint32_t GetKeyForIndex(FixedArray* dict, 529 static uint32_t GetKeyForIndexImpl(FixedArray* dict,
536 uint32_t index) { 530 uint32_t index) {
537 return index; 531 return index;
538 } 532 }
539 533
540 static bool HasElementAtIndex(FixedArray* parameter_map, 534 static bool HasElementAtIndexImpl(FixedArray* parameter_map,
541 uint32_t index, 535 uint32_t index,
542 JSObject* holder, 536 JSObject* holder,
543 Object* receiver) { 537 Object* receiver) {
544 Object* probe = GetParameterMapArg(parameter_map, index); 538 Object* probe = GetParameterMapArg(parameter_map, index);
545 if (!probe->IsTheHole()) { 539 if (!probe->IsTheHole()) {
546 return true; 540 return true;
547 } else { 541 } else {
548 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 542 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
549 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); 543 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments);
550 return !accessor->Get(arguments, index, holder, receiver)->IsTheHole(); 544 return !accessor->Get(arguments, index, holder, receiver)->IsTheHole();
551 } 545 }
552 } 546 }
553 547
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 &element_accessors.float_elements_handler, 620 &element_accessors.float_elements_handler,
627 &element_accessors.double_elements_handler, 621 &element_accessors.double_elements_handler,
628 &element_accessors.pixel_elements_handler 622 &element_accessors.pixel_elements_handler
629 }; 623 };
630 624
631 elements_accessors_ = accessor_array; 625 elements_accessors_ = accessor_array;
632 } 626 }
633 627
634 628
635 } } // namespace v8::internal 629 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698