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

Side by Side Diff: src/elements.cc

Issue 9572014: Recfactor core HasElement functionality into 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.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 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
11 // with the distribution. 11 // with the distribution.
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 } 166 }
167 #endif 167 #endif
168 BackingStoreClass* backing_store = BackingStoreClass::cast(from); 168 BackingStoreClass* backing_store = BackingStoreClass::cast(from);
169 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(backing_store); 169 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(backing_store);
170 170
171 // Optimize if 'other' is empty. 171 // Optimize if 'other' is empty.
172 // We cannot optimize if 'this' is empty, as other may have holes. 172 // We cannot optimize if 'this' is empty, as other may have holes.
173 if (len1 == 0) return to; 173 if (len1 == 0) return to;
174 174
175 // Compute how many elements are not in other. 175 // Compute how many elements are not in other.
176 int extra = 0; 176 uint32_t extra = 0;
177 for (uint32_t y = 0; y < len1; y++) { 177 for (uint32_t y = 0; y < len1; y++) {
178 if (ElementsAccessorSubclass::HasElementAtIndexImpl( 178 uint32_t key =
179 backing_store, y, holder, receiver)) { 179 ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y);
180 uint32_t key = 180 if (ElementsAccessorSubclass::HasElementImpl(
181 ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y); 181 backing_store, key, holder, receiver)) {
182 MaybeObject* maybe_value = 182 MaybeObject* maybe_value =
183 ElementsAccessorSubclass::GetImpl(backing_store, key, 183 ElementsAccessorSubclass::GetImpl(backing_store, key,
184 holder, receiver); 184 holder, receiver);
185 Object* value; 185 Object* value;
186 if (!maybe_value->ToObject(&value)) return maybe_value; 186 if (!maybe_value->ToObject(&value)) return maybe_value;
187 ASSERT(!value->IsTheHole()); 187 ASSERT(!value->IsTheHole());
188 if (!HasKey(to, value)) { 188 if (!HasKey(to, value)) {
189 extra++; 189 extra++;
190 } 190 }
191 } 191 }
(...skipping 11 matching lines...) Expand all
203 { 203 {
204 AssertNoAllocation no_gc; 204 AssertNoAllocation no_gc;
205 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); 205 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
206 for (int i = 0; i < len0; i++) { 206 for (int i = 0; i < len0; i++) {
207 Object* e = to->get(i); 207 Object* e = to->get(i);
208 ASSERT(e->IsString() || e->IsNumber()); 208 ASSERT(e->IsString() || e->IsNumber());
209 result->set(i, e, mode); 209 result->set(i, e, mode);
210 } 210 }
211 } 211 }
212 // Fill in the extra values. 212 // Fill in the extra values.
213 int index = 0; 213 uint32_t index = 0;
214 for (uint32_t y = 0; y < len1; y++) { 214 for (uint32_t y = 0; y < len1; y++) {
215 if (ElementsAccessorSubclass::HasElementAtIndexImpl( 215 uint32_t key =
216 backing_store, y, holder, receiver)) { 216 ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y);
217 uint32_t key = 217 if (ElementsAccessorSubclass::HasElementImpl(
218 ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y); 218 backing_store, key, holder, receiver)) {
219 MaybeObject* maybe_value = 219 MaybeObject* maybe_value =
220 ElementsAccessorSubclass::GetImpl(backing_store, key, 220 ElementsAccessorSubclass::GetImpl(backing_store, key,
221 holder, receiver); 221 holder, receiver);
222 Object* value; 222 Object* value;
223 if (!maybe_value->ToObject(&value)) return maybe_value; 223 if (!maybe_value->ToObject(&value)) return maybe_value;
224 if (!value->IsTheHole() && !HasKey(to, value)) { 224 if (!value->IsTheHole() && !HasKey(to, value)) {
225 result->set(len0 + index, value); 225 result->set(len0 + index, value);
226 index++; 226 index++;
227 } 227 }
228 } 228 }
229 } 229 }
230 ASSERT(extra == index); 230 ASSERT(extra == index);
231 return result; 231 return result;
232 } 232 }
233 233
234 protected: 234 protected:
235 static uint32_t GetCapacityImpl(BackingStoreClass* backing_store) { 235 static uint32_t GetCapacityImpl(BackingStoreClass* backing_store) {
236 return backing_store->length(); 236 return backing_store->length();
237 } 237 }
238 238
239 virtual uint32_t GetCapacity(FixedArrayBase* backing_store) { 239 virtual uint32_t GetCapacity(FixedArrayBase* backing_store) {
240 return ElementsAccessorSubclass::GetCapacityImpl( 240 return ElementsAccessorSubclass::GetCapacityImpl(
241 BackingStoreClass::cast(backing_store)); 241 BackingStoreClass::cast(backing_store));
242 } 242 }
243 243
244 static bool HasElementAtIndexImpl(BackingStoreClass* backing_store, 244 static bool HasElementImpl(BackingStoreClass* backing_store,
245 uint32_t index, 245 uint32_t key,
246 JSObject* holder, 246 JSObject* holder,
247 Object* receiver) { 247 Object* receiver) {
248 uint32_t key =
249 ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index);
250 MaybeObject* element = 248 MaybeObject* element =
251 ElementsAccessorSubclass::GetImpl(backing_store, key, holder, receiver); 249 ElementsAccessorSubclass::GetImpl(backing_store, key, holder, receiver);
252 return !element->IsTheHole(); 250 return !element->IsTheHole();
253 } 251 }
254 252
255 virtual bool HasElementAtIndex(FixedArrayBase* backing_store, 253 virtual bool HasElement(FixedArrayBase* backing_store,
256 uint32_t index, 254 uint32_t key,
257 JSObject* holder, 255 JSObject* holder,
258 Object* receiver) { 256 Object* receiver) {
259 return ElementsAccessorSubclass::HasElementAtIndexImpl( 257 return ElementsAccessorSubclass::HasElementImpl(
260 BackingStoreClass::cast(backing_store), index, holder, receiver); 258 BackingStoreClass::cast(backing_store), key, holder, receiver);
261 } 259 }
262 260
263 static uint32_t GetKeyForIndexImpl(BackingStoreClass* backing_store, 261 static uint32_t GetKeyForIndexImpl(BackingStoreClass* backing_store,
264 uint32_t index) { 262 uint32_t index) {
265 return index; 263 return index;
266 } 264 }
267 265
268 virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store, 266 virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store,
269 uint32_t index) { 267 uint32_t index) {
270 return ElementsAccessorSubclass::GetKeyForIndexImpl( 268 return ElementsAccessorSubclass::GetKeyForIndexImpl(
271 BackingStoreClass::cast(backing_store), index); 269 BackingStoreClass::cast(backing_store), index);
272 } 270 }
273 271
274 private: 272 private:
275 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); 273 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase);
276 }; 274 };
277 275
278 276
279 // Super class for all fast element arrays. 277 // Super class for all fast element arrays.
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 JSReceiver::DeleteMode mode) { 432 JSReceiver::DeleteMode mode) {
435 int length = obj->IsJSArray() 433 int length = obj->IsJSArray()
436 ? Smi::cast(JSArray::cast(obj)->length())->value() 434 ? Smi::cast(JSArray::cast(obj)->length())->value()
437 : FixedDoubleArray::cast(obj->elements())->length(); 435 : FixedDoubleArray::cast(obj->elements())->length();
438 if (key < static_cast<uint32_t>(length)) { 436 if (key < static_cast<uint32_t>(length)) {
439 FixedDoubleArray::cast(obj->elements())->set_the_hole(key); 437 FixedDoubleArray::cast(obj->elements())->set_the_hole(key);
440 } 438 }
441 return obj->GetHeap()->true_value(); 439 return obj->GetHeap()->true_value();
442 } 440 }
443 441
444 static bool HasElementAtIndexImpl(FixedDoubleArray* backing_store, 442 static bool HasElementImpl(FixedDoubleArray* backing_store,
445 uint32_t index, 443 uint32_t key,
446 JSObject* holder, 444 JSObject* holder,
447 Object* receiver) { 445 Object* receiver) {
448 return !backing_store->is_the_hole(index); 446 return !backing_store->is_the_hole(key);
449 } 447 }
450 }; 448 };
451 449
452 450
453 // Super class for all external element arrays. 451 // Super class for all external element arrays.
454 template<typename ExternalElementsAccessorSubclass, 452 template<typename ExternalElementsAccessorSubclass,
455 typename ExternalArray> 453 typename ExternalArray>
456 class ExternalElementsAccessor 454 class ExternalElementsAccessor
457 : public ElementsAccessorBase<ExternalElementsAccessorSubclass, 455 : public ElementsAccessorBase<ExternalElementsAccessorSubclass,
458 ExternalArray> { 456 ExternalArray> {
(...skipping 18 matching lines...) Expand all
477 UNREACHABLE(); 475 UNREACHABLE();
478 return obj; 476 return obj;
479 } 477 }
480 478
481 virtual MaybeObject* Delete(JSObject* obj, 479 virtual MaybeObject* Delete(JSObject* obj,
482 uint32_t key, 480 uint32_t key,
483 JSReceiver::DeleteMode mode) { 481 JSReceiver::DeleteMode mode) {
484 // External arrays always ignore deletes. 482 // External arrays always ignore deletes.
485 return obj->GetHeap()->true_value(); 483 return obj->GetHeap()->true_value();
486 } 484 }
485
486 static bool HasElementImpl(ExternalArray* backing_store,
487 uint32_t key,
488 JSObject* holder,
489 Object* receiver) {
490 uint32_t capacity =
491 ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store);
492 return key < capacity;
493 }
487 }; 494 };
488 495
489 496
490 class ExternalByteElementsAccessor 497 class ExternalByteElementsAccessor
491 : public ExternalElementsAccessor<ExternalByteElementsAccessor, 498 : public ExternalElementsAccessor<ExternalByteElementsAccessor,
492 ExternalByteArray> { 499 ExternalByteArray> {
493 }; 500 };
494 501
495 502
496 class ExternalUnsignedByteElementsAccessor 503 class ExternalUnsignedByteElementsAccessor
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 element, 677 element,
671 key, 678 key,
672 obj); 679 obj);
673 } else { 680 } else {
674 return element; 681 return element;
675 } 682 }
676 } 683 }
677 return obj->GetHeap()->the_hole_value(); 684 return obj->GetHeap()->the_hole_value();
678 } 685 }
679 686
687 static bool HasElementImpl(SeededNumberDictionary* backing_store,
688 uint32_t key,
689 JSObject* holder,
690 Object* receiver) {
691 return backing_store->FindEntry(key) !=
692 SeededNumberDictionary::kNotFound;
693 }
694
680 static uint32_t GetKeyForIndexImpl(SeededNumberDictionary* dict, 695 static uint32_t GetKeyForIndexImpl(SeededNumberDictionary* dict,
681 uint32_t index) { 696 uint32_t index) {
682 Object* key = dict->KeyAt(index); 697 Object* key = dict->KeyAt(index);
683 return Smi::cast(key)->value(); 698 return Smi::cast(key)->value();
684 } 699 }
685 }; 700 };
686 701
687 702
688 class NonStrictArgumentsElementsAccessor 703 class NonStrictArgumentsElementsAccessor
689 : public ElementsAccessorBase<NonStrictArgumentsElementsAccessor, 704 : public ElementsAccessorBase<NonStrictArgumentsElementsAccessor,
690 FixedArray> { 705 FixedArray> {
691 protected: 706 protected:
692 friend class ElementsAccessorBase<NonStrictArgumentsElementsAccessor, 707 friend class ElementsAccessorBase<NonStrictArgumentsElementsAccessor,
693 FixedArray>; 708 FixedArray>;
694 709
695 static MaybeObject* GetImpl(FixedArray* parameter_map, 710 static MaybeObject* GetImpl(FixedArray* parameter_map,
696 uint32_t key, 711 uint32_t key,
697 JSObject* obj, 712 JSObject* obj,
698 Object* receiver) { 713 Object* receiver) {
699 Object* probe = GetParameterMapArg(parameter_map, key); 714 Object* probe = GetParameterMapArg(obj, parameter_map, key);
700 if (!probe->IsTheHole()) { 715 if (!probe->IsTheHole()) {
701 Context* context = Context::cast(parameter_map->get(0)); 716 Context* context = Context::cast(parameter_map->get(0));
702 int context_index = Smi::cast(probe)->value(); 717 int context_index = Smi::cast(probe)->value();
703 ASSERT(!context->get(context_index)->IsTheHole()); 718 ASSERT(!context->get(context_index)->IsTheHole());
704 return context->get(context_index); 719 return context->get(context_index);
705 } else { 720 } else {
706 // Object is not mapped, defer to the arguments. 721 // Object is not mapped, defer to the arguments.
707 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 722 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
708 MaybeObject* maybe_result = ElementsAccessor::ForArray(arguments)->Get( 723 MaybeObject* maybe_result = ElementsAccessor::ForArray(arguments)->Get(
709 arguments, key, obj, receiver); 724 arguments, key, obj, receiver);
(...skipping 18 matching lines...) Expand all
728 // TODO(mstarzinger): This was never implemented but will be used once we 743 // TODO(mstarzinger): This was never implemented but will be used once we
729 // correctly implement [[DefineOwnProperty]] on arrays. 744 // correctly implement [[DefineOwnProperty]] on arrays.
730 UNIMPLEMENTED(); 745 UNIMPLEMENTED();
731 return obj; 746 return obj;
732 } 747 }
733 748
734 virtual MaybeObject* Delete(JSObject* obj, 749 virtual MaybeObject* Delete(JSObject* obj,
735 uint32_t key, 750 uint32_t key,
736 JSReceiver::DeleteMode mode) { 751 JSReceiver::DeleteMode mode) {
737 FixedArray* parameter_map = FixedArray::cast(obj->elements()); 752 FixedArray* parameter_map = FixedArray::cast(obj->elements());
738 Object* probe = GetParameterMapArg(parameter_map, key); 753 Object* probe = GetParameterMapArg(obj, parameter_map, key);
739 if (!probe->IsTheHole()) { 754 if (!probe->IsTheHole()) {
740 // TODO(kmillikin): We could check if this was the last aliased 755 // TODO(kmillikin): We could check if this was the last aliased
741 // parameter, and revert to normal elements in that case. That 756 // parameter, and revert to normal elements in that case. That
742 // would enable GC of the context. 757 // would enable GC of the context.
743 parameter_map->set_the_hole(key + 2); 758 parameter_map->set_the_hole(key + 2);
744 } else { 759 } else {
745 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 760 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
746 if (arguments->IsDictionary()) { 761 if (arguments->IsDictionary()) {
747 return DictionaryElementsAccessor::DeleteCommon(obj, key, mode); 762 return DictionaryElementsAccessor::DeleteCommon(obj, key, mode);
748 } else { 763 } else {
749 return FastObjectElementsAccessor::DeleteCommon(obj, key); 764 return FastObjectElementsAccessor::DeleteCommon(obj, key);
750 } 765 }
751 } 766 }
752 return obj->GetHeap()->true_value(); 767 return obj->GetHeap()->true_value();
753 } 768 }
754 769
755 static uint32_t GetCapacityImpl(FixedArray* parameter_map) { 770 static uint32_t GetCapacityImpl(FixedArray* parameter_map) {
756 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 771 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
757 return Max(static_cast<uint32_t>(parameter_map->length() - 2), 772 return Max(static_cast<uint32_t>(parameter_map->length() - 2),
758 ForArray(arguments)->GetCapacity(arguments)); 773 ForArray(arguments)->GetCapacity(arguments));
759 } 774 }
760 775
761 static uint32_t GetKeyForIndexImpl(FixedArray* dict, 776 static uint32_t GetKeyForIndexImpl(FixedArray* dict,
762 uint32_t index) { 777 uint32_t index) {
763 return index; 778 return index;
764 } 779 }
765 780
766 static bool HasElementAtIndexImpl(FixedArray* parameter_map, 781 static bool HasElementImpl(FixedArray* parameter_map,
767 uint32_t index, 782 uint32_t key,
768 JSObject* holder, 783 JSObject* holder,
769 Object* receiver) { 784 Object* receiver) {
770 Object* probe = GetParameterMapArg(parameter_map, index); 785 Object* probe = GetParameterMapArg(holder, parameter_map, key);
771 if (!probe->IsTheHole()) { 786 if (!probe->IsTheHole()) {
772 return true; 787 return true;
773 } else { 788 } else {
774 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 789 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
775 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); 790 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments);
776 return !accessor->Get(arguments, index, holder, receiver)->IsTheHole(); 791 return !accessor->Get(arguments, key, holder, receiver)->IsTheHole();
777 } 792 }
778 } 793 }
779 794
780 private: 795 private:
781 static Object* GetParameterMapArg(FixedArray* parameter_map, 796 static Object* GetParameterMapArg(JSObject* holder,
797 FixedArray* parameter_map,
782 uint32_t key) { 798 uint32_t key) {
783 uint32_t length = parameter_map->length(); 799 uint32_t length = holder->IsJSArray()
800 ? Smi::cast(JSArray::cast(holder)->length())->value()
801 : parameter_map->length();
784 return key < (length - 2 ) 802 return key < (length - 2 )
785 ? parameter_map->get(key + 2) 803 ? parameter_map->get(key + 2)
786 : parameter_map->GetHeap()->the_hole_value(); 804 : parameter_map->GetHeap()->the_hole_value();
787 } 805 }
788 }; 806 };
789 807
790 808
791 ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) { 809 ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) {
792 switch (array->map()->instance_type()) { 810 switch (array->map()->instance_type()) {
793 case FIXED_ARRAY_TYPE: 811 case FIXED_ARRAY_TYPE:
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
922 if (!maybe_obj->To(&new_backing_store)) return maybe_obj; 940 if (!maybe_obj->To(&new_backing_store)) return maybe_obj;
923 new_backing_store->set(0, length); 941 new_backing_store->set(0, length);
924 { MaybeObject* result = array->SetContent(new_backing_store); 942 { MaybeObject* result = array->SetContent(new_backing_store);
925 if (result->IsFailure()) return result; 943 if (result->IsFailure()) return result;
926 } 944 }
927 return array; 945 return array;
928 } 946 }
929 947
930 948
931 } } // namespace v8::internal 949 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/elements.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698