| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 5596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5607 return object; | 5607 return object; |
| 5608 } | 5608 } |
| 5609 | 5609 |
| 5610 | 5610 |
| 5611 void JSObject::SetObserved(Handle<JSObject> object) { | 5611 void JSObject::SetObserved(Handle<JSObject> object) { |
| 5612 Isolate* isolate = object->GetIsolate(); | 5612 Isolate* isolate = object->GetIsolate(); |
| 5613 | 5613 |
| 5614 if (object->map()->is_observed()) | 5614 if (object->map()->is_observed()) |
| 5615 return; | 5615 return; |
| 5616 | 5616 |
| 5617 if (!object->HasExternalArrayElements()) { | |
| 5618 // Go to dictionary mode, so that we don't skip map checks. | |
| 5619 NormalizeElements(object); | |
| 5620 ASSERT(!object->HasFastElements()); | |
| 5621 } | |
| 5622 | |
| 5623 LookupResult result(isolate); | 5617 LookupResult result(isolate); |
| 5624 object->map()->LookupTransition(*object, | 5618 object->map()->LookupTransition(*object, |
| 5625 isolate->heap()->observed_symbol(), | 5619 isolate->heap()->observed_symbol(), |
| 5626 &result); | 5620 &result); |
| 5627 | 5621 |
| 5628 Handle<Map> new_map; | 5622 Handle<Map> new_map; |
| 5629 if (result.IsTransition()) { | 5623 if (result.IsTransition()) { |
| 5630 new_map = handle(result.GetTransitionTarget()); | 5624 new_map = handle(result.GetTransitionTarget()); |
| 5631 ASSERT(new_map->is_observed()); | 5625 ASSERT(new_map->is_observed()); |
| 5632 } else if (object->map()->CanHaveMoreTransitions()) { | 5626 } else if (object->map()->CanHaveMoreTransitions()) { |
| 5633 new_map = Map::CopyForObserved(handle(object->map())); | 5627 new_map = Map::CopyForObserved(handle(object->map())); |
| 5634 } else { | 5628 } else { |
| 5635 new_map = Map::Copy(handle(object->map())); | 5629 new_map = Map::Copy(handle(object->map())); |
| 5636 new_map->set_is_observed(true); | 5630 new_map->set_is_observed(); |
| 5637 } | 5631 } |
| 5638 object->set_map(*new_map); | 5632 object->set_map(*new_map); |
| 5639 } | 5633 } |
| 5640 | 5634 |
| 5641 | 5635 |
| 5642 Handle<JSObject> JSObject::Copy(Handle<JSObject> object, | 5636 Handle<JSObject> JSObject::Copy(Handle<JSObject> object, |
| 5643 Handle<AllocationSite> site) { | 5637 Handle<AllocationSite> site) { |
| 5644 Isolate* isolate = object->GetIsolate(); | 5638 Isolate* isolate = object->GetIsolate(); |
| 5645 CALL_HEAP_FUNCTION(isolate, | 5639 CALL_HEAP_FUNCTION(isolate, |
| 5646 isolate->heap()->CopyJSObject(*object, *site), JSObject); | 5640 isolate->heap()->CopyJSObject(*object, *site), JSObject); |
| (...skipping 1317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6964 } else { | 6958 } else { |
| 6965 new_map = Map::Copy(map); | 6959 new_map = Map::Copy(map); |
| 6966 } | 6960 } |
| 6967 | 6961 |
| 6968 Handle<TransitionArray> transitions = | 6962 Handle<TransitionArray> transitions = |
| 6969 Map::AddTransition(map, isolate->factory()->observed_symbol(), new_map, | 6963 Map::AddTransition(map, isolate->factory()->observed_symbol(), new_map, |
| 6970 FULL_TRANSITION); | 6964 FULL_TRANSITION); |
| 6971 | 6965 |
| 6972 map->set_transitions(*transitions); | 6966 map->set_transitions(*transitions); |
| 6973 | 6967 |
| 6974 new_map->set_is_observed(true); | 6968 new_map->set_is_observed(); |
| 6975 | 6969 |
| 6976 if (map->owns_descriptors()) { | 6970 if (map->owns_descriptors()) { |
| 6977 new_map->InitializeDescriptors(map->instance_descriptors()); | 6971 new_map->InitializeDescriptors(map->instance_descriptors()); |
| 6978 map->set_owns_descriptors(false); | 6972 map->set_owns_descriptors(false); |
| 6979 } | 6973 } |
| 6980 | 6974 |
| 6981 new_map->SetBackPointer(*map); | 6975 new_map->SetBackPointer(*map); |
| 6982 return new_map; | 6976 return new_map; |
| 6983 } | 6977 } |
| 6984 | 6978 |
| (...skipping 4229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11214 #endif // ENABLE_DISASSEMBLER | 11208 #endif // ENABLE_DISASSEMBLER |
| 11215 | 11209 |
| 11216 | 11210 |
| 11217 MaybeObject* JSObject::SetFastElementsCapacityAndLength( | 11211 MaybeObject* JSObject::SetFastElementsCapacityAndLength( |
| 11218 int capacity, | 11212 int capacity, |
| 11219 int length, | 11213 int length, |
| 11220 SetFastElementsCapacitySmiMode smi_mode) { | 11214 SetFastElementsCapacitySmiMode smi_mode) { |
| 11221 Heap* heap = GetHeap(); | 11215 Heap* heap = GetHeap(); |
| 11222 // We should never end in here with a pixel or external array. | 11216 // We should never end in here with a pixel or external array. |
| 11223 ASSERT(!HasExternalArrayElements()); | 11217 ASSERT(!HasExternalArrayElements()); |
| 11224 ASSERT(!map()->is_observed()); | |
| 11225 | 11218 |
| 11226 // Allocate a new fast elements backing store. | 11219 // Allocate a new fast elements backing store. |
| 11227 FixedArray* new_elements; | 11220 FixedArray* new_elements; |
| 11228 MaybeObject* maybe = heap->AllocateUninitializedFixedArray(capacity); | 11221 MaybeObject* maybe = heap->AllocateUninitializedFixedArray(capacity); |
| 11229 if (!maybe->To(&new_elements)) return maybe; | 11222 if (!maybe->To(&new_elements)) return maybe; |
| 11230 | 11223 |
| 11231 ElementsKind elements_kind = GetElementsKind(); | 11224 ElementsKind elements_kind = GetElementsKind(); |
| 11232 ElementsKind new_elements_kind; | 11225 ElementsKind new_elements_kind; |
| 11233 // The resized array has FAST_*_SMI_ELEMENTS if the capacity mode forces it, | 11226 // The resized array has FAST_*_SMI_ELEMENTS if the capacity mode forces it, |
| 11234 // or if it's allowed and the old elements array contained only SMIs. | 11227 // or if it's allowed and the old elements array contained only SMIs. |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11299 | 11292 |
| 11300 return false; | 11293 return false; |
| 11301 } | 11294 } |
| 11302 | 11295 |
| 11303 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( | 11296 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( |
| 11304 int capacity, | 11297 int capacity, |
| 11305 int length) { | 11298 int length) { |
| 11306 Heap* heap = GetHeap(); | 11299 Heap* heap = GetHeap(); |
| 11307 // We should never end in here with a pixel or external array. | 11300 // We should never end in here with a pixel or external array. |
| 11308 ASSERT(!HasExternalArrayElements()); | 11301 ASSERT(!HasExternalArrayElements()); |
| 11309 ASSERT(!map()->is_observed()); | |
| 11310 | 11302 |
| 11311 FixedArrayBase* elems; | 11303 FixedArrayBase* elems; |
| 11312 { MaybeObject* maybe_obj = | 11304 { MaybeObject* maybe_obj = |
| 11313 heap->AllocateUninitializedFixedDoubleArray(capacity); | 11305 heap->AllocateUninitializedFixedDoubleArray(capacity); |
| 11314 if (!maybe_obj->To(&elems)) return maybe_obj; | 11306 if (!maybe_obj->To(&elems)) return maybe_obj; |
| 11315 } | 11307 } |
| 11316 | 11308 |
| 11317 ElementsKind elements_kind = GetElementsKind(); | 11309 ElementsKind elements_kind = GetElementsKind(); |
| 11318 ElementsKind new_elements_kind = elements_kind; | 11310 ElementsKind new_elements_kind = elements_kind; |
| 11319 if (IsHoleyElementsKind(elements_kind)) { | 11311 if (IsHoleyElementsKind(elements_kind)) { |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11448 List<uint32_t> indices; | 11440 List<uint32_t> indices; |
| 11449 List<Handle<Object> > old_values; | 11441 List<Handle<Object> > old_values; |
| 11450 Handle<Object> old_length_handle(self->length(), isolate); | 11442 Handle<Object> old_length_handle(self->length(), isolate); |
| 11451 Handle<Object> new_length_handle(len, isolate); | 11443 Handle<Object> new_length_handle(len, isolate); |
| 11452 uint32_t old_length = 0; | 11444 uint32_t old_length = 0; |
| 11453 CHECK(old_length_handle->ToArrayIndex(&old_length)); | 11445 CHECK(old_length_handle->ToArrayIndex(&old_length)); |
| 11454 uint32_t new_length = 0; | 11446 uint32_t new_length = 0; |
| 11455 if (!new_length_handle->ToArrayIndex(&new_length)) | 11447 if (!new_length_handle->ToArrayIndex(&new_length)) |
| 11456 return Failure::InternalError(); | 11448 return Failure::InternalError(); |
| 11457 | 11449 |
| 11458 // Observed arrays should always be in dictionary mode; | |
| 11459 // if they were in fast mode, the below is slower than necessary | |
| 11460 // as it iterates over the array backing store multiple times. | |
| 11461 ASSERT(self->HasDictionaryElements()); | |
| 11462 static const PropertyAttributes kNoAttrFilter = NONE; | 11450 static const PropertyAttributes kNoAttrFilter = NONE; |
| 11463 int num_elements = self->NumberOfLocalElements(kNoAttrFilter); | 11451 int num_elements = self->NumberOfLocalElements(kNoAttrFilter); |
| 11464 if (num_elements > 0) { | 11452 if (num_elements > 0) { |
| 11465 if (old_length == static_cast<uint32_t>(num_elements)) { | 11453 if (old_length == static_cast<uint32_t>(num_elements)) { |
| 11466 // Simple case for arrays without holes. | 11454 // Simple case for arrays without holes. |
| 11467 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) { | 11455 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) { |
| 11468 if (!GetOldValue(isolate, self, i, &old_values, &indices)) break; | 11456 if (!GetOldValue(isolate, self, i, &old_values, &indices)) break; |
| 11469 } | 11457 } |
| 11470 } else { | 11458 } else { |
| 11471 // For sparse arrays, only iterate over existing elements. | 11459 // For sparse arrays, only iterate over existing elements. |
| 11460 // TODO(rafaelw): For fast, sparse arrays, we can avoid iterating over |
| 11461 // the to-be-removed indices twice. |
| 11472 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements); | 11462 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements); |
| 11473 self->GetLocalElementKeys(*keys, kNoAttrFilter); | 11463 self->GetLocalElementKeys(*keys, kNoAttrFilter); |
| 11474 while (num_elements-- > 0) { | 11464 while (num_elements-- > 0) { |
| 11475 uint32_t index = NumberToUint32(keys->get(num_elements)); | 11465 uint32_t index = NumberToUint32(keys->get(num_elements)); |
| 11476 if (index < new_length) break; | 11466 if (index < new_length) break; |
| 11477 if (!GetOldValue(isolate, self, index, &old_values, &indices)) break; | 11467 if (!GetOldValue(isolate, self, index, &old_values, &indices)) break; |
| 11478 } | 11468 } |
| 11479 } | 11469 } |
| 11480 } | 11470 } |
| 11481 | 11471 |
| (...skipping 1378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12860 ElementsKindToString(to_kind)); | 12850 ElementsKindToString(to_kind)); |
| 12861 } | 12851 } |
| 12862 site->set_transition_info(Smi::FromInt(to_kind)); | 12852 site->set_transition_info(Smi::FromInt(to_kind)); |
| 12863 } | 12853 } |
| 12864 } | 12854 } |
| 12865 return this; | 12855 return this; |
| 12866 } | 12856 } |
| 12867 | 12857 |
| 12868 | 12858 |
| 12869 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { | 12859 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { |
| 12870 ASSERT(!map()->is_observed()); | |
| 12871 ElementsKind from_kind = map()->elements_kind(); | 12860 ElementsKind from_kind = map()->elements_kind(); |
| 12872 | 12861 |
| 12873 if (IsFastHoleyElementsKind(from_kind)) { | 12862 if (IsFastHoleyElementsKind(from_kind)) { |
| 12874 to_kind = GetHoleyElementsKind(to_kind); | 12863 to_kind = GetHoleyElementsKind(to_kind); |
| 12875 } | 12864 } |
| 12876 | 12865 |
| 12877 if (from_kind == to_kind) return this; | 12866 if (from_kind == to_kind) return this; |
| 12878 // Don't update the site if to_kind isn't fast | 12867 // Don't update the site if to_kind isn't fast |
| 12879 if (IsFastElementsKind(to_kind)) { | 12868 if (IsFastElementsKind(to_kind)) { |
| 12880 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); | 12869 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); |
| (...skipping 3649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16530 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16519 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16531 static const char* error_messages_[] = { | 16520 static const char* error_messages_[] = { |
| 16532 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16521 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16533 }; | 16522 }; |
| 16534 #undef ERROR_MESSAGES_TEXTS | 16523 #undef ERROR_MESSAGES_TEXTS |
| 16535 return error_messages_[reason]; | 16524 return error_messages_[reason]; |
| 16536 } | 16525 } |
| 16537 | 16526 |
| 16538 | 16527 |
| 16539 } } // namespace v8::internal | 16528 } } // namespace v8::internal |
| OLD | NEW |