| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 2629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2640 Object* array = Heap::AllocateFixedArray(ToKeyIndex(number_of_descriptors)); | 2640 Object* array = Heap::AllocateFixedArray(ToKeyIndex(number_of_descriptors)); |
| 2641 if (array->IsFailure()) return array; | 2641 if (array->IsFailure()) return array; |
| 2642 // Do not use DescriptorArray::cast on incomplete object. | 2642 // Do not use DescriptorArray::cast on incomplete object. |
| 2643 FixedArray* result = FixedArray::cast(array); | 2643 FixedArray* result = FixedArray::cast(array); |
| 2644 | 2644 |
| 2645 // Allocate the content array and set it in the descriptor array. | 2645 // Allocate the content array and set it in the descriptor array. |
| 2646 array = Heap::AllocateFixedArray(number_of_descriptors << 1); | 2646 array = Heap::AllocateFixedArray(number_of_descriptors << 1); |
| 2647 if (array->IsFailure()) return array; | 2647 if (array->IsFailure()) return array; |
| 2648 result->set(kContentArrayIndex, array); | 2648 result->set(kContentArrayIndex, array); |
| 2649 result->set(kEnumerationIndexIndex, | 2649 result->set(kEnumerationIndexIndex, |
| 2650 Smi::FromInt(PropertyDetails::kInitialIndex)); | 2650 Smi::FromInt(PropertyDetails::kInitialIndex), |
| 2651 SKIP_WRITE_BARRIER); |
| 2651 return result; | 2652 return result; |
| 2652 } | 2653 } |
| 2653 | 2654 |
| 2654 | 2655 |
| 2655 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage, | 2656 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage, |
| 2656 FixedArray* new_cache) { | 2657 FixedArray* new_cache) { |
| 2657 ASSERT(bridge_storage->length() >= kEnumCacheBridgeLength); | 2658 ASSERT(bridge_storage->length() >= kEnumCacheBridgeLength); |
| 2658 if (HasEnumCache()) { | 2659 if (HasEnumCache()) { |
| 2659 FixedArray::cast(get(kEnumerationIndexIndex))-> | 2660 FixedArray::cast(get(kEnumerationIndexIndex))-> |
| 2660 set(kEnumCacheBridgeCacheIndex, new_cache); | 2661 set(kEnumCacheBridgeCacheIndex, new_cache); |
| (...skipping 1783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4444 } | 4445 } |
| 4445 #endif // ENABLE_DISASSEMBLER | 4446 #endif // ENABLE_DISASSEMBLER |
| 4446 | 4447 |
| 4447 | 4448 |
| 4448 void JSObject::SetFastElements(FixedArray* elems) { | 4449 void JSObject::SetFastElements(FixedArray* elems) { |
| 4449 #ifdef DEBUG | 4450 #ifdef DEBUG |
| 4450 // Check the provided array is filled with the_hole. | 4451 // Check the provided array is filled with the_hole. |
| 4451 uint32_t len = static_cast<uint32_t>(elems->length()); | 4452 uint32_t len = static_cast<uint32_t>(elems->length()); |
| 4452 for (uint32_t i = 0; i < len; i++) ASSERT(elems->get(i)->IsTheHole()); | 4453 for (uint32_t i = 0; i < len; i++) ASSERT(elems->get(i)->IsTheHole()); |
| 4453 #endif | 4454 #endif |
| 4454 FixedArray::WriteBarrierMode mode = elems->GetWriteBarrierMode(); | 4455 WriteBarrierMode mode = elems->GetWriteBarrierMode(); |
| 4455 if (HasFastElements()) { | 4456 if (HasFastElements()) { |
| 4456 FixedArray* old_elements = FixedArray::cast(elements()); | 4457 FixedArray* old_elements = FixedArray::cast(elements()); |
| 4457 uint32_t old_length = static_cast<uint32_t>(old_elements->length()); | 4458 uint32_t old_length = static_cast<uint32_t>(old_elements->length()); |
| 4458 // Fill out the new array with this content and array holes. | 4459 // Fill out the new array with this content and array holes. |
| 4459 for (uint32_t i = 0; i < old_length; i++) { | 4460 for (uint32_t i = 0; i < old_length; i++) { |
| 4460 elems->set(i, old_elements->get(i), mode); | 4461 elems->set(i, old_elements->get(i), mode); |
| 4461 } | 4462 } |
| 4462 } else { | 4463 } else { |
| 4463 Dictionary* dictionary = Dictionary::cast(elements()); | 4464 Dictionary* dictionary = Dictionary::cast(elements()); |
| 4464 for (int i = 0; i < dictionary->Capacity(); i++) { | 4465 for (int i = 0; i < dictionary->Capacity(); i++) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 4493 if (obj->IsFailure()) return obj; | 4494 if (obj->IsFailure()) return obj; |
| 4494 | 4495 |
| 4495 // Update length for JSArrays. | 4496 // Update length for JSArrays. |
| 4496 if (IsJSArray()) JSArray::cast(this)->set_length(len); | 4497 if (IsJSArray()) JSArray::cast(this)->set_length(len); |
| 4497 return this; | 4498 return this; |
| 4498 } | 4499 } |
| 4499 | 4500 |
| 4500 | 4501 |
| 4501 Object* JSArray::Initialize(int capacity) { | 4502 Object* JSArray::Initialize(int capacity) { |
| 4502 ASSERT(capacity >= 0); | 4503 ASSERT(capacity >= 0); |
| 4503 set_length(Smi::FromInt(0)); | 4504 set_length(Smi::FromInt(0), SKIP_WRITE_BARRIER); |
| 4504 FixedArray* new_elements; | 4505 FixedArray* new_elements; |
| 4505 if (capacity == 0) { | 4506 if (capacity == 0) { |
| 4506 new_elements = Heap::empty_fixed_array(); | 4507 new_elements = Heap::empty_fixed_array(); |
| 4507 } else { | 4508 } else { |
| 4508 Object* obj = Heap::AllocateFixedArrayWithHoles(capacity); | 4509 Object* obj = Heap::AllocateFixedArrayWithHoles(capacity); |
| 4509 if (obj->IsFailure()) return obj; | 4510 if (obj->IsFailure()) return obj; |
| 4510 new_elements = FixedArray::cast(obj); | 4511 new_elements = FixedArray::cast(obj); |
| 4511 } | 4512 } |
| 4512 set_elements(new_elements); | 4513 set_elements(new_elements); |
| 4513 return this; | 4514 return this; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 4537 int old_capacity = FixedArray::cast(elements())->length(); | 4538 int old_capacity = FixedArray::cast(elements())->length(); |
| 4538 if (value <= old_capacity) { | 4539 if (value <= old_capacity) { |
| 4539 if (IsJSArray()) { | 4540 if (IsJSArray()) { |
| 4540 int old_length = FastD2I(JSArray::cast(this)->length()->Number()); | 4541 int old_length = FastD2I(JSArray::cast(this)->length()->Number()); |
| 4541 // NOTE: We may be able to optimize this by removing the | 4542 // NOTE: We may be able to optimize this by removing the |
| 4542 // last part of the elements backing storage array and | 4543 // last part of the elements backing storage array and |
| 4543 // setting the capacity to the new size. | 4544 // setting the capacity to the new size. |
| 4544 for (int i = value; i < old_length; i++) { | 4545 for (int i = value; i < old_length; i++) { |
| 4545 FixedArray::cast(elements())->set_the_hole(i); | 4546 FixedArray::cast(elements())->set_the_hole(i); |
| 4546 } | 4547 } |
| 4547 JSArray::cast(this)->set_length(smi_length); | 4548 JSArray::cast(this)->set_length(smi_length, SKIP_WRITE_BARRIER); |
| 4548 } | 4549 } |
| 4549 return this; | 4550 return this; |
| 4550 } | 4551 } |
| 4551 int min = NewElementsCapacity(old_capacity); | 4552 int min = NewElementsCapacity(old_capacity); |
| 4552 int new_capacity = value > min ? value : min; | 4553 int new_capacity = value > min ? value : min; |
| 4553 if (new_capacity <= kMaxFastElementsLength || | 4554 if (new_capacity <= kMaxFastElementsLength || |
| 4554 !ShouldConvertToSlowElements(new_capacity)) { | 4555 !ShouldConvertToSlowElements(new_capacity)) { |
| 4555 Object* obj = Heap::AllocateFixedArrayWithHoles(new_capacity); | 4556 Object* obj = Heap::AllocateFixedArrayWithHoles(new_capacity); |
| 4556 if (obj->IsFailure()) return obj; | 4557 if (obj->IsFailure()) return obj; |
| 4557 if (IsJSArray()) JSArray::cast(this)->set_length(smi_length); | 4558 if (IsJSArray()) JSArray::cast(this)->set_length(smi_length, |
| 4559 SKIP_WRITE_BARRIER); |
| 4558 SetFastElements(FixedArray::cast(obj)); | 4560 SetFastElements(FixedArray::cast(obj)); |
| 4559 return this; | 4561 return this; |
| 4560 } | 4562 } |
| 4561 } else { | 4563 } else { |
| 4562 if (IsJSArray()) { | 4564 if (IsJSArray()) { |
| 4563 if (value == 0) { | 4565 if (value == 0) { |
| 4564 // If the length of a slow array is reset to zero, we clear | 4566 // If the length of a slow array is reset to zero, we clear |
| 4565 // the array and flush backing storage. This has the added | 4567 // the array and flush backing storage. This has the added |
| 4566 // benefit that the array returns to fast mode. | 4568 // benefit that the array returns to fast mode. |
| 4567 initialize_elements(); | 4569 initialize_elements(); |
| 4568 } else { | 4570 } else { |
| 4569 // Remove deleted elements. | 4571 // Remove deleted elements. |
| 4570 uint32_t old_length = | 4572 uint32_t old_length = |
| 4571 static_cast<uint32_t>(JSArray::cast(this)->length()->Number()); | 4573 static_cast<uint32_t>(JSArray::cast(this)->length()->Number()); |
| 4572 element_dictionary()->RemoveNumberEntries(value, old_length); | 4574 element_dictionary()->RemoveNumberEntries(value, old_length); |
| 4573 } | 4575 } |
| 4574 JSArray::cast(this)->set_length(smi_length); | 4576 JSArray::cast(this)->set_length(smi_length, SKIP_WRITE_BARRIER); |
| 4575 } | 4577 } |
| 4576 return this; | 4578 return this; |
| 4577 } | 4579 } |
| 4578 } | 4580 } |
| 4579 | 4581 |
| 4580 // General slow case. | 4582 // General slow case. |
| 4581 if (len->IsNumber()) { | 4583 if (len->IsNumber()) { |
| 4582 uint32_t length; | 4584 uint32_t length; |
| 4583 if (Array::IndexFromObject(len, &length)) { | 4585 if (Array::IndexFromObject(len, &length)) { |
| 4584 return SetSlowElements(len); | 4586 return SetSlowElements(len); |
| 4585 } else { | 4587 } else { |
| 4586 return ArrayLengthRangeError(); | 4588 return ArrayLengthRangeError(); |
| 4587 } | 4589 } |
| 4588 } | 4590 } |
| 4589 | 4591 |
| 4590 // len is not a number so make the array size one and | 4592 // len is not a number so make the array size one and |
| 4591 // set only element to len. | 4593 // set only element to len. |
| 4592 Object* obj = Heap::AllocateFixedArray(1); | 4594 Object* obj = Heap::AllocateFixedArray(1); |
| 4593 if (obj->IsFailure()) return obj; | 4595 if (obj->IsFailure()) return obj; |
| 4594 FixedArray::cast(obj)->set(0, len); | 4596 FixedArray::cast(obj)->set(0, len); |
| 4595 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1)); | 4597 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1), |
| 4598 SKIP_WRITE_BARRIER); |
| 4596 set_elements(FixedArray::cast(obj)); | 4599 set_elements(FixedArray::cast(obj)); |
| 4597 return this; | 4600 return this; |
| 4598 } | 4601 } |
| 4599 | 4602 |
| 4600 | 4603 |
| 4601 bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) { | 4604 bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) { |
| 4602 if (HasFastElements()) { | 4605 if (HasFastElements()) { |
| 4603 uint32_t length = IsJSArray() ? | 4606 uint32_t length = IsJSArray() ? |
| 4604 static_cast<uint32_t>( | 4607 static_cast<uint32_t>( |
| 4605 Smi::cast(JSArray::cast(this)->length())->value()) : | 4608 Smi::cast(JSArray::cast(this)->length())->value()) : |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4786 | 4789 |
| 4787 // Check whether there is extra space in fixed array.. | 4790 // Check whether there is extra space in fixed array.. |
| 4788 if (index < elms_length) { | 4791 if (index < elms_length) { |
| 4789 elms->set(index, value); | 4792 elms->set(index, value); |
| 4790 if (IsJSArray()) { | 4793 if (IsJSArray()) { |
| 4791 // Update the length of the array if needed. | 4794 // Update the length of the array if needed. |
| 4792 uint32_t array_length = 0; | 4795 uint32_t array_length = 0; |
| 4793 CHECK(Array::IndexFromObject(JSArray::cast(this)->length(), | 4796 CHECK(Array::IndexFromObject(JSArray::cast(this)->length(), |
| 4794 &array_length)); | 4797 &array_length)); |
| 4795 if (index >= array_length) { | 4798 if (index >= array_length) { |
| 4796 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); | 4799 JSArray::cast(this)->set_length(Smi::FromInt(index + 1), |
| 4800 SKIP_WRITE_BARRIER); |
| 4797 } | 4801 } |
| 4798 } | 4802 } |
| 4799 return value; | 4803 return value; |
| 4800 } | 4804 } |
| 4801 | 4805 |
| 4802 // Allow gap in fast case. | 4806 // Allow gap in fast case. |
| 4803 if ((index - elms_length) < kMaxGap) { | 4807 if ((index - elms_length) < kMaxGap) { |
| 4804 // Try allocating extra space. | 4808 // Try allocating extra space. |
| 4805 int new_capacity = NewElementsCapacity(index+1); | 4809 int new_capacity = NewElementsCapacity(index+1); |
| 4806 if (new_capacity <= kMaxFastElementsLength || | 4810 if (new_capacity <= kMaxFastElementsLength || |
| 4807 !ShouldConvertToSlowElements(new_capacity)) { | 4811 !ShouldConvertToSlowElements(new_capacity)) { |
| 4808 ASSERT(static_cast<uint32_t>(new_capacity) > index); | 4812 ASSERT(static_cast<uint32_t>(new_capacity) > index); |
| 4809 Object* obj = Heap::AllocateFixedArrayWithHoles(new_capacity); | 4813 Object* obj = Heap::AllocateFixedArrayWithHoles(new_capacity); |
| 4810 if (obj->IsFailure()) return obj; | 4814 if (obj->IsFailure()) return obj; |
| 4811 SetFastElements(FixedArray::cast(obj)); | 4815 SetFastElements(FixedArray::cast(obj)); |
| 4812 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); | 4816 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(index + 1), |
| 4817 SKIP_WRITE_BARRIER); |
| 4813 FixedArray::cast(elements())->set(index, value); | 4818 FixedArray::cast(elements())->set(index, value); |
| 4814 return value; | 4819 return value; |
| 4815 } | 4820 } |
| 4816 } | 4821 } |
| 4817 | 4822 |
| 4818 // Otherwise default to slow case. | 4823 // Otherwise default to slow case. |
| 4819 Object* obj = NormalizeElements(); | 4824 Object* obj = NormalizeElements(); |
| 4820 if (obj->IsFailure()) return obj; | 4825 if (obj->IsFailure()) return obj; |
| 4821 ASSERT(!HasFastElements()); | 4826 ASSERT(!HasFastElements()); |
| 4822 return SetElement(index, value); | 4827 return SetElement(index, value); |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5084 int len = Smi::cast(length())->value(); | 5089 int len = Smi::cast(length())->value(); |
| 5085 int pos = 0; | 5090 int pos = 0; |
| 5086 FixedArray* elms = FixedArray::cast(elements()); | 5091 FixedArray* elms = FixedArray::cast(elements()); |
| 5087 for (int index = 0; index < len; index++) { | 5092 for (int index = 0; index < len; index++) { |
| 5088 Object* e = elms->get(index); | 5093 Object* e = elms->get(index); |
| 5089 if (!e->IsTheHole()) { | 5094 if (!e->IsTheHole()) { |
| 5090 if (index != pos) elms->set(pos, e); | 5095 if (index != pos) elms->set(pos, e); |
| 5091 pos++; | 5096 pos++; |
| 5092 } | 5097 } |
| 5093 } | 5098 } |
| 5094 set_length(Smi::FromInt(pos)); | 5099 set_length(Smi::FromInt(pos), SKIP_WRITE_BARRIER); |
| 5095 for (int index = pos; index < len; index++) { | 5100 for (int index = pos; index < len; index++) { |
| 5096 elms->set_the_hole(index); | 5101 elms->set_the_hole(index); |
| 5097 } | 5102 } |
| 5098 return this; | 5103 return this; |
| 5099 } | 5104 } |
| 5100 | 5105 |
| 5101 // Compact the sparse array if possible. | 5106 // Compact the sparse array if possible. |
| 5102 Dictionary* dict = element_dictionary(); | 5107 Dictionary* dict = element_dictionary(); |
| 5103 int length = dict->NumberOfElements(); | 5108 int length = dict->NumberOfElements(); |
| 5104 | 5109 |
| 5105 // Try to make this a fast array again. | 5110 // Try to make this a fast array again. |
| 5106 if (length <= kMaxFastElementsLength) { | 5111 if (length <= kMaxFastElementsLength) { |
| 5107 Object* obj = Heap::AllocateFixedArray(length); | 5112 Object* obj = Heap::AllocateFixedArray(length); |
| 5108 if (obj->IsFailure()) return obj; | 5113 if (obj->IsFailure()) return obj; |
| 5109 dict->CopyValuesTo(FixedArray::cast(obj)); | 5114 dict->CopyValuesTo(FixedArray::cast(obj)); |
| 5110 set_length(Smi::FromInt(length)); | 5115 set_length(Smi::FromInt(length), SKIP_WRITE_BARRIER); |
| 5111 set_elements(FixedArray::cast(obj)); | 5116 set_elements(FixedArray::cast(obj)); |
| 5112 return this; | 5117 return this; |
| 5113 } | 5118 } |
| 5114 | 5119 |
| 5115 // Make another dictionary with smaller indices. | 5120 // Make another dictionary with smaller indices. |
| 5116 Object* obj = dict->RemoveHoles(); | 5121 Object* obj = dict->RemoveHoles(); |
| 5117 if (obj->IsFailure()) return obj; | 5122 if (obj->IsFailure()) return obj; |
| 5118 set_length(Smi::FromInt(length)); | 5123 set_length(Smi::FromInt(length), SKIP_WRITE_BARRIER); |
| 5119 set_elements(Dictionary::cast(obj)); | 5124 set_elements(Dictionary::cast(obj)); |
| 5120 return this; | 5125 return this; |
| 5121 } | 5126 } |
| 5122 | 5127 |
| 5123 | 5128 |
| 5124 InterceptorInfo* JSObject::GetNamedInterceptor() { | 5129 InterceptorInfo* JSObject::GetNamedInterceptor() { |
| 5125 ASSERT(map()->has_named_interceptor()); | 5130 ASSERT(map()->has_named_interceptor()); |
| 5126 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 5131 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
| 5127 Object* template_info = constructor->shared()->function_data(); | 5132 Object* template_info = constructor->shared()->function_data(); |
| 5128 Object* result = | 5133 Object* result = |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5436 int JSObject::GetLocalElementKeys(FixedArray* storage, | 5441 int JSObject::GetLocalElementKeys(FixedArray* storage, |
| 5437 PropertyAttributes filter) { | 5442 PropertyAttributes filter) { |
| 5438 int counter = 0; | 5443 int counter = 0; |
| 5439 if (HasFastElements()) { | 5444 if (HasFastElements()) { |
| 5440 int length = IsJSArray() | 5445 int length = IsJSArray() |
| 5441 ? Smi::cast(JSArray::cast(this)->length())->value() | 5446 ? Smi::cast(JSArray::cast(this)->length())->value() |
| 5442 : FixedArray::cast(elements())->length(); | 5447 : FixedArray::cast(elements())->length(); |
| 5443 for (int i = 0; i < length; i++) { | 5448 for (int i = 0; i < length; i++) { |
| 5444 if (!FixedArray::cast(elements())->get(i)->IsTheHole()) { | 5449 if (!FixedArray::cast(elements())->get(i)->IsTheHole()) { |
| 5445 if (storage) { | 5450 if (storage) { |
| 5446 storage->set(counter, | 5451 storage->set(counter, Smi::FromInt(i), SKIP_WRITE_BARRIER); |
| 5447 Smi::FromInt(i), | |
| 5448 FixedArray::SKIP_WRITE_BARRIER); | |
| 5449 } | 5452 } |
| 5450 counter++; | 5453 counter++; |
| 5451 } | 5454 } |
| 5452 } | 5455 } |
| 5453 ASSERT(!storage || storage->length() >= counter); | 5456 ASSERT(!storage || storage->length() >= counter); |
| 5454 } else { | 5457 } else { |
| 5455 if (storage) { | 5458 if (storage) { |
| 5456 element_dictionary()->CopyKeysTo(storage, filter); | 5459 element_dictionary()->CopyKeysTo(storage, filter); |
| 5457 } | 5460 } |
| 5458 counter = element_dictionary()->NumberOfElementsFilterAttributes(filter); | 5461 counter = element_dictionary()->NumberOfElementsFilterAttributes(filter); |
| 5459 } | 5462 } |
| 5460 | 5463 |
| 5461 if (this->IsJSValue()) { | 5464 if (this->IsJSValue()) { |
| 5462 Object* val = JSValue::cast(this)->value(); | 5465 Object* val = JSValue::cast(this)->value(); |
| 5463 if (val->IsString()) { | 5466 if (val->IsString()) { |
| 5464 String* str = String::cast(val); | 5467 String* str = String::cast(val); |
| 5465 if (storage) { | 5468 if (storage) { |
| 5466 for (int i = 0; i < str->length(); i++) { | 5469 for (int i = 0; i < str->length(); i++) { |
| 5467 storage->set(counter + i, | 5470 storage->set(counter + i, Smi::FromInt(i), SKIP_WRITE_BARRIER); |
| 5468 Smi::FromInt(i), | |
| 5469 FixedArray::SKIP_WRITE_BARRIER); | |
| 5470 } | 5471 } |
| 5471 } | 5472 } |
| 5472 counter += str->length(); | 5473 counter += str->length(); |
| 5473 } | 5474 } |
| 5474 } | 5475 } |
| 5475 ASSERT(!storage || storage->length() == counter); | 5476 ASSERT(!storage || storage->length() == counter); |
| 5476 return counter; | 5477 return counter; |
| 5477 } | 5478 } |
| 5478 | 5479 |
| 5479 | 5480 |
| (...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5990 } | 5991 } |
| 5991 | 5992 |
| 5992 | 5993 |
| 5993 Object* Dictionary::GenerateNewEnumerationIndices() { | 5994 Object* Dictionary::GenerateNewEnumerationIndices() { |
| 5994 int length = NumberOfElements(); | 5995 int length = NumberOfElements(); |
| 5995 | 5996 |
| 5996 // Allocate and initialize iteration order array. | 5997 // Allocate and initialize iteration order array. |
| 5997 Object* obj = Heap::AllocateFixedArray(length); | 5998 Object* obj = Heap::AllocateFixedArray(length); |
| 5998 if (obj->IsFailure()) return obj; | 5999 if (obj->IsFailure()) return obj; |
| 5999 FixedArray* iteration_order = FixedArray::cast(obj); | 6000 FixedArray* iteration_order = FixedArray::cast(obj); |
| 6000 for (int i = 0; i < length; i++) iteration_order->set(i, Smi::FromInt(i)); | 6001 for (int i = 0; i < length; i++) { |
| 6002 iteration_order->set(i, Smi::FromInt(i), SKIP_WRITE_BARRIER); |
| 6003 } |
| 6001 | 6004 |
| 6002 // Allocate array with enumeration order. | 6005 // Allocate array with enumeration order. |
| 6003 obj = Heap::AllocateFixedArray(length); | 6006 obj = Heap::AllocateFixedArray(length); |
| 6004 if (obj->IsFailure()) return obj; | 6007 if (obj->IsFailure()) return obj; |
| 6005 FixedArray* enumeration_order = FixedArray::cast(obj); | 6008 FixedArray* enumeration_order = FixedArray::cast(obj); |
| 6006 | 6009 |
| 6007 // Fill the enumeration order array with property details. | 6010 // Fill the enumeration order array with property details. |
| 6008 int capacity = Capacity(); | 6011 int capacity = Capacity(); |
| 6009 int pos = 0; | 6012 int pos = 0; |
| 6010 for (int i = 0; i < capacity; i++) { | 6013 for (int i = 0; i < capacity; i++) { |
| 6011 if (IsKey(KeyAt(i))) { | 6014 if (IsKey(KeyAt(i))) { |
| 6012 enumeration_order->set(pos++, Smi::FromInt(DetailsAt(i).index())); | 6015 enumeration_order->set(pos++, |
| 6016 Smi::FromInt(DetailsAt(i).index()), |
| 6017 SKIP_WRITE_BARRIER); |
| 6013 } | 6018 } |
| 6014 } | 6019 } |
| 6015 | 6020 |
| 6016 // Sort the arrays wrt. enumeration order. | 6021 // Sort the arrays wrt. enumeration order. |
| 6017 iteration_order->SortPairs(enumeration_order); | 6022 iteration_order->SortPairs(enumeration_order); |
| 6018 | 6023 |
| 6019 // Overwrite the enumeration_order with the enumeration indices. | 6024 // Overwrite the enumeration_order with the enumeration indices. |
| 6020 for (int i = 0; i < length; i++) { | 6025 for (int i = 0; i < length; i++) { |
| 6021 int index = Smi::cast(iteration_order->get(i))->value(); | 6026 int index = Smi::cast(iteration_order->get(i))->value(); |
| 6022 int enum_index = PropertyDetails::kInitialIndex + i; | 6027 int enum_index = PropertyDetails::kInitialIndex + i; |
| 6023 enumeration_order->set(index, Smi::FromInt(enum_index)); | 6028 enumeration_order->set(index, |
| 6029 Smi::FromInt(enum_index), |
| 6030 SKIP_WRITE_BARRIER); |
| 6024 } | 6031 } |
| 6025 | 6032 |
| 6026 // Update the dictionary with new indices. | 6033 // Update the dictionary with new indices. |
| 6027 capacity = Capacity(); | 6034 capacity = Capacity(); |
| 6028 pos = 0; | 6035 pos = 0; |
| 6029 for (int i = 0; i < capacity; i++) { | 6036 for (int i = 0; i < capacity; i++) { |
| 6030 if (IsKey(KeyAt(i))) { | 6037 if (IsKey(KeyAt(i))) { |
| 6031 int enum_index = Smi::cast(enumeration_order->get(pos++))->value(); | 6038 int enum_index = Smi::cast(enumeration_order->get(pos++))->value(); |
| 6032 PropertyDetails details = DetailsAt(i); | 6039 PropertyDetails details = DetailsAt(i); |
| 6033 PropertyDetails new_details = | 6040 PropertyDetails new_details = |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6151 } | 6158 } |
| 6152 | 6159 |
| 6153 | 6160 |
| 6154 void Dictionary::UpdateMaxNumberKey(uint32_t key) { | 6161 void Dictionary::UpdateMaxNumberKey(uint32_t key) { |
| 6155 // If the dictionary requires slow elements an element has already | 6162 // If the dictionary requires slow elements an element has already |
| 6156 // been added at a high index. | 6163 // been added at a high index. |
| 6157 if (requires_slow_elements()) return; | 6164 if (requires_slow_elements()) return; |
| 6158 // Check if this index is high enough that we should require slow | 6165 // Check if this index is high enough that we should require slow |
| 6159 // elements. | 6166 // elements. |
| 6160 if (key > kRequiresSlowElementsLimit) { | 6167 if (key > kRequiresSlowElementsLimit) { |
| 6161 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask)); | 6168 set(kMaxNumberKeyIndex, |
| 6169 Smi::FromInt(kRequiresSlowElementsMask), |
| 6170 SKIP_WRITE_BARRIER); |
| 6162 return; | 6171 return; |
| 6163 } | 6172 } |
| 6164 // Update max key value. | 6173 // Update max key value. |
| 6165 Object* max_index_object = get(kMaxNumberKeyIndex); | 6174 Object* max_index_object = get(kMaxNumberKeyIndex); |
| 6166 if (!max_index_object->IsSmi() || max_number_key() < key) { | 6175 if (!max_index_object->IsSmi() || max_number_key() < key) { |
| 6167 set(kMaxNumberKeyIndex, Smi::FromInt(key << kRequiresSlowElementsTagSize)); | 6176 set(kMaxNumberKeyIndex, |
| 6177 Smi::FromInt(key << kRequiresSlowElementsTagSize), |
| 6178 SKIP_WRITE_BARRIER); |
| 6168 } | 6179 } |
| 6169 } | 6180 } |
| 6170 | 6181 |
| 6171 | 6182 |
| 6172 Object* Dictionary::AddStringEntry(String* key, | 6183 Object* Dictionary::AddStringEntry(String* key, |
| 6173 Object* value, | 6184 Object* value, |
| 6174 PropertyDetails details) { | 6185 PropertyDetails details) { |
| 6175 StringKey k(key); | 6186 StringKey k(key); |
| 6176 SLOW_ASSERT(FindEntry(&k) == -1); | 6187 SLOW_ASSERT(FindEntry(&k) == -1); |
| 6177 return Add(&k, value, details); | 6188 return Add(&k, value, details); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6254 void Dictionary::CopyEnumKeysTo(FixedArray* storage, FixedArray* sort_array) { | 6265 void Dictionary::CopyEnumKeysTo(FixedArray* storage, FixedArray* sort_array) { |
| 6255 ASSERT(storage->length() >= NumberOfEnumElements()); | 6266 ASSERT(storage->length() >= NumberOfEnumElements()); |
| 6256 int capacity = Capacity(); | 6267 int capacity = Capacity(); |
| 6257 int index = 0; | 6268 int index = 0; |
| 6258 for (int i = 0; i < capacity; i++) { | 6269 for (int i = 0; i < capacity; i++) { |
| 6259 Object* k = KeyAt(i); | 6270 Object* k = KeyAt(i); |
| 6260 if (IsKey(k)) { | 6271 if (IsKey(k)) { |
| 6261 PropertyDetails details = DetailsAt(i); | 6272 PropertyDetails details = DetailsAt(i); |
| 6262 if (!details.IsDontEnum()) { | 6273 if (!details.IsDontEnum()) { |
| 6263 storage->set(index, k); | 6274 storage->set(index, k); |
| 6264 sort_array->set(index, Smi::FromInt(details.index())); | 6275 sort_array->set(index, |
| 6276 Smi::FromInt(details.index()), |
| 6277 SKIP_WRITE_BARRIER); |
| 6265 index++; | 6278 index++; |
| 6266 } | 6279 } |
| 6267 } | 6280 } |
| 6268 } | 6281 } |
| 6269 storage->SortPairs(sort_array); | 6282 storage->SortPairs(sort_array); |
| 6270 ASSERT(storage->length() >= index); | 6283 ASSERT(storage->length() >= index); |
| 6271 } | 6284 } |
| 6272 | 6285 |
| 6273 | 6286 |
| 6274 void Dictionary::CopyKeysTo(FixedArray* storage) { | 6287 void Dictionary::CopyKeysTo(FixedArray* storage) { |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6639 // No break point. | 6652 // No break point. |
| 6640 if (break_point_objects()->IsUndefined()) return 0; | 6653 if (break_point_objects()->IsUndefined()) return 0; |
| 6641 // Single beak point. | 6654 // Single beak point. |
| 6642 if (!break_point_objects()->IsFixedArray()) return 1; | 6655 if (!break_point_objects()->IsFixedArray()) return 1; |
| 6643 // Multiple break points. | 6656 // Multiple break points. |
| 6644 return FixedArray::cast(break_point_objects())->length(); | 6657 return FixedArray::cast(break_point_objects())->length(); |
| 6645 } | 6658 } |
| 6646 | 6659 |
| 6647 | 6660 |
| 6648 } } // namespace v8::internal | 6661 } } // namespace v8::internal |
| OLD | NEW |