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

Side by Side Diff: src/objects.cc

Issue 558041: RFC: Try to be much more careful with where we skip the write barrier by:... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 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 | « src/objects.h ('k') | src/objects-inl.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 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 3182 matching lines...) Expand 10 before | Expand all | Expand 10 after
3193 Object* value = other->get(y); 3193 Object* value = other->get(y);
3194 if (!value->IsTheHole() && !HasKey(this, value)) extra++; 3194 if (!value->IsTheHole() && !HasKey(this, value)) extra++;
3195 } 3195 }
3196 3196
3197 if (extra == 0) return this; 3197 if (extra == 0) return this;
3198 3198
3199 // Allocate the result 3199 // Allocate the result
3200 Object* obj = Heap::AllocateFixedArray(len0 + extra); 3200 Object* obj = Heap::AllocateFixedArray(len0 + extra);
3201 if (obj->IsFailure()) return obj; 3201 if (obj->IsFailure()) return obj;
3202 // Fill in the content 3202 // Fill in the content
3203 AssertNoAllocation no_gc;
3203 FixedArray* result = FixedArray::cast(obj); 3204 FixedArray* result = FixedArray::cast(obj);
3204 WriteBarrierMode mode = result->GetWriteBarrierMode(); 3205 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
3205 for (int i = 0; i < len0; i++) { 3206 for (int i = 0; i < len0; i++) {
3206 result->set(i, get(i), mode); 3207 result->set(i, get(i), mode);
3207 } 3208 }
3208 // Fill in the extra keys. 3209 // Fill in the extra keys.
3209 int index = 0; 3210 int index = 0;
3210 for (int y = 0; y < len1; y++) { 3211 for (int y = 0; y < len1; y++) {
3211 Object* value = other->get(y); 3212 Object* value = other->get(y);
3212 if (!value->IsTheHole() && !HasKey(this, value)) { 3213 if (!value->IsTheHole() && !HasKey(this, value)) {
3213 result->set(len0 + index, other->get(y), mode); 3214 result->set(len0 + index, other->get(y), mode);
3214 index++; 3215 index++;
3215 } 3216 }
3216 } 3217 }
3217 ASSERT(extra == index); 3218 ASSERT(extra == index);
3218 return result; 3219 return result;
3219 } 3220 }
3220 3221
3221 3222
3222 Object* FixedArray::CopySize(int new_length) { 3223 Object* FixedArray::CopySize(int new_length) {
3223 if (new_length == 0) return Heap::empty_fixed_array(); 3224 if (new_length == 0) return Heap::empty_fixed_array();
3224 Object* obj = Heap::AllocateFixedArray(new_length); 3225 Object* obj = Heap::AllocateFixedArray(new_length);
3225 if (obj->IsFailure()) return obj; 3226 if (obj->IsFailure()) return obj;
3226 FixedArray* result = FixedArray::cast(obj); 3227 FixedArray* result = FixedArray::cast(obj);
3227 // Copy the content 3228 // Copy the content
3229 AssertNoAllocation no_gc;
3228 int len = length(); 3230 int len = length();
3229 if (new_length < len) len = new_length; 3231 if (new_length < len) len = new_length;
3230 result->set_map(map()); 3232 result->set_map(map());
3231 WriteBarrierMode mode = result->GetWriteBarrierMode(); 3233 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
3232 for (int i = 0; i < len; i++) { 3234 for (int i = 0; i < len; i++) {
3233 result->set(i, get(i), mode); 3235 result->set(i, get(i), mode);
3234 } 3236 }
3235 return result; 3237 return result;
3236 } 3238 }
3237 3239
3238 3240
3239 void FixedArray::CopyTo(int pos, FixedArray* dest, int dest_pos, int len) { 3241 void FixedArray::CopyTo(int pos, FixedArray* dest, int dest_pos, int len) {
3240 WriteBarrierMode mode = dest->GetWriteBarrierMode(); 3242 AssertNoAllocation no_gc;
3243 WriteBarrierMode mode = dest->GetWriteBarrierMode(no_gc);
3241 for (int index = 0; index < len; index++) { 3244 for (int index = 0; index < len; index++) {
3242 dest->set(dest_pos+index, get(pos+index), mode); 3245 dest->set(dest_pos+index, get(pos+index), mode);
3243 } 3246 }
3244 } 3247 }
3245 3248
3246 3249
3247 #ifdef DEBUG 3250 #ifdef DEBUG
3248 bool FixedArray::IsEqualTo(FixedArray* other) { 3251 bool FixedArray::IsEqualTo(FixedArray* other) {
3249 if (length() != other->length()) return false; 3252 if (length() != other->length()) return false;
3250 for (int i = 0 ; i < length(); ++i) { 3253 for (int i = 0 ; i < length(); ++i) {
(...skipping 13 matching lines...) Expand all
3264 Heap::AllocateFixedArray(ToKeyIndex(number_of_descriptors)); 3267 Heap::AllocateFixedArray(ToKeyIndex(number_of_descriptors));
3265 if (array->IsFailure()) return array; 3268 if (array->IsFailure()) return array;
3266 // Do not use DescriptorArray::cast on incomplete object. 3269 // Do not use DescriptorArray::cast on incomplete object.
3267 FixedArray* result = FixedArray::cast(array); 3270 FixedArray* result = FixedArray::cast(array);
3268 3271
3269 // Allocate the content array and set it in the descriptor array. 3272 // Allocate the content array and set it in the descriptor array.
3270 array = Heap::AllocateFixedArray(number_of_descriptors << 1); 3273 array = Heap::AllocateFixedArray(number_of_descriptors << 1);
3271 if (array->IsFailure()) return array; 3274 if (array->IsFailure()) return array;
3272 result->set(kContentArrayIndex, array); 3275 result->set(kContentArrayIndex, array);
3273 result->set(kEnumerationIndexIndex, 3276 result->set(kEnumerationIndexIndex,
3274 Smi::FromInt(PropertyDetails::kInitialIndex), 3277 Smi::FromInt(PropertyDetails::kInitialIndex));
3275 SKIP_WRITE_BARRIER);
3276 return result; 3278 return result;
3277 } 3279 }
3278 3280
3279 3281
3280 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage, 3282 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage,
3281 FixedArray* new_cache) { 3283 FixedArray* new_cache) {
3282 ASSERT(bridge_storage->length() >= kEnumCacheBridgeLength); 3284 ASSERT(bridge_storage->length() >= kEnumCacheBridgeLength);
3283 if (HasEnumCache()) { 3285 if (HasEnumCache()) {
3284 FixedArray::cast(get(kEnumerationIndexIndex))-> 3286 FixedArray::cast(get(kEnumerationIndexIndex))->
3285 set(kEnumCacheBridgeCacheIndex, new_cache); 3287 set(kEnumCacheBridgeCacheIndex, new_cache);
(...skipping 1407 matching lines...) Expand 10 before | Expand all | Expand 10 after
4693 // check if the target is live. If not, null the descriptor. 4695 // check if the target is live. If not, null the descriptor.
4694 // Also drop the back pointer for that map transition, so that this 4696 // Also drop the back pointer for that map transition, so that this
4695 // map is not reached again by following a back pointer from a 4697 // map is not reached again by following a back pointer from a
4696 // non-live object. 4698 // non-live object.
4697 PropertyDetails details(Smi::cast(contents->get(i + 1))); 4699 PropertyDetails details(Smi::cast(contents->get(i + 1)));
4698 if (details.type() == MAP_TRANSITION) { 4700 if (details.type() == MAP_TRANSITION) {
4699 Map* target = reinterpret_cast<Map*>(contents->get(i)); 4701 Map* target = reinterpret_cast<Map*>(contents->get(i));
4700 ASSERT(target->IsHeapObject()); 4702 ASSERT(target->IsHeapObject());
4701 if (!target->IsMarked()) { 4703 if (!target->IsMarked()) {
4702 ASSERT(target->IsMap()); 4704 ASSERT(target->IsMap());
4703 contents->set(i + 1, NullDescriptorDetails, SKIP_WRITE_BARRIER); 4705 contents->set(i + 1, NullDescriptorDetails);
4704 contents->set(i, Heap::null_value(), SKIP_WRITE_BARRIER); 4706 contents->set_null(i);
4705 ASSERT(target->prototype() == this || 4707 ASSERT(target->prototype() == this ||
4706 target->prototype() == real_prototype); 4708 target->prototype() == real_prototype);
4707 // Getter prototype() is read-only, set_prototype() has side effects. 4709 // Getter prototype() is read-only, set_prototype() has side effects.
4708 *RawField(target, Map::kPrototypeOffset) = real_prototype; 4710 *RawField(target, Map::kPrototypeOffset) = real_prototype;
4709 } 4711 }
4710 } 4712 }
4711 } 4713 }
4712 } 4714 }
4713 4715
4714 4716
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after
5154 5156
5155 5157
5156 void JSObject::SetFastElements(FixedArray* elems) { 5158 void JSObject::SetFastElements(FixedArray* elems) {
5157 // We should never end in here with a pixel or external array. 5159 // We should never end in here with a pixel or external array.
5158 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); 5160 ASSERT(!HasPixelElements() && !HasExternalArrayElements());
5159 #ifdef DEBUG 5161 #ifdef DEBUG
5160 // Check the provided array is filled with the_hole. 5162 // Check the provided array is filled with the_hole.
5161 uint32_t len = static_cast<uint32_t>(elems->length()); 5163 uint32_t len = static_cast<uint32_t>(elems->length());
5162 for (uint32_t i = 0; i < len; i++) ASSERT(elems->get(i)->IsTheHole()); 5164 for (uint32_t i = 0; i < len; i++) ASSERT(elems->get(i)->IsTheHole());
5163 #endif 5165 #endif
5164 WriteBarrierMode mode = elems->GetWriteBarrierMode(); 5166 AssertNoAllocation no_gc;
5167 WriteBarrierMode mode = elems->GetWriteBarrierMode(no_gc);
5165 switch (GetElementsKind()) { 5168 switch (GetElementsKind()) {
5166 case FAST_ELEMENTS: { 5169 case FAST_ELEMENTS: {
5167 FixedArray* old_elements = FixedArray::cast(elements()); 5170 FixedArray* old_elements = FixedArray::cast(elements());
5168 uint32_t old_length = static_cast<uint32_t>(old_elements->length()); 5171 uint32_t old_length = static_cast<uint32_t>(old_elements->length());
5169 // Fill out the new array with this content and array holes. 5172 // Fill out the new array with this content and array holes.
5170 for (uint32_t i = 0; i < old_length; i++) { 5173 for (uint32_t i = 0; i < old_length; i++) {
5171 elems->set(i, old_elements->get(i), mode); 5174 elems->set(i, old_elements->get(i), mode);
5172 } 5175 }
5173 break; 5176 break;
5174 } 5177 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
5221 default: 5224 default:
5222 UNREACHABLE(); 5225 UNREACHABLE();
5223 break; 5226 break;
5224 } 5227 }
5225 return this; 5228 return this;
5226 } 5229 }
5227 5230
5228 5231
5229 Object* JSArray::Initialize(int capacity) { 5232 Object* JSArray::Initialize(int capacity) {
5230 ASSERT(capacity >= 0); 5233 ASSERT(capacity >= 0);
5231 set_length(Smi::FromInt(0), SKIP_WRITE_BARRIER); 5234 set_length(Smi::FromInt(0));
5232 FixedArray* new_elements; 5235 FixedArray* new_elements;
5233 if (capacity == 0) { 5236 if (capacity == 0) {
5234 new_elements = Heap::empty_fixed_array(); 5237 new_elements = Heap::empty_fixed_array();
5235 } else { 5238 } else {
5236 Object* obj = Heap::AllocateFixedArrayWithHoles(capacity); 5239 Object* obj = Heap::AllocateFixedArrayWithHoles(capacity);
5237 if (obj->IsFailure()) return obj; 5240 if (obj->IsFailure()) return obj;
5238 new_elements = FixedArray::cast(obj); 5241 new_elements = FixedArray::cast(obj);
5239 } 5242 }
5240 set_elements(new_elements); 5243 set_elements(new_elements);
5241 return this; 5244 return this;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
5281 int old_capacity = FixedArray::cast(elements())->length(); 5284 int old_capacity = FixedArray::cast(elements())->length();
5282 if (value <= old_capacity) { 5285 if (value <= old_capacity) {
5283 if (IsJSArray()) { 5286 if (IsJSArray()) {
5284 int old_length = FastD2I(JSArray::cast(this)->length()->Number()); 5287 int old_length = FastD2I(JSArray::cast(this)->length()->Number());
5285 // NOTE: We may be able to optimize this by removing the 5288 // NOTE: We may be able to optimize this by removing the
5286 // last part of the elements backing storage array and 5289 // last part of the elements backing storage array and
5287 // setting the capacity to the new size. 5290 // setting the capacity to the new size.
5288 for (int i = value; i < old_length; i++) { 5291 for (int i = value; i < old_length; i++) {
5289 FixedArray::cast(elements())->set_the_hole(i); 5292 FixedArray::cast(elements())->set_the_hole(i);
5290 } 5293 }
5291 JSArray::cast(this)->set_length(smi_length, SKIP_WRITE_BARRIER); 5294 JSArray::cast(this)->set_length(Smi::cast(smi_length));
5292 } 5295 }
5293 return this; 5296 return this;
5294 } 5297 }
5295 int min = NewElementsCapacity(old_capacity); 5298 int min = NewElementsCapacity(old_capacity);
5296 int new_capacity = value > min ? value : min; 5299 int new_capacity = value > min ? value : min;
5297 if (new_capacity <= kMaxFastElementsLength || 5300 if (new_capacity <= kMaxFastElementsLength ||
5298 !ShouldConvertToSlowElements(new_capacity)) { 5301 !ShouldConvertToSlowElements(new_capacity)) {
5299 Object* obj = Heap::AllocateFixedArrayWithHoles(new_capacity); 5302 Object* obj = Heap::AllocateFixedArrayWithHoles(new_capacity);
5300 if (obj->IsFailure()) return obj; 5303 if (obj->IsFailure()) return obj;
5301 if (IsJSArray()) JSArray::cast(this)->set_length(smi_length, 5304 if (IsJSArray()) {
5302 SKIP_WRITE_BARRIER); 5305 JSArray::cast(this)->set_length(Smi::cast(smi_length));
5306 }
5303 SetFastElements(FixedArray::cast(obj)); 5307 SetFastElements(FixedArray::cast(obj));
5304 return this; 5308 return this;
5305 } 5309 }
5306 break; 5310 break;
5307 } 5311 }
5308 case DICTIONARY_ELEMENTS: { 5312 case DICTIONARY_ELEMENTS: {
5309 if (IsJSArray()) { 5313 if (IsJSArray()) {
5310 if (value == 0) { 5314 if (value == 0) {
5311 // If the length of a slow array is reset to zero, we clear 5315 // If the length of a slow array is reset to zero, we clear
5312 // the array and flush backing storage. This has the added 5316 // the array and flush backing storage. This has the added
5313 // benefit that the array returns to fast mode. 5317 // benefit that the array returns to fast mode.
5314 initialize_elements(); 5318 initialize_elements();
5315 } else { 5319 } else {
5316 // Remove deleted elements. 5320 // Remove deleted elements.
5317 uint32_t old_length = 5321 uint32_t old_length =
5318 static_cast<uint32_t>(JSArray::cast(this)->length()->Number()); 5322 static_cast<uint32_t>(JSArray::cast(this)->length()->Number());
5319 element_dictionary()->RemoveNumberEntries(value, old_length); 5323 element_dictionary()->RemoveNumberEntries(value, old_length);
5320 } 5324 }
5321 JSArray::cast(this)->set_length(smi_length, SKIP_WRITE_BARRIER); 5325 JSArray::cast(this)->set_length(Smi::cast(smi_length));
5322 } 5326 }
5323 return this; 5327 return this;
5324 } 5328 }
5325 default: 5329 default:
5326 UNREACHABLE(); 5330 UNREACHABLE();
5327 break; 5331 break;
5328 } 5332 }
5329 } 5333 }
5330 5334
5331 // General slow case. 5335 // General slow case.
5332 if (len->IsNumber()) { 5336 if (len->IsNumber()) {
5333 uint32_t length; 5337 uint32_t length;
5334 if (Array::IndexFromObject(len, &length)) { 5338 if (Array::IndexFromObject(len, &length)) {
5335 return SetSlowElements(len); 5339 return SetSlowElements(len);
5336 } else { 5340 } else {
5337 return ArrayLengthRangeError(); 5341 return ArrayLengthRangeError();
5338 } 5342 }
5339 } 5343 }
5340 5344
5341 // len is not a number so make the array size one and 5345 // len is not a number so make the array size one and
5342 // set only element to len. 5346 // set only element to len.
5343 Object* obj = Heap::AllocateFixedArray(1); 5347 Object* obj = Heap::AllocateFixedArray(1);
5344 if (obj->IsFailure()) return obj; 5348 if (obj->IsFailure()) return obj;
5345 FixedArray::cast(obj)->set(0, len); 5349 FixedArray::cast(obj)->set(0, len);
5346 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1), 5350 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1));
5347 SKIP_WRITE_BARRIER);
5348 set_elements(FixedArray::cast(obj)); 5351 set_elements(FixedArray::cast(obj));
5349 return this; 5352 return this;
5350 } 5353 }
5351 5354
5352 5355
5353 bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) { 5356 bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) {
5354 switch (GetElementsKind()) { 5357 switch (GetElementsKind()) {
5355 case FAST_ELEMENTS: { 5358 case FAST_ELEMENTS: {
5356 uint32_t length = IsJSArray() ? 5359 uint32_t length = IsJSArray() ?
5357 static_cast<uint32_t> 5360 static_cast<uint32_t>
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
5607 5610
5608 // Check whether there is extra space in fixed array.. 5611 // Check whether there is extra space in fixed array..
5609 if (index < elms_length) { 5612 if (index < elms_length) {
5610 elms->set(index, value); 5613 elms->set(index, value);
5611 if (IsJSArray()) { 5614 if (IsJSArray()) {
5612 // Update the length of the array if needed. 5615 // Update the length of the array if needed.
5613 uint32_t array_length = 0; 5616 uint32_t array_length = 0;
5614 CHECK(Array::IndexFromObject(JSArray::cast(this)->length(), 5617 CHECK(Array::IndexFromObject(JSArray::cast(this)->length(),
5615 &array_length)); 5618 &array_length));
5616 if (index >= array_length) { 5619 if (index >= array_length) {
5617 JSArray::cast(this)->set_length(Smi::FromInt(index + 1), 5620 JSArray::cast(this)->set_length(Smi::FromInt(index + 1));
5618 SKIP_WRITE_BARRIER);
5619 } 5621 }
5620 } 5622 }
5621 return value; 5623 return value;
5622 } 5624 }
5623 5625
5624 // Allow gap in fast case. 5626 // Allow gap in fast case.
5625 if ((index - elms_length) < kMaxGap) { 5627 if ((index - elms_length) < kMaxGap) {
5626 // Try allocating extra space. 5628 // Try allocating extra space.
5627 int new_capacity = NewElementsCapacity(index+1); 5629 int new_capacity = NewElementsCapacity(index+1);
5628 if (new_capacity <= kMaxFastElementsLength || 5630 if (new_capacity <= kMaxFastElementsLength ||
5629 !ShouldConvertToSlowElements(new_capacity)) { 5631 !ShouldConvertToSlowElements(new_capacity)) {
5630 ASSERT(static_cast<uint32_t>(new_capacity) > index); 5632 ASSERT(static_cast<uint32_t>(new_capacity) > index);
5631 Object* obj = Heap::AllocateFixedArrayWithHoles(new_capacity); 5633 Object* obj = Heap::AllocateFixedArrayWithHoles(new_capacity);
5632 if (obj->IsFailure()) return obj; 5634 if (obj->IsFailure()) return obj;
5633 SetFastElements(FixedArray::cast(obj)); 5635 SetFastElements(FixedArray::cast(obj));
5634 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(index + 1), 5636 if (IsJSArray()) {
5635 SKIP_WRITE_BARRIER); 5637 JSArray::cast(this)->set_length(Smi::FromInt(index + 1));
5638 }
5636 FixedArray::cast(elements())->set(index, value); 5639 FixedArray::cast(elements())->set(index, value);
5637 return value; 5640 return value;
5638 } 5641 }
5639 } 5642 }
5640 5643
5641 // Otherwise default to slow case. 5644 // Otherwise default to slow case.
5642 Object* obj = NormalizeElements(); 5645 Object* obj = NormalizeElements();
5643 if (obj->IsFailure()) return obj; 5646 if (obj->IsFailure()) return obj;
5644 ASSERT(HasDictionaryElements()); 5647 ASSERT(HasDictionaryElements());
5645 return SetElement(index, value); 5648 return SetElement(index, value);
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
6122 } 6125 }
6123 } 6126 }
6124 } 6127 }
6125 #endif 6128 #endif
6126 6129
6127 6130
6128 template<typename Shape, typename Key> 6131 template<typename Shape, typename Key>
6129 void Dictionary<Shape, Key>::CopyValuesTo(FixedArray* elements) { 6132 void Dictionary<Shape, Key>::CopyValuesTo(FixedArray* elements) {
6130 int pos = 0; 6133 int pos = 0;
6131 int capacity = HashTable<Shape, Key>::Capacity(); 6134 int capacity = HashTable<Shape, Key>::Capacity();
6132 WriteBarrierMode mode = elements->GetWriteBarrierMode(); 6135 AssertNoAllocation no_gc;
6136 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
6133 for (int i = 0; i < capacity; i++) { 6137 for (int i = 0; i < capacity; i++) {
6134 Object* k = Dictionary<Shape, Key>::KeyAt(i); 6138 Object* k = Dictionary<Shape, Key>::KeyAt(i);
6135 if (Dictionary<Shape, Key>::IsKey(k)) { 6139 if (Dictionary<Shape, Key>::IsKey(k)) {
6136 elements->set(pos++, ValueAt(i), mode); 6140 elements->set(pos++, ValueAt(i), mode);
6137 } 6141 }
6138 } 6142 }
6139 ASSERT(pos == elements->length()); 6143 ASSERT(pos == elements->length());
6140 } 6144 }
6141 6145
6142 6146
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
6493 PropertyAttributes filter) { 6497 PropertyAttributes filter) {
6494 int counter = 0; 6498 int counter = 0;
6495 switch (GetElementsKind()) { 6499 switch (GetElementsKind()) {
6496 case FAST_ELEMENTS: { 6500 case FAST_ELEMENTS: {
6497 int length = IsJSArray() ? 6501 int length = IsJSArray() ?
6498 Smi::cast(JSArray::cast(this)->length())->value() : 6502 Smi::cast(JSArray::cast(this)->length())->value() :
6499 FixedArray::cast(elements())->length(); 6503 FixedArray::cast(elements())->length();
6500 for (int i = 0; i < length; i++) { 6504 for (int i = 0; i < length; i++) {
6501 if (!FixedArray::cast(elements())->get(i)->IsTheHole()) { 6505 if (!FixedArray::cast(elements())->get(i)->IsTheHole()) {
6502 if (storage != NULL) { 6506 if (storage != NULL) {
6503 storage->set(counter, Smi::FromInt(i), SKIP_WRITE_BARRIER); 6507 storage->set(counter, Smi::FromInt(i));
6504 } 6508 }
6505 counter++; 6509 counter++;
6506 } 6510 }
6507 } 6511 }
6508 ASSERT(!storage || storage->length() >= counter); 6512 ASSERT(!storage || storage->length() >= counter);
6509 break; 6513 break;
6510 } 6514 }
6511 case PIXEL_ELEMENTS: { 6515 case PIXEL_ELEMENTS: {
6512 int length = PixelArray::cast(elements())->length(); 6516 int length = PixelArray::cast(elements())->length();
6513 while (counter < length) { 6517 while (counter < length) {
6514 if (storage != NULL) { 6518 if (storage != NULL) {
6515 storage->set(counter, Smi::FromInt(counter), SKIP_WRITE_BARRIER); 6519 storage->set(counter, Smi::FromInt(counter));
6516 } 6520 }
6517 counter++; 6521 counter++;
6518 } 6522 }
6519 ASSERT(!storage || storage->length() >= counter); 6523 ASSERT(!storage || storage->length() >= counter);
6520 break; 6524 break;
6521 } 6525 }
6522 case EXTERNAL_BYTE_ELEMENTS: 6526 case EXTERNAL_BYTE_ELEMENTS:
6523 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 6527 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
6524 case EXTERNAL_SHORT_ELEMENTS: 6528 case EXTERNAL_SHORT_ELEMENTS:
6525 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 6529 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
6526 case EXTERNAL_INT_ELEMENTS: 6530 case EXTERNAL_INT_ELEMENTS:
6527 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 6531 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
6528 case EXTERNAL_FLOAT_ELEMENTS: { 6532 case EXTERNAL_FLOAT_ELEMENTS: {
6529 int length = ExternalArray::cast(elements())->length(); 6533 int length = ExternalArray::cast(elements())->length();
6530 while (counter < length) { 6534 while (counter < length) {
6531 if (storage != NULL) { 6535 if (storage != NULL) {
6532 storage->set(counter, Smi::FromInt(counter), SKIP_WRITE_BARRIER); 6536 storage->set(counter, Smi::FromInt(counter));
6533 } 6537 }
6534 counter++; 6538 counter++;
6535 } 6539 }
6536 ASSERT(!storage || storage->length() >= counter); 6540 ASSERT(!storage || storage->length() >= counter);
6537 break; 6541 break;
6538 } 6542 }
6539 case DICTIONARY_ELEMENTS: { 6543 case DICTIONARY_ELEMENTS: {
6540 if (storage != NULL) { 6544 if (storage != NULL) {
6541 element_dictionary()->CopyKeysTo(storage, filter); 6545 element_dictionary()->CopyKeysTo(storage, filter);
6542 } 6546 }
6543 counter = element_dictionary()->NumberOfElementsFilterAttributes(filter); 6547 counter = element_dictionary()->NumberOfElementsFilterAttributes(filter);
6544 break; 6548 break;
6545 } 6549 }
6546 default: 6550 default:
6547 UNREACHABLE(); 6551 UNREACHABLE();
6548 break; 6552 break;
6549 } 6553 }
6550 6554
6551 if (this->IsJSValue()) { 6555 if (this->IsJSValue()) {
6552 Object* val = JSValue::cast(this)->value(); 6556 Object* val = JSValue::cast(this)->value();
6553 if (val->IsString()) { 6557 if (val->IsString()) {
6554 String* str = String::cast(val); 6558 String* str = String::cast(val);
6555 if (storage) { 6559 if (storage) {
6556 for (int i = 0; i < str->length(); i++) { 6560 for (int i = 0; i < str->length(); i++) {
6557 storage->set(counter + i, Smi::FromInt(i), SKIP_WRITE_BARRIER); 6561 storage->set(counter + i, Smi::FromInt(i));
6558 } 6562 }
6559 } 6563 }
6560 counter += str->length(); 6564 counter += str->length();
6561 } 6565 }
6562 } 6566 }
6563 ASSERT(!storage || storage->length() == counter); 6567 ASSERT(!storage || storage->length() == counter);
6564 return counter; 6568 return counter;
6565 } 6569 }
6566 6570
6567 6571
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
6879 int nof = NumberOfElements() + n; 6883 int nof = NumberOfElements() + n;
6880 int nod = NumberOfDeletedElements(); 6884 int nod = NumberOfDeletedElements();
6881 // Return if: 6885 // Return if:
6882 // 50% is still free after adding n elements and 6886 // 50% is still free after adding n elements and
6883 // at most 50% of the free elements are deleted elements. 6887 // at most 50% of the free elements are deleted elements.
6884 if ((nof + (nof >> 1) <= capacity) && 6888 if ((nof + (nof >> 1) <= capacity) &&
6885 (nod <= (capacity - nof) >> 1)) return this; 6889 (nod <= (capacity - nof) >> 1)) return this;
6886 6890
6887 Object* obj = Allocate(nof * 2); 6891 Object* obj = Allocate(nof * 2);
6888 if (obj->IsFailure()) return obj; 6892 if (obj->IsFailure()) return obj;
6893
6894 AssertNoAllocation no_gc;
6889 HashTable* table = HashTable::cast(obj); 6895 HashTable* table = HashTable::cast(obj);
6890 WriteBarrierMode mode = table->GetWriteBarrierMode(); 6896 WriteBarrierMode mode = table->GetWriteBarrierMode(no_gc);
6891 6897
6892 // Copy prefix to new array. 6898 // Copy prefix to new array.
6893 for (int i = kPrefixStartIndex; 6899 for (int i = kPrefixStartIndex;
6894 i < kPrefixStartIndex + Shape::kPrefixSize; 6900 i < kPrefixStartIndex + Shape::kPrefixSize;
6895 i++) { 6901 i++) {
6896 table->set(i, get(i), mode); 6902 table->set(i, get(i), mode);
6897 } 6903 }
6898 // Rehash the elements. 6904 // Rehash the elements.
6899 for (int i = 0; i < capacity; i++) { 6905 for (int i = 0; i < capacity; i++) {
6900 uint32_t from_index = EntryToIndex(i); 6906 uint32_t from_index = EntryToIndex(i);
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
7127 // we start mutating the array. 7133 // we start mutating the array.
7128 Object* new_double = Heap::AllocateHeapNumber(0.0); 7134 Object* new_double = Heap::AllocateHeapNumber(0.0);
7129 if (new_double->IsFailure()) return new_double; 7135 if (new_double->IsFailure()) return new_double;
7130 result_double = HeapNumber::cast(new_double); 7136 result_double = HeapNumber::cast(new_double);
7131 } 7137 }
7132 7138
7133 AssertNoAllocation no_alloc; 7139 AssertNoAllocation no_alloc;
7134 7140
7135 // Split elements into defined, undefined and the_hole, in that order. 7141 // Split elements into defined, undefined and the_hole, in that order.
7136 // Only count locations for undefined and the hole, and fill them afterwards. 7142 // Only count locations for undefined and the hole, and fill them afterwards.
7137 WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(); 7143 WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_alloc);
7138 unsigned int undefs = limit; 7144 unsigned int undefs = limit;
7139 unsigned int holes = limit; 7145 unsigned int holes = limit;
7140 // Assume most arrays contain no holes and undefined values, so minimize the 7146 // Assume most arrays contain no holes and undefined values, so minimize the
7141 // number of stores of non-undefined, non-the-hole values. 7147 // number of stores of non-undefined, non-the-hole values.
7142 for (unsigned int i = 0; i < undefs; i++) { 7148 for (unsigned int i = 0; i < undefs; i++) {
7143 Object* current = elements->get(i); 7149 Object* current = elements->get(i);
7144 if (current->IsTheHole()) { 7150 if (current->IsTheHole()) {
7145 holes--; 7151 holes--;
7146 undefs--; 7152 undefs--;
7147 } else if (current->IsUndefined()) { 7153 } else if (current->IsUndefined()) {
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
7622 7628
7623 template<typename Shape, typename Key> 7629 template<typename Shape, typename Key>
7624 Object* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() { 7630 Object* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() {
7625 int length = HashTable<Shape, Key>::NumberOfElements(); 7631 int length = HashTable<Shape, Key>::NumberOfElements();
7626 7632
7627 // Allocate and initialize iteration order array. 7633 // Allocate and initialize iteration order array.
7628 Object* obj = Heap::AllocateFixedArray(length); 7634 Object* obj = Heap::AllocateFixedArray(length);
7629 if (obj->IsFailure()) return obj; 7635 if (obj->IsFailure()) return obj;
7630 FixedArray* iteration_order = FixedArray::cast(obj); 7636 FixedArray* iteration_order = FixedArray::cast(obj);
7631 for (int i = 0; i < length; i++) { 7637 for (int i = 0; i < length; i++) {
7632 iteration_order->set(i, Smi::FromInt(i), SKIP_WRITE_BARRIER); 7638 iteration_order->set(i, Smi::FromInt(i));
7633 } 7639 }
7634 7640
7635 // Allocate array with enumeration order. 7641 // Allocate array with enumeration order.
7636 obj = Heap::AllocateFixedArray(length); 7642 obj = Heap::AllocateFixedArray(length);
7637 if (obj->IsFailure()) return obj; 7643 if (obj->IsFailure()) return obj;
7638 FixedArray* enumeration_order = FixedArray::cast(obj); 7644 FixedArray* enumeration_order = FixedArray::cast(obj);
7639 7645
7640 // Fill the enumeration order array with property details. 7646 // Fill the enumeration order array with property details.
7641 int capacity = HashTable<Shape, Key>::Capacity(); 7647 int capacity = HashTable<Shape, Key>::Capacity();
7642 int pos = 0; 7648 int pos = 0;
7643 for (int i = 0; i < capacity; i++) { 7649 for (int i = 0; i < capacity; i++) {
7644 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { 7650 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) {
7645 enumeration_order->set(pos++, 7651 enumeration_order->set(pos++, Smi::FromInt(DetailsAt(i).index()));
7646 Smi::FromInt(DetailsAt(i).index()),
7647 SKIP_WRITE_BARRIER);
7648 } 7652 }
7649 } 7653 }
7650 7654
7651 // Sort the arrays wrt. enumeration order. 7655 // Sort the arrays wrt. enumeration order.
7652 iteration_order->SortPairs(enumeration_order, enumeration_order->length()); 7656 iteration_order->SortPairs(enumeration_order, enumeration_order->length());
7653 7657
7654 // Overwrite the enumeration_order with the enumeration indices. 7658 // Overwrite the enumeration_order with the enumeration indices.
7655 for (int i = 0; i < length; i++) { 7659 for (int i = 0; i < length; i++) {
7656 int index = Smi::cast(iteration_order->get(i))->value(); 7660 int index = Smi::cast(iteration_order->get(i))->value();
7657 int enum_index = PropertyDetails::kInitialIndex + i; 7661 int enum_index = PropertyDetails::kInitialIndex + i;
7658 enumeration_order->set(index, 7662 enumeration_order->set(index, Smi::FromInt(enum_index));
7659 Smi::FromInt(enum_index),
7660 SKIP_WRITE_BARRIER);
7661 } 7663 }
7662 7664
7663 // Update the dictionary with new indices. 7665 // Update the dictionary with new indices.
7664 capacity = HashTable<Shape, Key>::Capacity(); 7666 capacity = HashTable<Shape, Key>::Capacity();
7665 pos = 0; 7667 pos = 0;
7666 for (int i = 0; i < capacity; i++) { 7668 for (int i = 0; i < capacity; i++) {
7667 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { 7669 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) {
7668 int enum_index = Smi::cast(enumeration_order->get(pos++))->value(); 7670 int enum_index = Smi::cast(enumeration_order->get(pos++))->value();
7669 PropertyDetails details = DetailsAt(i); 7671 PropertyDetails details = DetailsAt(i);
7670 PropertyDetails new_details = 7672 PropertyDetails new_details =
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
7798 // Check if this index is high enough that we should require slow 7800 // Check if this index is high enough that we should require slow
7799 // elements. 7801 // elements.
7800 if (key > kRequiresSlowElementsLimit) { 7802 if (key > kRequiresSlowElementsLimit) {
7801 set_requires_slow_elements(); 7803 set_requires_slow_elements();
7802 return; 7804 return;
7803 } 7805 }
7804 // Update max key value. 7806 // Update max key value.
7805 Object* max_index_object = get(kMaxNumberKeyIndex); 7807 Object* max_index_object = get(kMaxNumberKeyIndex);
7806 if (!max_index_object->IsSmi() || max_number_key() < key) { 7808 if (!max_index_object->IsSmi() || max_number_key() < key) {
7807 FixedArray::set(kMaxNumberKeyIndex, 7809 FixedArray::set(kMaxNumberKeyIndex,
7808 Smi::FromInt(key << kRequiresSlowElementsTagSize), 7810 Smi::FromInt(key << kRequiresSlowElementsTagSize));
7809 SKIP_WRITE_BARRIER);
7810 } 7811 }
7811 } 7812 }
7812 7813
7813 7814
7814 Object* NumberDictionary::AddNumberEntry(uint32_t key, 7815 Object* NumberDictionary::AddNumberEntry(uint32_t key,
7815 Object* value, 7816 Object* value,
7816 PropertyDetails details) { 7817 PropertyDetails details) {
7817 UpdateMaxNumberKey(key); 7818 UpdateMaxNumberKey(key);
7818 SLOW_ASSERT(FindEntry(key) == kNotFound); 7819 SLOW_ASSERT(FindEntry(key) == kNotFound);
7819 return Add(key, value, details); 7820 return Add(key, value, details);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
7890 FixedArray* sort_array) { 7891 FixedArray* sort_array) {
7891 ASSERT(storage->length() >= NumberOfEnumElements()); 7892 ASSERT(storage->length() >= NumberOfEnumElements());
7892 int capacity = Capacity(); 7893 int capacity = Capacity();
7893 int index = 0; 7894 int index = 0;
7894 for (int i = 0; i < capacity; i++) { 7895 for (int i = 0; i < capacity; i++) {
7895 Object* k = KeyAt(i); 7896 Object* k = KeyAt(i);
7896 if (IsKey(k)) { 7897 if (IsKey(k)) {
7897 PropertyDetails details = DetailsAt(i); 7898 PropertyDetails details = DetailsAt(i);
7898 if (details.IsDeleted() || details.IsDontEnum()) continue; 7899 if (details.IsDeleted() || details.IsDontEnum()) continue;
7899 storage->set(index, k); 7900 storage->set(index, k);
7900 sort_array->set(index, 7901 sort_array->set(index, Smi::FromInt(details.index()));
7901 Smi::FromInt(details.index()),
7902 SKIP_WRITE_BARRIER);
7903 index++; 7902 index++;
7904 } 7903 }
7905 } 7904 }
7906 storage->SortPairs(sort_array, sort_array->length()); 7905 storage->SortPairs(sort_array, sort_array->length());
7907 ASSERT(storage->length() >= index); 7906 ASSERT(storage->length() >= index);
7908 } 7907 }
7909 7908
7910 7909
7911 template<typename Shape, typename Key> 7910 template<typename Shape, typename Key>
7912 void Dictionary<Shape, Key>::CopyKeysTo(FixedArray* storage) { 7911 void Dictionary<Shape, Key>::CopyKeysTo(FixedArray* storage) {
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
8301 if (break_point_objects()->IsUndefined()) return 0; 8300 if (break_point_objects()->IsUndefined()) return 0;
8302 // Single beak point. 8301 // Single beak point.
8303 if (!break_point_objects()->IsFixedArray()) return 1; 8302 if (!break_point_objects()->IsFixedArray()) return 1;
8304 // Multiple break points. 8303 // Multiple break points.
8305 return FixedArray::cast(break_point_objects())->length(); 8304 return FixedArray::cast(break_point_objects())->length();
8306 } 8305 }
8307 #endif 8306 #endif
8308 8307
8309 8308
8310 } } // namespace v8::internal 8309 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698