Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 9677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9688 // JSObject::kMaxElementCount. | 9688 // JSObject::kMaxElementCount. |
| 9689 uint32_t index_offset_; | 9689 uint32_t index_offset_; |
| 9690 bool fast_elements_; | 9690 bool fast_elements_; |
| 9691 }; | 9691 }; |
| 9692 | 9692 |
| 9693 | 9693 |
| 9694 static uint32_t EstimateElementCount(Handle<JSArray> array) { | 9694 static uint32_t EstimateElementCount(Handle<JSArray> array) { |
| 9695 uint32_t length = static_cast<uint32_t>(array->length()->Number()); | 9695 uint32_t length = static_cast<uint32_t>(array->length()->Number()); |
| 9696 int element_count = 0; | 9696 int element_count = 0; |
| 9697 switch (array->GetElementsKind()) { | 9697 switch (array->GetElementsKind()) { |
| 9698 case FAST_SMI_ONLY_ELEMENTS: | |
|
danno
2011/11/04 10:02:04
Add all of the other elements kinds explicitly to
| |
| 9698 case FAST_ELEMENTS: { | 9699 case FAST_ELEMENTS: { |
| 9699 // Fast elements can't have lengths that are not representable by | 9700 // Fast elements can't have lengths that are not representable by |
| 9700 // a 32-bit signed integer. | 9701 // a 32-bit signed integer. |
| 9701 ASSERT(static_cast<int32_t>(FixedArray::kMaxLength) >= 0); | 9702 ASSERT(static_cast<int32_t>(FixedArray::kMaxLength) >= 0); |
| 9702 int fast_length = static_cast<int>(length); | 9703 int fast_length = static_cast<int>(length); |
| 9703 Handle<FixedArray> elements(FixedArray::cast(array->elements())); | 9704 Handle<FixedArray> elements(FixedArray::cast(array->elements())); |
| 9704 for (int i = 0; i < fast_length; i++) { | 9705 for (int i = 0; i < fast_length; i++) { |
| 9705 if (!elements->get(i)->IsTheHole()) element_count++; | 9706 if (!elements->get(i)->IsTheHole()) element_count++; |
| 9706 } | 9707 } |
| 9707 break; | 9708 break; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9789 Handle<FixedArray> elements(FixedArray::cast(object->elements())); | 9790 Handle<FixedArray> elements(FixedArray::cast(object->elements())); |
| 9790 uint32_t length = static_cast<uint32_t>(elements->length()); | 9791 uint32_t length = static_cast<uint32_t>(elements->length()); |
| 9791 if (range < length) length = range; | 9792 if (range < length) length = range; |
| 9792 for (uint32_t i = 0; i < length; i++) { | 9793 for (uint32_t i = 0; i < length; i++) { |
| 9793 if (!elements->get(i)->IsTheHole()) { | 9794 if (!elements->get(i)->IsTheHole()) { |
| 9794 indices->Add(i); | 9795 indices->Add(i); |
| 9795 } | 9796 } |
| 9796 } | 9797 } |
| 9797 break; | 9798 break; |
| 9798 } | 9799 } |
| 9800 case FAST_DOUBLE_ELEMENTS: { | |
| 9801 // TODO(1810): Decide if it's worthwhile to implement this. | |
| 9802 UNREACHABLE(); | |
| 9803 break; | |
| 9804 } | |
| 9799 case DICTIONARY_ELEMENTS: { | 9805 case DICTIONARY_ELEMENTS: { |
| 9800 Handle<NumberDictionary> dict(NumberDictionary::cast(object->elements())); | 9806 Handle<NumberDictionary> dict(NumberDictionary::cast(object->elements())); |
| 9801 uint32_t capacity = dict->Capacity(); | 9807 uint32_t capacity = dict->Capacity(); |
| 9802 for (uint32_t j = 0; j < capacity; j++) { | 9808 for (uint32_t j = 0; j < capacity; j++) { |
| 9803 HandleScope loop_scope; | 9809 HandleScope loop_scope; |
| 9804 Handle<Object> k(dict->KeyAt(j)); | 9810 Handle<Object> k(dict->KeyAt(j)); |
| 9805 if (dict->IsKey(*k)) { | 9811 if (dict->IsKey(*k)) { |
| 9806 ASSERT(k->IsNumber()); | 9812 ASSERT(k->IsNumber()); |
| 9807 uint32_t index = static_cast<uint32_t>(k->Number()); | 9813 uint32_t index = static_cast<uint32_t>(k->Number()); |
| 9808 if (index < range) { | 9814 if (index < range) { |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9919 } else if (receiver->HasElement(j)) { | 9925 } else if (receiver->HasElement(j)) { |
| 9920 // Call GetElement on receiver, not its prototype, or getters won't | 9926 // Call GetElement on receiver, not its prototype, or getters won't |
| 9921 // have the correct receiver. | 9927 // have the correct receiver. |
| 9922 element_value = Object::GetElement(receiver, j); | 9928 element_value = Object::GetElement(receiver, j); |
| 9923 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false); | 9929 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false); |
| 9924 visitor->visit(j, element_value); | 9930 visitor->visit(j, element_value); |
| 9925 } | 9931 } |
| 9926 } | 9932 } |
| 9927 break; | 9933 break; |
| 9928 } | 9934 } |
| 9935 case FAST_DOUBLE_ELEMENTS: { | |
| 9936 // TODO(1810): Decide if it's worthwhile to implement this. | |
| 9937 UNREACHABLE(); | |
| 9938 break; | |
| 9939 } | |
| 9929 case DICTIONARY_ELEMENTS: { | 9940 case DICTIONARY_ELEMENTS: { |
| 9930 Handle<NumberDictionary> dict(receiver->element_dictionary()); | 9941 Handle<NumberDictionary> dict(receiver->element_dictionary()); |
| 9931 List<uint32_t> indices(dict->Capacity() / 2); | 9942 List<uint32_t> indices(dict->Capacity() / 2); |
| 9932 // Collect all indices in the object and the prototypes less | 9943 // Collect all indices in the object and the prototypes less |
| 9933 // than length. This might introduce duplicates in the indices list. | 9944 // than length. This might introduce duplicates in the indices list. |
| 9934 CollectElementIndices(receiver, length, &indices); | 9945 CollectElementIndices(receiver, length, &indices); |
| 9935 indices.Sort(&compareUInt32); | 9946 indices.Sort(&compareUInt32); |
| 9936 int j = 0; | 9947 int j = 0; |
| 9937 int n = indices.length(); | 9948 int n = indices.length(); |
| 9938 while (j < n) { | 9949 while (j < n) { |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10029 uint32_t estimate_result_length = 0; | 10040 uint32_t estimate_result_length = 0; |
| 10030 uint32_t estimate_nof_elements = 0; | 10041 uint32_t estimate_nof_elements = 0; |
| 10031 { | 10042 { |
| 10032 for (int i = 0; i < argument_count; i++) { | 10043 for (int i = 0; i < argument_count; i++) { |
| 10033 HandleScope loop_scope; | 10044 HandleScope loop_scope; |
| 10034 Handle<Object> obj(elements->get(i)); | 10045 Handle<Object> obj(elements->get(i)); |
| 10035 uint32_t length_estimate; | 10046 uint32_t length_estimate; |
| 10036 uint32_t element_estimate; | 10047 uint32_t element_estimate; |
| 10037 if (obj->IsJSArray()) { | 10048 if (obj->IsJSArray()) { |
| 10038 Handle<JSArray> array(Handle<JSArray>::cast(obj)); | 10049 Handle<JSArray> array(Handle<JSArray>::cast(obj)); |
| 10050 // TODO(1810): Find out if it's worthwhile to properly support | |
| 10051 // arbitrary ElementsKinds. For now, pessimistically transition to | |
| 10052 // FAST_ELEMENTS. | |
| 10053 if (array->HasFastDoubleElements()) { | |
| 10054 array = Handle<JSArray>::cast( | |
| 10055 TransitionElementsKind(array, FAST_ELEMENTS)); | |
| 10056 } | |
| 10039 length_estimate = | 10057 length_estimate = |
| 10040 static_cast<uint32_t>(array->length()->Number()); | 10058 static_cast<uint32_t>(array->length()->Number()); |
| 10041 element_estimate = | 10059 element_estimate = |
| 10042 EstimateElementCount(array); | 10060 EstimateElementCount(array); |
| 10043 } else { | 10061 } else { |
| 10044 length_estimate = 1; | 10062 length_estimate = 1; |
| 10045 element_estimate = 1; | 10063 element_estimate = 1; |
| 10046 } | 10064 } |
| 10047 // Avoid overflows by capping at kMaxElementCount. | 10065 // Avoid overflows by capping at kMaxElementCount. |
| 10048 if (JSObject::kMaxElementCount - estimate_result_length < | 10066 if (JSObject::kMaxElementCount - estimate_result_length < |
| (...skipping 3469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13518 } else { | 13536 } else { |
| 13519 // Handle last resort GC and make sure to allow future allocations | 13537 // Handle last resort GC and make sure to allow future allocations |
| 13520 // to grow the heap without causing GCs (if possible). | 13538 // to grow the heap without causing GCs (if possible). |
| 13521 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13539 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 13522 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); | 13540 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 13523 } | 13541 } |
| 13524 } | 13542 } |
| 13525 | 13543 |
| 13526 | 13544 |
| 13527 } } // namespace v8::internal | 13545 } } // namespace v8::internal |
| OLD | NEW |