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

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: fix whitespce 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()); 142 ASSERT(value->IsString() || value->IsNumber());
Sven Panne 2011/08/12 08:20:43 This ASSERT should be removed to make this method
144 result->set(len0 + index, value); 143 result->set(len0 + index, value);
145 index++; 144 index++;
146 } 145 }
147 } 146 }
148 ASSERT(extra == index); 147 ASSERT(extra == index);
149 return result; 148 return result;
150 } 149 }
151 150
152 static uint32_t GetCapacity(JSObject* obj) { 151 static uint32_t GetLength(BackingStoreClass* backing_store) {
153 return ElementsAccessorSubclass::GetBackingStore(obj)->length(); 152 return backing_store->length();
154 } 153 }
155 154
156 static MaybeObject* GetElementAtCapacityIndex(JSObject* obj, int index) { 155 static uint32_t GetCapacity(BackingStoreClass* backing_store) {
157 BackingStoreClass* backing_store = 156 return GetLength(backing_store);
158 ElementsAccessorSubclass::GetBackingStore(obj); 157 }
158
159 static MaybeObject* GetElementAtCapacityIndex(
160 BackingStoreClass* backing_store,
161 int index) {
159 return backing_store->get(index); 162 return backing_store->get(index);
160 } 163 }
161 164
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: 165 private:
172 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); 166 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase);
173 }; 167 };
174 168
175 169
176 class FastElementsAccessor 170 class FastElementsAccessor
177 : public ElementsAccessorBase<FastElementsAccessor, FixedArray> { 171 : public ElementsAccessorBase<FastElementsAccessor, FixedArray> {
178 public: 172 public:
179 static MaybeObject* DeleteCommon(JSObject* obj, 173 static MaybeObject* DeleteCommon(JSObject* obj,
180 uint32_t index) { 174 uint32_t index) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 // Super class for all external element arrays. 242 // Super class for all external element arrays.
249 template<typename ExternalElementsAccessorSubclass, 243 template<typename ExternalElementsAccessorSubclass,
250 typename ExternalArray> 244 typename ExternalArray>
251 class ExternalElementsAccessor 245 class ExternalElementsAccessor
252 : public ElementsAccessorBase<ExternalElementsAccessorSubclass, 246 : public ElementsAccessorBase<ExternalElementsAccessorSubclass,
253 ExternalArray> { 247 ExternalArray> {
254 public: 248 public:
255 virtual MaybeObject* GetWithReceiver(JSObject* obj, 249 virtual MaybeObject* GetWithReceiver(JSObject* obj,
256 Object* receiver, 250 Object* receiver,
257 uint32_t index) { 251 uint32_t index) {
258 if (index < ExternalElementsAccessorSubclass::GetLength(obj)) { 252 ExternalArray* backing_store = ExternalArray::cast(obj->elements());
259 ExternalArray* backing_store = 253 if (index < ExternalElementsAccessorSubclass::GetLength(backing_store)) {
260 ExternalElementsAccessorSubclass::GetBackingStore(obj);
261 return backing_store->get(index); 254 return backing_store->get(index);
262 } else { 255 } else {
263 return obj->GetHeap()->undefined_value(); 256 return obj->GetHeap()->undefined_value();
264 } 257 }
265 } 258 }
266 259
267 virtual MaybeObject* Delete(JSObject* obj, 260 virtual MaybeObject* Delete(JSObject* obj,
268 uint32_t index, 261 uint32_t index,
269 JSReceiver::DeleteMode mode) { 262 JSReceiver::DeleteMode mode) {
270 // External arrays always ignore deletes. 263 // External arrays always ignore deletes.
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 398
406 virtual MaybeObject* GetWithReceiver(JSObject* obj, 399 virtual MaybeObject* GetWithReceiver(JSObject* obj,
407 Object* receiver, 400 Object* receiver,
408 uint32_t index) { 401 uint32_t index) {
409 return GetNumberDictionaryElement(obj, 402 return GetNumberDictionaryElement(obj,
410 receiver, 403 receiver,
411 obj->element_dictionary(), 404 obj->element_dictionary(),
412 index); 405 index);
413 } 406 }
414 407
415 static uint32_t GetCapacity(JSObject* obj) { 408 static uint32_t GetCapacity(NumberDictionary* dict) {
416 return obj->element_dictionary()->Capacity(); 409 return dict->Capacity();
417 } 410 }
418 411
419 static MaybeObject* GetElementAtCapacityIndex(JSObject* obj, int index) { 412 static MaybeObject* GetElementAtCapacityIndex(NumberDictionary* dict,
420 NumberDictionary* dict = obj->element_dictionary(); 413 int index) {
421 if (dict->IsKey(dict->KeyAt(index))) { 414 if (dict->IsKey(dict->KeyAt(index))) {
422 return dict->ValueAt(index); 415 return dict->ValueAt(index);
423 } else { 416 } else {
424 return obj->GetHeap()->the_hole_value(); 417 return dict->GetHeap()->the_hole_value();
425 } 418 }
426 } 419 }
427 }; 420 };
428 421
429 422
430 class NonStrictArgumentsElementsAccessor 423 class NonStrictArgumentsElementsAccessor
431 : public ElementsAccessorBase<NonStrictArgumentsElementsAccessor, 424 : public ElementsAccessorBase<NonStrictArgumentsElementsAccessor,
432 FixedArray> { 425 FixedArray> {
433 public: 426 public:
434 virtual MaybeObject* GetWithReceiver(JSObject* obj, 427 virtual MaybeObject* GetWithReceiver(JSObject* obj,
435 Object* receiver, 428 Object* receiver,
436 uint32_t index) { 429 uint32_t index) {
437 FixedArray* parameter_map = GetBackingStore(obj); 430 FixedArray* parameter_map = FixedArray::cast(obj->elements());
438 uint32_t length = parameter_map->length(); 431 uint32_t length = parameter_map->length();
439 Object* probe = 432 Object* probe =
440 (index < length - 2) ? parameter_map->get(index + 2) : NULL; 433 (index < length - 2) ? parameter_map->get(index + 2) : NULL;
441 if (probe != NULL && !probe->IsTheHole()) { 434 if (probe != NULL && !probe->IsTheHole()) {
442 Context* context = Context::cast(parameter_map->get(0)); 435 Context* context = Context::cast(parameter_map->get(0));
443 int context_index = Smi::cast(probe)->value(); 436 int context_index = Smi::cast(probe)->value();
444 ASSERT(!context->get(context_index)->IsTheHole()); 437 ASSERT(!context->get(context_index)->IsTheHole());
445 return context->get(context_index); 438 return context->get(context_index);
446 } else { 439 } else {
447 // Object is not mapped, defer to the arguments. 440 // Object is not mapped, defer to the arguments.
(...skipping 27 matching lines...) Expand all
475 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 468 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
476 if (arguments->IsDictionary()) { 469 if (arguments->IsDictionary()) {
477 return DictionaryElementsAccessor::DeleteCommon(obj, index, mode); 470 return DictionaryElementsAccessor::DeleteCommon(obj, index, mode);
478 } else { 471 } else {
479 return FastElementsAccessor::DeleteCommon(obj, index); 472 return FastElementsAccessor::DeleteCommon(obj, index);
480 } 473 }
481 } 474 }
482 return obj->GetHeap()->true_value(); 475 return obj->GetHeap()->true_value();
483 } 476 }
484 477
485 static uint32_t GetCapacity(JSObject* obj) { 478 static uint32_t GetCapacity(FixedArray* obj) {
486 // TODO(danno): Return max of parameter map length or backing store 479 // TODO(danno): Return max of parameter map length or backing store
487 // capacity. 480 // capacity.
488 return 0; 481 return 0;
489 } 482 }
490 483
491 static MaybeObject* GetElementAtCapacityIndex(JSObject* obj, int index) { 484 static MaybeObject* GetElementAtCapacityIndex(FixedArray* obj, int index) {
492 // TODO(danno): Return either value from parameter map of backing 485 // TODO(danno): Return either value from parameter map of backing
493 // store value at index. 486 // store value at index.
494 return obj->GetHeap()->the_hole_value(); 487 return obj->GetHeap()->the_hole_value();
495 } 488 }
496 }; 489 };
497 490
498 491
499 void ElementsAccessor::InitializeOncePerProcess() { 492 void ElementsAccessor::InitializeOncePerProcess() {
500 static struct ConcreteElementsAccessors { 493 static struct ConcreteElementsAccessors {
501 FastElementsAccessor fast_elements_handler; 494 FastElementsAccessor fast_elements_handler;
(...skipping 25 matching lines...) Expand all
527 &element_accessors.float_elements_handler, 520 &element_accessors.float_elements_handler,
528 &element_accessors.double_elements_handler, 521 &element_accessors.double_elements_handler,
529 &element_accessors.pixel_elements_handler 522 &element_accessors.pixel_elements_handler
530 }; 523 };
531 524
532 elements_accessors_ = accessor_array; 525 elements_accessors_ = accessor_array;
533 } 526 }
534 527
535 528
536 } } // namespace v8::internal 529 } } // 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