OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 js_object); | 221 js_object); |
222 if (!maybe_result->ToObject(&result)) return maybe_result; | 222 if (!maybe_result->ToObject(&result)) return maybe_result; |
223 } | 223 } |
224 elements->set(i, result); | 224 elements->set(i, result); |
225 } | 225 } |
226 } | 226 } |
227 } | 227 } |
228 break; | 228 break; |
229 } | 229 } |
230 case DICTIONARY_ELEMENTS: { | 230 case DICTIONARY_ELEMENTS: { |
231 NumberDictionary* element_dictionary = copy->element_dictionary(); | 231 SeededNumberDictionary* element_dictionary = copy->element_dictionary(); |
232 int capacity = element_dictionary->Capacity(); | 232 int capacity = element_dictionary->Capacity(); |
233 for (int i = 0; i < capacity; i++) { | 233 for (int i = 0; i < capacity; i++) { |
234 Object* k = element_dictionary->KeyAt(i); | 234 Object* k = element_dictionary->KeyAt(i); |
235 if (element_dictionary->IsKey(k)) { | 235 if (element_dictionary->IsKey(k)) { |
236 Object* value = element_dictionary->ValueAt(i); | 236 Object* value = element_dictionary->ValueAt(i); |
237 if (value->IsJSObject()) { | 237 if (value->IsJSObject()) { |
238 JSObject* js_object = JSObject::cast(value); | 238 JSObject* js_object = JSObject::cast(value); |
239 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, | 239 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, |
240 js_object); | 240 js_object); |
241 if (!maybe_result->ToObject(&result)) return maybe_result; | 241 if (!maybe_result->ToObject(&result)) return maybe_result; |
(...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1037 | 1037 |
1038 case JSObject::DICTIONARY_ELEMENT: { | 1038 case JSObject::DICTIONARY_ELEMENT: { |
1039 Handle<JSObject> holder = obj; | 1039 Handle<JSObject> holder = obj; |
1040 if (obj->IsJSGlobalProxy()) { | 1040 if (obj->IsJSGlobalProxy()) { |
1041 Object* proto = obj->GetPrototype(); | 1041 Object* proto = obj->GetPrototype(); |
1042 if (proto->IsNull()) return heap->undefined_value(); | 1042 if (proto->IsNull()) return heap->undefined_value(); |
1043 ASSERT(proto->IsJSGlobalObject()); | 1043 ASSERT(proto->IsJSGlobalObject()); |
1044 holder = Handle<JSObject>(JSObject::cast(proto)); | 1044 holder = Handle<JSObject>(JSObject::cast(proto)); |
1045 } | 1045 } |
1046 FixedArray* elements = FixedArray::cast(holder->elements()); | 1046 FixedArray* elements = FixedArray::cast(holder->elements()); |
1047 NumberDictionary* dictionary = NULL; | 1047 SeededNumberDictionary* dictionary = NULL; |
1048 if (elements->map() == heap->non_strict_arguments_elements_map()) { | 1048 if (elements->map() == heap->non_strict_arguments_elements_map()) { |
1049 dictionary = NumberDictionary::cast(elements->get(1)); | 1049 dictionary = SeededNumberDictionary::cast(elements->get(1)); |
1050 } else { | 1050 } else { |
1051 dictionary = NumberDictionary::cast(elements); | 1051 dictionary = SeededNumberDictionary::cast(elements); |
1052 } | 1052 } |
1053 int entry = dictionary->FindEntry(index); | 1053 int entry = dictionary->FindEntry(index); |
1054 ASSERT(entry != NumberDictionary::kNotFound); | 1054 ASSERT(entry != SeededNumberDictionary::kNotFound); |
1055 PropertyDetails details = dictionary->DetailsAt(entry); | 1055 PropertyDetails details = dictionary->DetailsAt(entry); |
1056 switch (details.type()) { | 1056 switch (details.type()) { |
1057 case CALLBACKS: { | 1057 case CALLBACKS: { |
1058 // This is an accessor property with getter and/or setter. | 1058 // This is an accessor property with getter and/or setter. |
1059 AccessorPair* accessors = | 1059 AccessorPair* accessors = |
1060 AccessorPair::cast(dictionary->ValueAt(entry)); | 1060 AccessorPair::cast(dictionary->ValueAt(entry)); |
1061 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); | 1061 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); |
1062 if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) { | 1062 if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) { |
1063 elms->set(GETTER_INDEX, accessors->getter()); | 1063 elms->set(GETTER_INDEX, accessors->getter()); |
1064 } | 1064 } |
(...skipping 3228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4293 // Don't allow element properties to be redefined on objects with external | 4293 // Don't allow element properties to be redefined on objects with external |
4294 // array elements. | 4294 // array elements. |
4295 if (js_object->HasExternalArrayElements()) { | 4295 if (js_object->HasExternalArrayElements()) { |
4296 Handle<Object> args[2] = { js_object, name }; | 4296 Handle<Object> args[2] = { js_object, name }; |
4297 Handle<Object> error = | 4297 Handle<Object> error = |
4298 isolate->factory()->NewTypeError("redef_external_array_element", | 4298 isolate->factory()->NewTypeError("redef_external_array_element", |
4299 HandleVector(args, 2)); | 4299 HandleVector(args, 2)); |
4300 return isolate->Throw(*error); | 4300 return isolate->Throw(*error); |
4301 } | 4301 } |
4302 | 4302 |
4303 Handle<NumberDictionary> dictionary = | 4303 Handle<SeededNumberDictionary> dictionary = |
4304 JSObject::NormalizeElements(js_object); | 4304 JSObject::NormalizeElements(js_object); |
4305 // Make sure that we never go back to fast case. | 4305 // Make sure that we never go back to fast case. |
4306 dictionary->set_requires_slow_elements(); | 4306 dictionary->set_requires_slow_elements(); |
4307 PropertyDetails details = PropertyDetails(attr, NORMAL); | 4307 PropertyDetails details = PropertyDetails(attr, NORMAL); |
4308 Handle<NumberDictionary> extended_dictionary = | 4308 Handle<SeededNumberDictionary> extended_dictionary = |
4309 NumberDictionary::Set(dictionary, index, obj_value, details); | 4309 SeededNumberDictionary::Set(dictionary, index, obj_value, details); |
4310 if (*extended_dictionary != *dictionary) { | 4310 if (*extended_dictionary != *dictionary) { |
4311 if (js_object->GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS) { | 4311 if (js_object->GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS) { |
4312 FixedArray::cast(js_object->elements())->set(1, *extended_dictionary); | 4312 FixedArray::cast(js_object->elements())->set(1, *extended_dictionary); |
4313 } else { | 4313 } else { |
4314 js_object->set_elements(*extended_dictionary); | 4314 js_object->set_elements(*extended_dictionary); |
4315 } | 4315 } |
4316 } | 4316 } |
4317 return *obj_value; | 4317 return *obj_value; |
4318 } | 4318 } |
4319 | 4319 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4374 | 4374 |
4375 // Special case for elements if any of the flags are true. | 4375 // Special case for elements if any of the flags are true. |
4376 // If elements are in fast case we always implicitly assume that: | 4376 // If elements are in fast case we always implicitly assume that: |
4377 // DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false. | 4377 // DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false. |
4378 static MaybeObject* NormalizeObjectSetElement(Isolate* isolate, | 4378 static MaybeObject* NormalizeObjectSetElement(Isolate* isolate, |
4379 Handle<JSObject> js_object, | 4379 Handle<JSObject> js_object, |
4380 uint32_t index, | 4380 uint32_t index, |
4381 Handle<Object> value, | 4381 Handle<Object> value, |
4382 PropertyAttributes attr) { | 4382 PropertyAttributes attr) { |
4383 // Normalize the elements to enable attributes on the property. | 4383 // Normalize the elements to enable attributes on the property. |
4384 Handle<NumberDictionary> dictionary = JSObject::NormalizeElements(js_object); | 4384 Handle<SeededNumberDictionary> dictionary = |
| 4385 JSObject::NormalizeElements(js_object); |
4385 // Make sure that we never go back to fast case. | 4386 // Make sure that we never go back to fast case. |
4386 dictionary->set_requires_slow_elements(); | 4387 dictionary->set_requires_slow_elements(); |
4387 PropertyDetails details = PropertyDetails(attr, NORMAL); | 4388 PropertyDetails details = PropertyDetails(attr, NORMAL); |
4388 Handle<NumberDictionary> extended_dictionary = | 4389 Handle<SeededNumberDictionary> extended_dictionary = |
4389 NumberDictionary::Set(dictionary, index, value, details); | 4390 SeededNumberDictionary::Set(dictionary, index, value, details); |
4390 if (*extended_dictionary != *dictionary) { | 4391 if (*extended_dictionary != *dictionary) { |
4391 js_object->set_elements(*extended_dictionary); | 4392 js_object->set_elements(*extended_dictionary); |
4392 } | 4393 } |
4393 return *value; | 4394 return *value; |
4394 } | 4395 } |
4395 | 4396 |
4396 | 4397 |
4397 MaybeObject* Runtime::SetObjectProperty(Isolate* isolate, | 4398 MaybeObject* Runtime::SetObjectProperty(Isolate* isolate, |
4398 Handle<Object> object, | 4399 Handle<Object> object, |
4399 Handle<Object> key, | 4400 Handle<Object> key, |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4808 case JSObject::DICTIONARY_ELEMENT: { | 4809 case JSObject::DICTIONARY_ELEMENT: { |
4809 if (object->IsJSGlobalProxy()) { | 4810 if (object->IsJSGlobalProxy()) { |
4810 Object* proto = object->GetPrototype(); | 4811 Object* proto = object->GetPrototype(); |
4811 if (proto->IsNull()) { | 4812 if (proto->IsNull()) { |
4812 return isolate->heap()->false_value(); | 4813 return isolate->heap()->false_value(); |
4813 } | 4814 } |
4814 ASSERT(proto->IsJSGlobalObject()); | 4815 ASSERT(proto->IsJSGlobalObject()); |
4815 object = JSObject::cast(proto); | 4816 object = JSObject::cast(proto); |
4816 } | 4817 } |
4817 FixedArray* elements = FixedArray::cast(object->elements()); | 4818 FixedArray* elements = FixedArray::cast(object->elements()); |
4818 NumberDictionary* dictionary = NULL; | 4819 SeededNumberDictionary* dictionary = NULL; |
4819 if (elements->map() == | 4820 if (elements->map() == |
4820 isolate->heap()->non_strict_arguments_elements_map()) { | 4821 isolate->heap()->non_strict_arguments_elements_map()) { |
4821 dictionary = NumberDictionary::cast(elements->get(1)); | 4822 dictionary = SeededNumberDictionary::cast(elements->get(1)); |
4822 } else { | 4823 } else { |
4823 dictionary = NumberDictionary::cast(elements); | 4824 dictionary = SeededNumberDictionary::cast(elements); |
4824 } | 4825 } |
4825 int entry = dictionary->FindEntry(index); | 4826 int entry = dictionary->FindEntry(index); |
4826 ASSERT(entry != NumberDictionary::kNotFound); | 4827 ASSERT(entry != SeededNumberDictionary::kNotFound); |
4827 PropertyDetails details = dictionary->DetailsAt(entry); | 4828 PropertyDetails details = dictionary->DetailsAt(entry); |
4828 return isolate->heap()->ToBoolean(!details.IsDontEnum()); | 4829 return isolate->heap()->ToBoolean(!details.IsDontEnum()); |
4829 } | 4830 } |
4830 } | 4831 } |
4831 } | 4832 } |
4832 | 4833 |
4833 PropertyAttributes att = object->GetLocalPropertyAttribute(key); | 4834 PropertyAttributes att = object->GetLocalPropertyAttribute(key); |
4834 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); | 4835 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); |
4835 } | 4836 } |
4836 | 4837 |
(...skipping 4738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9575 return; | 9576 return; |
9576 } | 9577 } |
9577 // Our initial estimate of length was foiled, possibly by | 9578 // Our initial estimate of length was foiled, possibly by |
9578 // getters on the arrays increasing the length of later arrays | 9579 // getters on the arrays increasing the length of later arrays |
9579 // during iteration. | 9580 // during iteration. |
9580 // This shouldn't happen in anything but pathological cases. | 9581 // This shouldn't happen in anything but pathological cases. |
9581 SetDictionaryMode(index); | 9582 SetDictionaryMode(index); |
9582 // Fall-through to dictionary mode. | 9583 // Fall-through to dictionary mode. |
9583 } | 9584 } |
9584 ASSERT(!fast_elements_); | 9585 ASSERT(!fast_elements_); |
9585 Handle<NumberDictionary> dict(NumberDictionary::cast(*storage_)); | 9586 Handle<SeededNumberDictionary> dict( |
9586 Handle<NumberDictionary> result = | 9587 SeededNumberDictionary::cast(*storage_)); |
| 9588 Handle<SeededNumberDictionary> result = |
9587 isolate_->factory()->DictionaryAtNumberPut(dict, index, elm); | 9589 isolate_->factory()->DictionaryAtNumberPut(dict, index, elm); |
9588 if (!result.is_identical_to(dict)) { | 9590 if (!result.is_identical_to(dict)) { |
9589 // Dictionary needed to grow. | 9591 // Dictionary needed to grow. |
9590 clear_storage(); | 9592 clear_storage(); |
9591 set_storage(*result); | 9593 set_storage(*result); |
9592 } | 9594 } |
9593 } | 9595 } |
9594 | 9596 |
9595 void increase_index_offset(uint32_t delta) { | 9597 void increase_index_offset(uint32_t delta) { |
9596 if (JSObject::kMaxElementCount - index_offset_ < delta) { | 9598 if (JSObject::kMaxElementCount - index_offset_ < delta) { |
(...skipping 19 matching lines...) Expand all Loading... |
9616 array->set_length(*length); | 9618 array->set_length(*length); |
9617 array->set_elements(*storage_); | 9619 array->set_elements(*storage_); |
9618 return array; | 9620 return array; |
9619 } | 9621 } |
9620 | 9622 |
9621 private: | 9623 private: |
9622 // Convert storage to dictionary mode. | 9624 // Convert storage to dictionary mode. |
9623 void SetDictionaryMode(uint32_t index) { | 9625 void SetDictionaryMode(uint32_t index) { |
9624 ASSERT(fast_elements_); | 9626 ASSERT(fast_elements_); |
9625 Handle<FixedArray> current_storage(*storage_); | 9627 Handle<FixedArray> current_storage(*storage_); |
9626 Handle<NumberDictionary> slow_storage( | 9628 Handle<SeededNumberDictionary> slow_storage( |
9627 isolate_->factory()->NewNumberDictionary(current_storage->length())); | 9629 isolate_->factory()->NewSeededNumberDictionary( |
| 9630 current_storage->length())); |
9628 uint32_t current_length = static_cast<uint32_t>(current_storage->length()); | 9631 uint32_t current_length = static_cast<uint32_t>(current_storage->length()); |
9629 for (uint32_t i = 0; i < current_length; i++) { | 9632 for (uint32_t i = 0; i < current_length; i++) { |
9630 HandleScope loop_scope; | 9633 HandleScope loop_scope; |
9631 Handle<Object> element(current_storage->get(i)); | 9634 Handle<Object> element(current_storage->get(i)); |
9632 if (!element->IsTheHole()) { | 9635 if (!element->IsTheHole()) { |
9633 Handle<NumberDictionary> new_storage = | 9636 Handle<SeededNumberDictionary> new_storage = |
9634 isolate_->factory()->DictionaryAtNumberPut(slow_storage, i, element); | 9637 isolate_->factory()->DictionaryAtNumberPut(slow_storage, i, element); |
9635 if (!new_storage.is_identical_to(slow_storage)) { | 9638 if (!new_storage.is_identical_to(slow_storage)) { |
9636 slow_storage = loop_scope.CloseAndEscape(new_storage); | 9639 slow_storage = loop_scope.CloseAndEscape(new_storage); |
9637 } | 9640 } |
9638 } | 9641 } |
9639 } | 9642 } |
9640 clear_storage(); | 9643 clear_storage(); |
9641 set_storage(*slow_storage); | 9644 set_storage(*slow_storage); |
9642 fast_elements_ = false; | 9645 fast_elements_ = false; |
9643 } | 9646 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9675 for (int i = 0; i < fast_length; i++) { | 9678 for (int i = 0; i < fast_length; i++) { |
9676 if (!elements->get(i)->IsTheHole()) element_count++; | 9679 if (!elements->get(i)->IsTheHole()) element_count++; |
9677 } | 9680 } |
9678 break; | 9681 break; |
9679 } | 9682 } |
9680 case FAST_DOUBLE_ELEMENTS: | 9683 case FAST_DOUBLE_ELEMENTS: |
9681 // TODO(1810): Decide if it's worthwhile to implement this. | 9684 // TODO(1810): Decide if it's worthwhile to implement this. |
9682 UNREACHABLE(); | 9685 UNREACHABLE(); |
9683 break; | 9686 break; |
9684 case DICTIONARY_ELEMENTS: { | 9687 case DICTIONARY_ELEMENTS: { |
9685 Handle<NumberDictionary> dictionary( | 9688 Handle<SeededNumberDictionary> dictionary( |
9686 NumberDictionary::cast(array->elements())); | 9689 SeededNumberDictionary::cast(array->elements())); |
9687 int capacity = dictionary->Capacity(); | 9690 int capacity = dictionary->Capacity(); |
9688 for (int i = 0; i < capacity; i++) { | 9691 for (int i = 0; i < capacity; i++) { |
9689 Handle<Object> key(dictionary->KeyAt(i)); | 9692 Handle<Object> key(dictionary->KeyAt(i)); |
9690 if (dictionary->IsKey(*key)) { | 9693 if (dictionary->IsKey(*key)) { |
9691 element_count++; | 9694 element_count++; |
9692 } | 9695 } |
9693 } | 9696 } |
9694 break; | 9697 break; |
9695 } | 9698 } |
9696 case NON_STRICT_ARGUMENTS_ELEMENTS: | 9699 case NON_STRICT_ARGUMENTS_ELEMENTS: |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9779 } | 9782 } |
9780 } | 9783 } |
9781 break; | 9784 break; |
9782 } | 9785 } |
9783 case FAST_DOUBLE_ELEMENTS: { | 9786 case FAST_DOUBLE_ELEMENTS: { |
9784 // TODO(1810): Decide if it's worthwhile to implement this. | 9787 // TODO(1810): Decide if it's worthwhile to implement this. |
9785 UNREACHABLE(); | 9788 UNREACHABLE(); |
9786 break; | 9789 break; |
9787 } | 9790 } |
9788 case DICTIONARY_ELEMENTS: { | 9791 case DICTIONARY_ELEMENTS: { |
9789 Handle<NumberDictionary> dict(NumberDictionary::cast(object->elements())); | 9792 Handle<SeededNumberDictionary> dict( |
| 9793 SeededNumberDictionary::cast(object->elements())); |
9790 uint32_t capacity = dict->Capacity(); | 9794 uint32_t capacity = dict->Capacity(); |
9791 for (uint32_t j = 0; j < capacity; j++) { | 9795 for (uint32_t j = 0; j < capacity; j++) { |
9792 HandleScope loop_scope; | 9796 HandleScope loop_scope; |
9793 Handle<Object> k(dict->KeyAt(j)); | 9797 Handle<Object> k(dict->KeyAt(j)); |
9794 if (dict->IsKey(*k)) { | 9798 if (dict->IsKey(*k)) { |
9795 ASSERT(k->IsNumber()); | 9799 ASSERT(k->IsNumber()); |
9796 uint32_t index = static_cast<uint32_t>(k->Number()); | 9800 uint32_t index = static_cast<uint32_t>(k->Number()); |
9797 if (index < range) { | 9801 if (index < range) { |
9798 indices->Add(index); | 9802 indices->Add(index); |
9799 } | 9803 } |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9914 } | 9918 } |
9915 } | 9919 } |
9916 break; | 9920 break; |
9917 } | 9921 } |
9918 case FAST_DOUBLE_ELEMENTS: { | 9922 case FAST_DOUBLE_ELEMENTS: { |
9919 // TODO(1810): Decide if it's worthwhile to implement this. | 9923 // TODO(1810): Decide if it's worthwhile to implement this. |
9920 UNREACHABLE(); | 9924 UNREACHABLE(); |
9921 break; | 9925 break; |
9922 } | 9926 } |
9923 case DICTIONARY_ELEMENTS: { | 9927 case DICTIONARY_ELEMENTS: { |
9924 Handle<NumberDictionary> dict(receiver->element_dictionary()); | 9928 Handle<SeededNumberDictionary> dict(receiver->element_dictionary()); |
9925 List<uint32_t> indices(dict->Capacity() / 2); | 9929 List<uint32_t> indices(dict->Capacity() / 2); |
9926 // Collect all indices in the object and the prototypes less | 9930 // Collect all indices in the object and the prototypes less |
9927 // than length. This might introduce duplicates in the indices list. | 9931 // than length. This might introduce duplicates in the indices list. |
9928 CollectElementIndices(receiver, length, &indices); | 9932 CollectElementIndices(receiver, length, &indices); |
9929 indices.Sort(&compareUInt32); | 9933 indices.Sort(&compareUInt32); |
9930 int j = 0; | 9934 int j = 0; |
9931 int n = indices.length(); | 9935 int n = indices.length(); |
9932 while (j < n) { | 9936 while (j < n) { |
9933 HandleScope loop_scope; | 9937 HandleScope loop_scope; |
9934 uint32_t index = indices[j]; | 9938 uint32_t index = indices[j]; |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10070 if (fast_case) { | 10074 if (fast_case) { |
10071 // The backing storage array must have non-existing elements to | 10075 // The backing storage array must have non-existing elements to |
10072 // preserve holes across concat operations. | 10076 // preserve holes across concat operations. |
10073 storage = isolate->factory()->NewFixedArrayWithHoles( | 10077 storage = isolate->factory()->NewFixedArrayWithHoles( |
10074 estimate_result_length); | 10078 estimate_result_length); |
10075 } else { | 10079 } else { |
10076 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate | 10080 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate |
10077 uint32_t at_least_space_for = estimate_nof_elements + | 10081 uint32_t at_least_space_for = estimate_nof_elements + |
10078 (estimate_nof_elements >> 2); | 10082 (estimate_nof_elements >> 2); |
10079 storage = Handle<FixedArray>::cast( | 10083 storage = Handle<FixedArray>::cast( |
10080 isolate->factory()->NewNumberDictionary(at_least_space_for)); | 10084 isolate->factory()->NewSeededNumberDictionary(at_least_space_for)); |
10081 } | 10085 } |
10082 | 10086 |
10083 ArrayConcatVisitor visitor(isolate, storage, fast_case); | 10087 ArrayConcatVisitor visitor(isolate, storage, fast_case); |
10084 | 10088 |
10085 for (int i = 0; i < argument_count; i++) { | 10089 for (int i = 0; i < argument_count; i++) { |
10086 Handle<Object> obj(elements->get(i)); | 10090 Handle<Object> obj(elements->get(i)); |
10087 if (obj->IsJSArray()) { | 10091 if (obj->IsJSArray()) { |
10088 Handle<JSArray> array = Handle<JSArray>::cast(obj); | 10092 Handle<JSArray> array = Handle<JSArray>::cast(obj); |
10089 if (!IterateElements(isolate, array, &visitor)) { | 10093 if (!IterateElements(isolate, array, &visitor)) { |
10090 return Failure::Exception(); | 10094 return Failure::Exception(); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10158 return to; | 10162 return to; |
10159 } | 10163 } |
10160 | 10164 |
10161 | 10165 |
10162 // How many elements does this object/array have? | 10166 // How many elements does this object/array have? |
10163 RUNTIME_FUNCTION(MaybeObject*, Runtime_EstimateNumberOfElements) { | 10167 RUNTIME_FUNCTION(MaybeObject*, Runtime_EstimateNumberOfElements) { |
10164 ASSERT(args.length() == 1); | 10168 ASSERT(args.length() == 1); |
10165 CONVERT_CHECKED(JSObject, object, args[0]); | 10169 CONVERT_CHECKED(JSObject, object, args[0]); |
10166 HeapObject* elements = object->elements(); | 10170 HeapObject* elements = object->elements(); |
10167 if (elements->IsDictionary()) { | 10171 if (elements->IsDictionary()) { |
10168 return Smi::FromInt(NumberDictionary::cast(elements)->NumberOfElements()); | 10172 int result = SeededNumberDictionary::cast(elements)->NumberOfElements(); |
| 10173 return Smi::FromInt(result); |
10169 } else if (object->IsJSArray()) { | 10174 } else if (object->IsJSArray()) { |
10170 return JSArray::cast(object)->length(); | 10175 return JSArray::cast(object)->length(); |
10171 } else { | 10176 } else { |
10172 return Smi::FromInt(FixedArray::cast(elements)->length()); | 10177 return Smi::FromInt(FixedArray::cast(elements)->length()); |
10173 } | 10178 } |
10174 } | 10179 } |
10175 | 10180 |
10176 | 10181 |
10177 RUNTIME_FUNCTION(MaybeObject*, Runtime_SwapElements) { | 10182 RUNTIME_FUNCTION(MaybeObject*, Runtime_SwapElements) { |
10178 HandleScope handle_scope(isolate); | 10183 HandleScope handle_scope(isolate); |
(...skipping 3368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13547 } else { | 13552 } else { |
13548 // Handle last resort GC and make sure to allow future allocations | 13553 // Handle last resort GC and make sure to allow future allocations |
13549 // to grow the heap without causing GCs (if possible). | 13554 // to grow the heap without causing GCs (if possible). |
13550 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13555 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13551 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); | 13556 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); |
13552 } | 13557 } |
13553 } | 13558 } |
13554 | 13559 |
13555 | 13560 |
13556 } } // namespace v8::internal | 13561 } } // namespace v8::internal |
OLD | NEW |