| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 for (int i = 0; i < elements->length(); i++) { | 161 for (int i = 0; i < elements->length(); i++) { |
| 162 Object* value = elements->get(i); | 162 Object* value = elements->get(i); |
| 163 if (value->IsJSObject()) { | 163 if (value->IsJSObject()) { |
| 164 JSObject* jsObject = JSObject::cast(value); | 164 JSObject* jsObject = JSObject::cast(value); |
| 165 result = DeepCopyBoilerplate(jsObject); | 165 result = DeepCopyBoilerplate(jsObject); |
| 166 if (result->IsFailure()) return result; | 166 if (result->IsFailure()) return result; |
| 167 elements->set(i, result, mode); | 167 elements->set(i, result, mode); |
| 168 } | 168 } |
| 169 } | 169 } |
| 170 } else { | 170 } else { |
| 171 Dictionary* element_dictionary = copy->element_dictionary(); | 171 NumberDictionary* element_dictionary = copy->element_dictionary(); |
| 172 int capacity = element_dictionary->Capacity(); | 172 int capacity = element_dictionary->Capacity(); |
| 173 for (int i = 0; i < capacity; i++) { | 173 for (int i = 0; i < capacity; i++) { |
| 174 Object* k = element_dictionary->KeyAt(i); | 174 Object* k = element_dictionary->KeyAt(i); |
| 175 if (element_dictionary->IsKey(k)) { | 175 if (element_dictionary->IsKey(k)) { |
| 176 Object* value = element_dictionary->ValueAt(i); | 176 Object* value = element_dictionary->ValueAt(i); |
| 177 if (value->IsJSObject()) { | 177 if (value->IsJSObject()) { |
| 178 JSObject* jsObject = JSObject::cast(value); | 178 JSObject* jsObject = JSObject::cast(value); |
| 179 result = DeepCopyBoilerplate(jsObject); | 179 result = DeepCopyBoilerplate(jsObject); |
| 180 if (result->IsFailure()) return result; | 180 if (result->IsFailure()) return result; |
| 181 element_dictionary->ValueAtPut(i, result); | 181 element_dictionary->ValueAtPut(i, result); |
| (...skipping 2421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2603 LookupResult result; | 2603 LookupResult result; |
| 2604 receiver->LocalLookup(key, &result); | 2604 receiver->LocalLookup(key, &result); |
| 2605 if (result.IsProperty() && result.IsLoaded() && result.type() == FIELD) { | 2605 if (result.IsProperty() && result.IsLoaded() && result.type() == FIELD) { |
| 2606 int offset = result.GetFieldIndex(); | 2606 int offset = result.GetFieldIndex(); |
| 2607 KeyedLookupCache::Update(receiver_map, key, offset); | 2607 KeyedLookupCache::Update(receiver_map, key, offset); |
| 2608 Object* value = receiver->FastPropertyAt(offset); | 2608 Object* value = receiver->FastPropertyAt(offset); |
| 2609 return value->IsTheHole() ? Heap::undefined_value() : value; | 2609 return value->IsTheHole() ? Heap::undefined_value() : value; |
| 2610 } | 2610 } |
| 2611 } else { | 2611 } else { |
| 2612 // Attempt dictionary lookup. | 2612 // Attempt dictionary lookup. |
| 2613 Dictionary* dictionary = receiver->property_dictionary(); | 2613 StringDictionary* dictionary = receiver->property_dictionary(); |
| 2614 int entry = dictionary->FindStringEntry(key); | 2614 int entry = dictionary->FindEntry(key); |
| 2615 if ((entry != Dictionary::kNotFound) && | 2615 if ((entry != StringDictionary::kNotFound) && |
| 2616 (dictionary->DetailsAt(entry).type() == NORMAL)) { | 2616 (dictionary->DetailsAt(entry).type() == NORMAL)) { |
| 2617 Object* value = dictionary->ValueAt(entry); | 2617 Object* value = dictionary->ValueAt(entry); |
| 2618 if (receiver->IsGlobalObject()) { | 2618 if (receiver->IsGlobalObject()) { |
| 2619 value = JSGlobalPropertyCell::cast(value)->value(); | 2619 value = JSGlobalPropertyCell::cast(value)->value(); |
| 2620 } | 2620 } |
| 2621 return value; | 2621 return value; |
| 2622 } | 2622 } |
| 2623 } | 2623 } |
| 2624 } | 2624 } |
| 2625 | 2625 |
| (...skipping 2503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5129 | 5129 |
| 5130 void visit(uint32_t i, Handle<Object> elm) { | 5130 void visit(uint32_t i, Handle<Object> elm) { |
| 5131 uint32_t index = i + index_offset_; | 5131 uint32_t index = i + index_offset_; |
| 5132 if (index >= index_limit_) return; | 5132 if (index >= index_limit_) return; |
| 5133 | 5133 |
| 5134 if (fast_elements_) { | 5134 if (fast_elements_) { |
| 5135 ASSERT(index < static_cast<uint32_t>(storage_->length())); | 5135 ASSERT(index < static_cast<uint32_t>(storage_->length())); |
| 5136 storage_->set(index, *elm); | 5136 storage_->set(index, *elm); |
| 5137 | 5137 |
| 5138 } else { | 5138 } else { |
| 5139 Handle<Dictionary> dict = Handle<Dictionary>::cast(storage_); | 5139 Handle<NumberDictionary> dict = Handle<NumberDictionary>::cast(storage_); |
| 5140 Handle<Dictionary> result = | 5140 Handle<NumberDictionary> result = |
| 5141 Factory::DictionaryAtNumberPut(dict, index, elm); | 5141 Factory::DictionaryAtNumberPut(dict, index, elm); |
| 5142 if (!result.is_identical_to(dict)) | 5142 if (!result.is_identical_to(dict)) |
| 5143 storage_ = result; | 5143 storage_ = result; |
| 5144 } | 5144 } |
| 5145 } | 5145 } |
| 5146 | 5146 |
| 5147 void increase_index_offset(uint32_t delta) { | 5147 void increase_index_offset(uint32_t delta) { |
| 5148 index_offset_ += delta; | 5148 index_offset_ += delta; |
| 5149 } | 5149 } |
| 5150 | 5150 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 5178 for (uint32_t j = 0; j < len; j++) { | 5178 for (uint32_t j = 0; j < len; j++) { |
| 5179 Handle<Object> e(elements->get(j)); | 5179 Handle<Object> e(elements->get(j)); |
| 5180 if (!e->IsTheHole()) { | 5180 if (!e->IsTheHole()) { |
| 5181 num_of_elements++; | 5181 num_of_elements++; |
| 5182 if (visitor) | 5182 if (visitor) |
| 5183 visitor->visit(j, e); | 5183 visitor->visit(j, e); |
| 5184 } | 5184 } |
| 5185 } | 5185 } |
| 5186 | 5186 |
| 5187 } else { | 5187 } else { |
| 5188 Handle<Dictionary> dict(receiver->element_dictionary()); | 5188 Handle<NumberDictionary> dict(receiver->element_dictionary()); |
| 5189 uint32_t capacity = dict->Capacity(); | 5189 uint32_t capacity = dict->Capacity(); |
| 5190 for (uint32_t j = 0; j < capacity; j++) { | 5190 for (uint32_t j = 0; j < capacity; j++) { |
| 5191 Handle<Object> k(dict->KeyAt(j)); | 5191 Handle<Object> k(dict->KeyAt(j)); |
| 5192 if (dict->IsKey(*k)) { | 5192 if (dict->IsKey(*k)) { |
| 5193 ASSERT(k->IsNumber()); | 5193 ASSERT(k->IsNumber()); |
| 5194 uint32_t index = static_cast<uint32_t>(k->Number()); | 5194 uint32_t index = static_cast<uint32_t>(k->Number()); |
| 5195 if (index < range) { | 5195 if (index < range) { |
| 5196 num_of_elements++; | 5196 num_of_elements++; |
| 5197 if (visitor) { | 5197 if (visitor) { |
| 5198 visitor->visit(index, | 5198 visitor->visit(index, |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5332 if (fast_case) { | 5332 if (fast_case) { |
| 5333 // The backing storage array must have non-existing elements to | 5333 // The backing storage array must have non-existing elements to |
| 5334 // preserve holes across concat operations. | 5334 // preserve holes across concat operations. |
| 5335 storage = Factory::NewFixedArrayWithHoles(result_length); | 5335 storage = Factory::NewFixedArrayWithHoles(result_length); |
| 5336 | 5336 |
| 5337 } else { | 5337 } else { |
| 5338 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate | 5338 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate |
| 5339 uint32_t at_least_space_for = estimate_nof_elements + | 5339 uint32_t at_least_space_for = estimate_nof_elements + |
| 5340 (estimate_nof_elements >> 2); | 5340 (estimate_nof_elements >> 2); |
| 5341 storage = Handle<FixedArray>::cast( | 5341 storage = Handle<FixedArray>::cast( |
| 5342 Factory::NewDictionary(at_least_space_for)); | 5342 Factory::NewNumberDictionary(at_least_space_for)); |
| 5343 } | 5343 } |
| 5344 | 5344 |
| 5345 Handle<Object> len = Factory::NewNumber(static_cast<double>(result_length)); | 5345 Handle<Object> len = Factory::NewNumber(static_cast<double>(result_length)); |
| 5346 | 5346 |
| 5347 ArrayConcatVisitor visitor(storage, result_length, fast_case); | 5347 ArrayConcatVisitor visitor(storage, result_length, fast_case); |
| 5348 | 5348 |
| 5349 IterateArguments(arguments, &visitor); | 5349 IterateArguments(arguments, &visitor); |
| 5350 | 5350 |
| 5351 result->set_length(*len); | 5351 result->set_length(*len); |
| 5352 result->set_elements(*storage); | 5352 result->set_elements(*storage); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5395 return to; | 5395 return to; |
| 5396 } | 5396 } |
| 5397 | 5397 |
| 5398 | 5398 |
| 5399 // How many elements does this array have? | 5399 // How many elements does this array have? |
| 5400 static Object* Runtime_EstimateNumberOfElements(Arguments args) { | 5400 static Object* Runtime_EstimateNumberOfElements(Arguments args) { |
| 5401 ASSERT(args.length() == 1); | 5401 ASSERT(args.length() == 1); |
| 5402 CONVERT_CHECKED(JSArray, array, args[0]); | 5402 CONVERT_CHECKED(JSArray, array, args[0]); |
| 5403 HeapObject* elements = array->elements(); | 5403 HeapObject* elements = array->elements(); |
| 5404 if (elements->IsDictionary()) { | 5404 if (elements->IsDictionary()) { |
| 5405 return Smi::FromInt(Dictionary::cast(elements)->NumberOfElements()); | 5405 return Smi::FromInt(NumberDictionary::cast(elements)->NumberOfElements()); |
| 5406 } else { | 5406 } else { |
| 5407 return array->length(); | 5407 return array->length(); |
| 5408 } | 5408 } |
| 5409 } | 5409 } |
| 5410 | 5410 |
| 5411 | 5411 |
| 5412 // Returns an array that tells you where in the [0, length) interval an array | 5412 // Returns an array that tells you where in the [0, length) interval an array |
| 5413 // might have elements. Can either return keys or intervals. Keys can have | 5413 // might have elements. Can either return keys or intervals. Keys can have |
| 5414 // gaps in (undefined). Intervals can also span over some undefined keys. | 5414 // gaps in (undefined). Intervals can also span over some undefined keys. |
| 5415 static Object* Runtime_GetArrayKeys(Arguments args) { | 5415 static Object* Runtime_GetArrayKeys(Arguments args) { |
| (...skipping 2126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7542 } else { | 7542 } else { |
| 7543 // Handle last resort GC and make sure to allow future allocations | 7543 // Handle last resort GC and make sure to allow future allocations |
| 7544 // to grow the heap without causing GCs (if possible). | 7544 // to grow the heap without causing GCs (if possible). |
| 7545 Counters::gc_last_resort_from_js.Increment(); | 7545 Counters::gc_last_resort_from_js.Increment(); |
| 7546 Heap::CollectAllGarbage(); | 7546 Heap::CollectAllGarbage(); |
| 7547 } | 7547 } |
| 7548 } | 7548 } |
| 7549 | 7549 |
| 7550 | 7550 |
| 7551 } } // namespace v8::internal | 7551 } } // namespace v8::internal |
| OLD | NEW |