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

Side by Side Diff: src/elements.cc

Issue 7618012: Change AddElementsToFixedArray to work on FixedArrayBase rather than JSObject (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: review feedback Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/elements.h ('k') | src/objects.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 // http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). We use 68 // http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). We use
69 // CRTP to guarantee aggressive compile time optimizations (i.e. inlining and 69 // CRTP to guarantee aggressive compile time optimizations (i.e. inlining and
70 // specialization of SomeElementsAccessor methods). 70 // specialization of SomeElementsAccessor methods).
71 template <typename ElementsAccessorSubclass, typename BackingStoreClass> 71 template <typename ElementsAccessorSubclass, typename BackingStoreClass>
72 class ElementsAccessorBase : public ElementsAccessor { 72 class ElementsAccessorBase : public ElementsAccessor {
73 public: 73 public:
74 ElementsAccessorBase() { } 74 ElementsAccessorBase() { }
75 virtual MaybeObject* GetWithReceiver(JSObject* obj, 75 virtual MaybeObject* GetWithReceiver(JSObject* obj,
76 Object* receiver, 76 Object* receiver,
77 uint32_t index) { 77 uint32_t index) {
78 if (index < ElementsAccessorSubclass::GetLength(obj)) { 78 BackingStoreClass* backing_store = BackingStoreClass::cast(obj->elements());
79 BackingStoreClass* backing_store = 79 if (index < ElementsAccessorSubclass::GetLength(backing_store)) {
80 ElementsAccessorSubclass::GetBackingStore(obj);
81 return backing_store->get(index); 80 return backing_store->get(index);
82 } 81 }
83 return obj->GetHeap()->the_hole_value(); 82 return obj->GetHeap()->the_hole_value();
84 } 83 }
85 84
86 virtual MaybeObject* Delete(JSObject* obj, 85 virtual MaybeObject* Delete(JSObject* obj,
87 uint32_t index, 86 uint32_t index,
88 JSReceiver::DeleteMode mode) = 0; 87 JSReceiver::DeleteMode mode) = 0;
89 88
90 virtual MaybeObject* AddJSArrayKeysToFixedArray(JSArray* other, 89 virtual MaybeObject* AddElementsToFixedArray(FixedArrayBase* from,
91 FixedArray* keys) { 90 FixedArray* to) {
92 int len0 = keys->length(); 91 int len0 = to->length();
93 #ifdef DEBUG 92 #ifdef DEBUG
94 if (FLAG_enable_slow_asserts) { 93 if (FLAG_enable_slow_asserts) {
95 for (int i = 0; i < len0; i++) { 94 for (int i = 0; i < len0; i++) {
96 ASSERT(keys->get(i)->IsString() || keys->get(i)->IsNumber()); 95 ASSERT(!to->get(i)->IsTheHole());
97 } 96 }
98 } 97 }
99 #endif 98 #endif
100 int len1 = ElementsAccessorSubclass::GetCapacity(other); 99 BackingStoreClass* backing_store = BackingStoreClass::cast(from);
100 int len1 = ElementsAccessorSubclass::GetCapacity(backing_store);
101 101
102 // Optimize if 'other' is empty. 102 // Optimize if 'other' is empty.
103 // We cannot optimize if 'this' is empty, as other may have holes 103 // We cannot optimize if 'this' is empty, as other may have holes.
104 // or non keys. 104 if (len1 == 0) return to;
105 if (len1 == 0) return keys;
106 105
107 // Compute how many elements are not in other. 106 // Compute how many elements are not in other.
108 int extra = 0; 107 int extra = 0;
109 for (int y = 0; y < len1; y++) { 108 for (int y = 0; y < len1; y++) {
110 Object* value; 109 Object* value;
111 MaybeObject* maybe_value = 110 MaybeObject* maybe_value =
112 ElementsAccessorSubclass::GetElementAtCapacityIndex(other, y); 111 ElementsAccessorSubclass::GetElementAtCapacityIndex(backing_store, y);
113 if (!maybe_value->ToObject(&value)) return maybe_value; 112 if (!maybe_value->ToObject(&value)) return maybe_value;
114 if (!value->IsTheHole() && !HasKey(keys, value)) extra++; 113 if (!value->IsTheHole() && !HasKey(to, value)) extra++;
115 } 114 }
116 115
117 if (extra == 0) return keys; 116 if (extra == 0) return to;
118 117
119 // Allocate the result 118 // Allocate the result
120 FixedArray* result; 119 FixedArray* result;
121 MaybeObject* maybe_obj = 120 MaybeObject* maybe_obj =
122 other->GetHeap()->AllocateFixedArray(len0 + extra); 121 backing_store->GetHeap()->AllocateFixedArray(len0 + extra);
123 if (!maybe_obj->To<FixedArray>(&result)) return maybe_obj; 122 if (!maybe_obj->To<FixedArray>(&result)) return maybe_obj;
124 123
125 // Fill in the content 124 // Fill in the content
126 { 125 {
127 AssertNoAllocation no_gc; 126 AssertNoAllocation no_gc;
128 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); 127 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
129 for (int i = 0; i < len0; i++) { 128 for (int i = 0; i < len0; i++) {
130 Object* e = keys->get(i); 129 Object* e = to->get(i);
131 ASSERT(e->IsString() || e->IsNumber()); 130 ASSERT(e->IsString() || e->IsNumber());
132 result->set(i, e, mode); 131 result->set(i, e, mode);
133 } 132 }
134 } 133 }
135 // Fill in the extra keys. 134 // Fill in the extra values.
136 int index = 0; 135 int index = 0;
137 for (int y = 0; y < len1; y++) { 136 for (int y = 0; y < len1; y++) {
138 MaybeObject* maybe_value = 137 MaybeObject* maybe_value =
139 ElementsAccessorSubclass::GetElementAtCapacityIndex(other, y); 138 ElementsAccessorSubclass::GetElementAtCapacityIndex(backing_store, y);
140 Object* value; 139 Object* value;
141 if (!maybe_value->ToObject(&value)) return maybe_value; 140 if (!maybe_value->ToObject(&value)) return maybe_value;
142 if (!value->IsTheHole() && !HasKey(keys, value)) { 141 if (!value->IsTheHole() && !HasKey(to, value)) {
143 ASSERT(value->IsString() || value->IsNumber());
144 result->set(len0 + index, value); 142 result->set(len0 + index, value);
145 index++; 143 index++;
146 } 144 }
147 } 145 }
148 ASSERT(extra == index); 146 ASSERT(extra == index);
149 return result; 147 return result;
150 } 148 }
151 149
152 static uint32_t GetCapacity(JSObject* obj) { 150 static uint32_t GetLength(BackingStoreClass* backing_store) {
153 return ElementsAccessorSubclass::GetBackingStore(obj)->length(); 151 return backing_store->length();
154 } 152 }
155 153
156 static MaybeObject* GetElementAtCapacityIndex(JSObject* obj, int index) { 154 static uint32_t GetCapacity(BackingStoreClass* backing_store) {
157 BackingStoreClass* backing_store = 155 return GetLength(backing_store);
158 ElementsAccessorSubclass::GetBackingStore(obj); 156 }
157
158 static MaybeObject* GetElementAtCapacityIndex(
159 BackingStoreClass* backing_store,
160 int index) {
159 return backing_store->get(index); 161 return backing_store->get(index);
160 } 162 }
161 163
162 protected:
163 static BackingStoreClass* GetBackingStore(JSObject* obj) {
164 return BackingStoreClass::cast(obj->elements());
165 }
166
167 static uint32_t GetLength(JSObject* obj) {
168 return ElementsAccessorSubclass::GetBackingStore(obj)->length();
169 }
170
171 private: 164 private:
172 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); 165 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase);
173 }; 166 };
174 167
175 168
176 class FastElementsAccessor 169 class FastElementsAccessor
177 : public ElementsAccessorBase<FastElementsAccessor, FixedArray> { 170 : public ElementsAccessorBase<FastElementsAccessor, FixedArray> {
178 public: 171 public:
179 static MaybeObject* DeleteCommon(JSObject* obj, 172 static MaybeObject* DeleteCommon(JSObject* obj,
180 uint32_t index) { 173 uint32_t index) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 // Super class for all external element arrays. 241 // Super class for all external element arrays.
249 template<typename ExternalElementsAccessorSubclass, 242 template<typename ExternalElementsAccessorSubclass,
250 typename ExternalArray> 243 typename ExternalArray>
251 class ExternalElementsAccessor 244 class ExternalElementsAccessor
252 : public ElementsAccessorBase<ExternalElementsAccessorSubclass, 245 : public ElementsAccessorBase<ExternalElementsAccessorSubclass,
253 ExternalArray> { 246 ExternalArray> {
254 public: 247 public:
255 virtual MaybeObject* GetWithReceiver(JSObject* obj, 248 virtual MaybeObject* GetWithReceiver(JSObject* obj,
256 Object* receiver, 249 Object* receiver,
257 uint32_t index) { 250 uint32_t index) {
258 if (index < ExternalElementsAccessorSubclass::GetLength(obj)) { 251 ExternalArray* backing_store = ExternalArray::cast(obj->elements());
259 ExternalArray* backing_store = 252 if (index < ExternalElementsAccessorSubclass::GetLength(backing_store)) {
260 ExternalElementsAccessorSubclass::GetBackingStore(obj);
261 return backing_store->get(index); 253 return backing_store->get(index);
262 } else { 254 } else {
263 return obj->GetHeap()->undefined_value(); 255 return obj->GetHeap()->undefined_value();
264 } 256 }
265 } 257 }
266 258
267 virtual MaybeObject* Delete(JSObject* obj, 259 virtual MaybeObject* Delete(JSObject* obj,
268 uint32_t index, 260 uint32_t index,
269 JSReceiver::DeleteMode mode) { 261 JSReceiver::DeleteMode mode) {
270 // External arrays always ignore deletes. 262 // External arrays always ignore deletes.
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 397
406 virtual MaybeObject* GetWithReceiver(JSObject* obj, 398 virtual MaybeObject* GetWithReceiver(JSObject* obj,
407 Object* receiver, 399 Object* receiver,
408 uint32_t index) { 400 uint32_t index) {
409 return GetNumberDictionaryElement(obj, 401 return GetNumberDictionaryElement(obj,
410 receiver, 402 receiver,
411 obj->element_dictionary(), 403 obj->element_dictionary(),
412 index); 404 index);
413 } 405 }
414 406
415 static uint32_t GetCapacity(JSObject* obj) { 407 static uint32_t GetCapacity(NumberDictionary* dict) {
416 return obj->element_dictionary()->Capacity(); 408 return dict->Capacity();
417 } 409 }
418 410
419 static MaybeObject* GetElementAtCapacityIndex(JSObject* obj, int index) { 411 static MaybeObject* GetElementAtCapacityIndex(NumberDictionary* dict,
420 NumberDictionary* dict = obj->element_dictionary(); 412 int index) {
421 if (dict->IsKey(dict->KeyAt(index))) { 413 if (dict->IsKey(dict->KeyAt(index))) {
422 return dict->ValueAt(index); 414 return dict->ValueAt(index);
423 } else { 415 } else {
424 return obj->GetHeap()->the_hole_value(); 416 return dict->GetHeap()->the_hole_value();
425 } 417 }
426 } 418 }
427 }; 419 };
428 420
429 421
430 class NonStrictArgumentsElementsAccessor 422 class NonStrictArgumentsElementsAccessor
431 : public ElementsAccessorBase<NonStrictArgumentsElementsAccessor, 423 : public ElementsAccessorBase<NonStrictArgumentsElementsAccessor,
432 FixedArray> { 424 FixedArray> {
433 public: 425 public:
434 virtual MaybeObject* GetWithReceiver(JSObject* obj, 426 virtual MaybeObject* GetWithReceiver(JSObject* obj,
435 Object* receiver, 427 Object* receiver,
436 uint32_t index) { 428 uint32_t index) {
437 FixedArray* parameter_map = GetBackingStore(obj); 429 FixedArray* parameter_map = FixedArray::cast(obj->elements());
438 uint32_t length = parameter_map->length(); 430 uint32_t length = parameter_map->length();
439 Object* probe = 431 Object* probe =
440 (index < length - 2) ? parameter_map->get(index + 2) : NULL; 432 (index < length - 2) ? parameter_map->get(index + 2) : NULL;
441 if (probe != NULL && !probe->IsTheHole()) { 433 if (probe != NULL && !probe->IsTheHole()) {
442 Context* context = Context::cast(parameter_map->get(0)); 434 Context* context = Context::cast(parameter_map->get(0));
443 int context_index = Smi::cast(probe)->value(); 435 int context_index = Smi::cast(probe)->value();
444 ASSERT(!context->get(context_index)->IsTheHole()); 436 ASSERT(!context->get(context_index)->IsTheHole());
445 return context->get(context_index); 437 return context->get(context_index);
446 } else { 438 } else {
447 // Object is not mapped, defer to the arguments. 439 // Object is not mapped, defer to the arguments.
(...skipping 27 matching lines...) Expand all
475 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 467 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
476 if (arguments->IsDictionary()) { 468 if (arguments->IsDictionary()) {
477 return DictionaryElementsAccessor::DeleteCommon(obj, index, mode); 469 return DictionaryElementsAccessor::DeleteCommon(obj, index, mode);
478 } else { 470 } else {
479 return FastElementsAccessor::DeleteCommon(obj, index); 471 return FastElementsAccessor::DeleteCommon(obj, index);
480 } 472 }
481 } 473 }
482 return obj->GetHeap()->true_value(); 474 return obj->GetHeap()->true_value();
483 } 475 }
484 476
485 static uint32_t GetCapacity(JSObject* obj) { 477 static uint32_t GetCapacity(FixedArray* obj) {
486 // TODO(danno): Return max of parameter map length or backing store 478 // TODO(danno): Return max of parameter map length or backing store
487 // capacity. 479 // capacity.
488 return 0; 480 return 0;
489 } 481 }
490 482
491 static MaybeObject* GetElementAtCapacityIndex(JSObject* obj, int index) { 483 static MaybeObject* GetElementAtCapacityIndex(FixedArray* obj, int index) {
492 // TODO(danno): Return either value from parameter map of backing 484 // TODO(danno): Return either value from parameter map of backing
493 // store value at index. 485 // store value at index.
494 return obj->GetHeap()->the_hole_value(); 486 return obj->GetHeap()->the_hole_value();
495 } 487 }
496 }; 488 };
497 489
498 490
499 void ElementsAccessor::InitializeOncePerProcess() { 491 void ElementsAccessor::InitializeOncePerProcess() {
500 static struct ConcreteElementsAccessors { 492 static struct ConcreteElementsAccessors {
501 FastElementsAccessor fast_elements_handler; 493 FastElementsAccessor fast_elements_handler;
(...skipping 25 matching lines...) Expand all
527 &element_accessors.float_elements_handler, 519 &element_accessors.float_elements_handler,
528 &element_accessors.double_elements_handler, 520 &element_accessors.double_elements_handler,
529 &element_accessors.pixel_elements_handler 521 &element_accessors.pixel_elements_handler
530 }; 522 };
531 523
532 elements_accessors_ = accessor_array; 524 elements_accessors_ = accessor_array;
533 } 525 }
534 526
535 527
536 } } // namespace v8::internal 528 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/elements.h ('k') | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698