| 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 3976 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3987 } | 3987 } |
| 3988 | 3988 |
| 3989 | 3989 |
| 3990 /** | 3990 /** |
| 3991 * A simple visitor visits every element of Array's. | 3991 * A simple visitor visits every element of Array's. |
| 3992 * The backend storage can be a fixed array for fast elements case, | 3992 * The backend storage can be a fixed array for fast elements case, |
| 3993 * or a dictionary for sparse array. Since Dictionary is a subtype | 3993 * or a dictionary for sparse array. Since Dictionary is a subtype |
| 3994 * of FixedArray, the class can be used by both fast and slow cases. | 3994 * of FixedArray, the class can be used by both fast and slow cases. |
| 3995 * The second parameter of the constructor, fast_elements, specifies | 3995 * The second parameter of the constructor, fast_elements, specifies |
| 3996 * whether the storage is a FixedArray or Dictionary. | 3996 * whether the storage is a FixedArray or Dictionary. |
| 3997 * |
| 3998 * An index limit is used to deal with the situation that a result array |
| 3999 * length overflows 32-bit non-negative integer. |
| 3997 */ | 4000 */ |
| 3998 class ArrayConcatVisitor { | 4001 class ArrayConcatVisitor { |
| 3999 public: | 4002 public: |
| 4000 ArrayConcatVisitor(Handle<FixedArray> storage, bool fast_elements) | 4003 ArrayConcatVisitor(Handle<FixedArray> storage, |
| 4001 : storage_(storage), fast_elements_(fast_elements), index_offset_(0) { } | 4004 uint32_t index_limit, |
| 4005 bool fast_elements) : |
| 4006 storage_(storage), index_limit_(index_limit), |
| 4007 fast_elements_(fast_elements), index_offset_(0) { } |
| 4002 | 4008 |
| 4003 void visit(uint32_t i, Handle<Object> elm) { | 4009 void visit(uint32_t i, Handle<Object> elm) { |
| 4004 uint32_t index = i + index_offset_; | 4010 uint32_t index = i + index_offset_; |
| 4005 | 4011 if (index >= index_limit_) return; |
| 4012 |
| 4006 if (fast_elements_) { | 4013 if (fast_elements_) { |
| 4007 ASSERT(index < static_cast<uint32_t>(storage_->length())); | 4014 ASSERT(index < static_cast<uint32_t>(storage_->length())); |
| 4008 storage_->set(index, *elm); | 4015 storage_->set(index, *elm); |
| 4009 | 4016 |
| 4010 } else { | 4017 } else { |
| 4011 Handle<Dictionary> dict = Handle<Dictionary>::cast(storage_); | 4018 Handle<Dictionary> dict = Handle<Dictionary>::cast(storage_); |
| 4012 Handle<Dictionary> result = | 4019 Handle<Dictionary> result = |
| 4013 Factory::DictionaryAtNumberPut(dict, index, elm); | 4020 Factory::DictionaryAtNumberPut(dict, index, elm); |
| 4014 if (!result.is_identical_to(dict)) | 4021 if (!result.is_identical_to(dict)) |
| 4015 storage_ = result; | 4022 storage_ = result; |
| 4016 } | 4023 } |
| 4017 } | 4024 } |
| 4018 | 4025 |
| 4019 void increase_index_offset(uint32_t delta) { | 4026 void increase_index_offset(uint32_t delta) { |
| 4020 index_offset_ += delta; | 4027 index_offset_ += delta; |
| 4021 } | 4028 } |
| 4022 | 4029 |
| 4023 private: | 4030 private: |
| 4024 Handle<FixedArray> storage_; | 4031 Handle<FixedArray> storage_; |
| 4032 uint32_t index_limit_; |
| 4025 bool fast_elements_; | 4033 bool fast_elements_; |
| 4026 uint32_t index_offset_; | 4034 uint32_t index_offset_; |
| 4027 }; | 4035 }; |
| 4028 | 4036 |
| 4029 | 4037 |
| 4030 /** | 4038 /** |
| 4031 * A helper function that visits elements of a JSObject. Only elements | 4039 * A helper function that visits elements of a JSObject. Only elements |
| 4032 * whose index between 0 and range (exclusive) are visited. | 4040 * whose index between 0 and range (exclusive) are visited. |
| 4033 * | 4041 * |
| 4034 * If the third parameter, visitor, is not NULL, the visitor is called | 4042 * If the third parameter, visitor, is not NULL, the visitor is called |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4119 | 4127 |
| 4120 /** | 4128 /** |
| 4121 * A helper function of Runtime_ArrayConcat. | 4129 * A helper function of Runtime_ArrayConcat. |
| 4122 * | 4130 * |
| 4123 * The first argument is an Array of Arrays and objects. It is the same as | 4131 * The first argument is an Array of Arrays and objects. It is the same as |
| 4124 * the arguments array of Array::concat JS function. | 4132 * the arguments array of Array::concat JS function. |
| 4125 * | 4133 * |
| 4126 * If an argument is an Array object, the function visits array elements. | 4134 * If an argument is an Array object, the function visits array elements. |
| 4127 * If an argument is not an Array object, the function visits the object | 4135 * If an argument is not an Array object, the function visits the object |
| 4128 * as if it is an one-element array. | 4136 * as if it is an one-element array. |
| 4137 * |
| 4138 * If the result array index overflows 32-bit integer, the rounded non-negative |
| 4139 * number is used as new length. For example, if one array length is 2^32 - 1, |
| 4140 * second array length is 1, the concatenated array length is 0. |
| 4129 */ | 4141 */ |
| 4130 static uint32_t IterateArguments(Handle<JSArray> arguments, | 4142 static uint32_t IterateArguments(Handle<JSArray> arguments, |
| 4131 ArrayConcatVisitor* visitor) { | 4143 ArrayConcatVisitor* visitor) { |
| 4132 uint32_t visited_elements = 0; | 4144 uint32_t visited_elements = 0; |
| 4133 uint32_t num_of_args = static_cast<uint32_t>(arguments->length()->Number()); | 4145 uint32_t num_of_args = static_cast<uint32_t>(arguments->length()->Number()); |
| 4134 | 4146 |
| 4135 for (uint32_t i = 0; i < num_of_args; i++) { | 4147 for (uint32_t i = 0; i < num_of_args; i++) { |
| 4136 Handle<Object> obj(arguments->GetElement(i)); | 4148 Handle<Object> obj(arguments->GetElement(i)); |
| 4137 if (obj->IsJSArray()) { | 4149 if (obj->IsJSArray()) { |
| 4138 Handle<JSArray> array = Handle<JSArray>::cast(obj); | 4150 Handle<JSArray> array = Handle<JSArray>::cast(obj); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4200 } else { | 4212 } else { |
| 4201 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate | 4213 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate |
| 4202 uint32_t at_least_space_for = estimate_nof_elements + | 4214 uint32_t at_least_space_for = estimate_nof_elements + |
| 4203 (estimate_nof_elements >> 2); | 4215 (estimate_nof_elements >> 2); |
| 4204 storage = Handle<FixedArray>::cast( | 4216 storage = Handle<FixedArray>::cast( |
| 4205 Factory::NewDictionary(at_least_space_for)); | 4217 Factory::NewDictionary(at_least_space_for)); |
| 4206 } | 4218 } |
| 4207 | 4219 |
| 4208 Handle<Object> len = Factory::NewNumber(static_cast<double>(result_length)); | 4220 Handle<Object> len = Factory::NewNumber(static_cast<double>(result_length)); |
| 4209 | 4221 |
| 4210 ArrayConcatVisitor visitor(storage, fast_case); | 4222 ArrayConcatVisitor visitor(storage, result_length, fast_case); |
| 4211 | 4223 |
| 4212 IterateArguments(arguments, &visitor); | 4224 IterateArguments(arguments, &visitor); |
| 4213 | 4225 |
| 4214 result->set_length(*len); | 4226 result->set_length(*len); |
| 4215 result->set_elements(*storage); | 4227 result->set_elements(*storage); |
| 4216 | 4228 |
| 4217 return *result; | 4229 return *result; |
| 4218 } | 4230 } |
| 4219 | 4231 |
| 4220 | 4232 |
| (...skipping 1533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5754 | 5766 |
| 5755 void Runtime::PerformGC(Object* result) { | 5767 void Runtime::PerformGC(Object* result) { |
| 5756 Failure* failure = Failure::cast(result); | 5768 Failure* failure = Failure::cast(result); |
| 5757 // Try to do a garbage collection; ignore it if it fails. The C | 5769 // Try to do a garbage collection; ignore it if it fails. The C |
| 5758 // entry stub will throw an out-of-memory exception in that case. | 5770 // entry stub will throw an out-of-memory exception in that case. |
| 5759 Heap::CollectGarbage(failure->requested(), failure->allocation_space()); | 5771 Heap::CollectGarbage(failure->requested(), failure->allocation_space()); |
| 5760 } | 5772 } |
| 5761 | 5773 |
| 5762 | 5774 |
| 5763 } } // namespace v8::internal | 5775 } } // namespace v8::internal |
| OLD | NEW |