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 |