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 4234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11219 #endif // ENABLE_DISASSEMBLER | 11213 #endif // ENABLE_DISASSEMBLER |
11220 | 11214 |
11221 | 11215 |
11222 MaybeObject* JSObject::SetFastElementsCapacityAndLength( | 11216 MaybeObject* JSObject::SetFastElementsCapacityAndLength( |
11223 int capacity, | 11217 int capacity, |
11224 int length, | 11218 int length, |
11225 SetFastElementsCapacitySmiMode smi_mode) { | 11219 SetFastElementsCapacitySmiMode smi_mode) { |
11226 Heap* heap = GetHeap(); | 11220 Heap* heap = GetHeap(); |
11227 // We should never end in here with a pixel or external array. | 11221 // We should never end in here with a pixel or external array. |
11228 ASSERT(!HasExternalArrayElements()); | 11222 ASSERT(!HasExternalArrayElements()); |
11229 ASSERT(!map()->is_observed()); | |
11230 | 11223 |
11231 // Allocate a new fast elements backing store. | 11224 // Allocate a new fast elements backing store. |
11232 FixedArray* new_elements; | 11225 FixedArray* new_elements; |
11233 MaybeObject* maybe = heap->AllocateUninitializedFixedArray(capacity); | 11226 MaybeObject* maybe = heap->AllocateUninitializedFixedArray(capacity); |
11234 if (!maybe->To(&new_elements)) return maybe; | 11227 if (!maybe->To(&new_elements)) return maybe; |
11235 | 11228 |
11236 ElementsKind elements_kind = GetElementsKind(); | 11229 ElementsKind elements_kind = GetElementsKind(); |
11237 ElementsKind new_elements_kind; | 11230 ElementsKind new_elements_kind; |
11238 // The resized array has FAST_*_SMI_ELEMENTS if the capacity mode forces it, | 11231 // The resized array has FAST_*_SMI_ELEMENTS if the capacity mode forces it, |
11239 // or if it's allowed and the old elements array contained only SMIs. | 11232 // 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... |
11304 | 11297 |
11305 return false; | 11298 return false; |
11306 } | 11299 } |
11307 | 11300 |
11308 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( | 11301 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( |
11309 int capacity, | 11302 int capacity, |
11310 int length) { | 11303 int length) { |
11311 Heap* heap = GetHeap(); | 11304 Heap* heap = GetHeap(); |
11312 // We should never end in here with a pixel or external array. | 11305 // We should never end in here with a pixel or external array. |
11313 ASSERT(!HasExternalArrayElements()); | 11306 ASSERT(!HasExternalArrayElements()); |
11314 ASSERT(!map()->is_observed()); | |
11315 | 11307 |
11316 FixedArrayBase* elems; | 11308 FixedArrayBase* elems; |
11317 { MaybeObject* maybe_obj = | 11309 { MaybeObject* maybe_obj = |
11318 heap->AllocateUninitializedFixedDoubleArray(capacity); | 11310 heap->AllocateUninitializedFixedDoubleArray(capacity); |
11319 if (!maybe_obj->To(&elems)) return maybe_obj; | 11311 if (!maybe_obj->To(&elems)) return maybe_obj; |
11320 } | 11312 } |
11321 | 11313 |
11322 ElementsKind elements_kind = GetElementsKind(); | 11314 ElementsKind elements_kind = GetElementsKind(); |
11323 ElementsKind new_elements_kind = elements_kind; | 11315 ElementsKind new_elements_kind = elements_kind; |
11324 if (IsHoleyElementsKind(elements_kind)) { | 11316 if (IsHoleyElementsKind(elements_kind)) { |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11453 List<uint32_t> indices; | 11445 List<uint32_t> indices; |
11454 List<Handle<Object> > old_values; | 11446 List<Handle<Object> > old_values; |
11455 Handle<Object> old_length_handle(self->length(), isolate); | 11447 Handle<Object> old_length_handle(self->length(), isolate); |
11456 Handle<Object> new_length_handle(len, isolate); | 11448 Handle<Object> new_length_handle(len, isolate); |
11457 uint32_t old_length = 0; | 11449 uint32_t old_length = 0; |
11458 CHECK(old_length_handle->ToArrayIndex(&old_length)); | 11450 CHECK(old_length_handle->ToArrayIndex(&old_length)); |
11459 uint32_t new_length = 0; | 11451 uint32_t new_length = 0; |
11460 if (!new_length_handle->ToArrayIndex(&new_length)) | 11452 if (!new_length_handle->ToArrayIndex(&new_length)) |
11461 return Failure::InternalError(); | 11453 return Failure::InternalError(); |
11462 | 11454 |
11463 // Observed arrays should always be in dictionary mode; | |
11464 // if they were in fast mode, the below is slower than necessary | |
11465 // as it iterates over the array backing store multiple times. | |
11466 ASSERT(self->HasDictionaryElements()); | |
11467 static const PropertyAttributes kNoAttrFilter = NONE; | 11455 static const PropertyAttributes kNoAttrFilter = NONE; |
11468 int num_elements = self->NumberOfLocalElements(kNoAttrFilter); | 11456 int num_elements = self->NumberOfLocalElements(kNoAttrFilter); |
11469 if (num_elements > 0) { | 11457 if (num_elements > 0) { |
11470 if (old_length == static_cast<uint32_t>(num_elements)) { | 11458 if (old_length == static_cast<uint32_t>(num_elements)) { |
11471 // Simple case for arrays without holes. | 11459 // Simple case for arrays without holes. |
11472 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) { | 11460 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) { |
11473 if (!GetOldValue(isolate, self, i, &old_values, &indices)) break; | 11461 if (!GetOldValue(isolate, self, i, &old_values, &indices)) break; |
11474 } | 11462 } |
11475 } else { | 11463 } else { |
11476 // For sparse arrays, only iterate over existing elements. | 11464 // For sparse arrays, only iterate over existing elements. |
| 11465 // TODO(rafaelw): For fast, sparse arrays, we can avoid iterating over |
| 11466 // the to-be-removed indices twice. |
11477 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements); | 11467 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements); |
11478 self->GetLocalElementKeys(*keys, kNoAttrFilter); | 11468 self->GetLocalElementKeys(*keys, kNoAttrFilter); |
11479 while (num_elements-- > 0) { | 11469 while (num_elements-- > 0) { |
11480 uint32_t index = NumberToUint32(keys->get(num_elements)); | 11470 uint32_t index = NumberToUint32(keys->get(num_elements)); |
11481 if (index < new_length) break; | 11471 if (index < new_length) break; |
11482 if (!GetOldValue(isolate, self, index, &old_values, &indices)) break; | 11472 if (!GetOldValue(isolate, self, index, &old_values, &indices)) break; |
11483 } | 11473 } |
11484 } | 11474 } |
11485 } | 11475 } |
11486 | 11476 |
(...skipping 1378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12865 ElementsKindToString(to_kind)); | 12855 ElementsKindToString(to_kind)); |
12866 } | 12856 } |
12867 site->set_transition_info(Smi::FromInt(to_kind)); | 12857 site->set_transition_info(Smi::FromInt(to_kind)); |
12868 } | 12858 } |
12869 } | 12859 } |
12870 return this; | 12860 return this; |
12871 } | 12861 } |
12872 | 12862 |
12873 | 12863 |
12874 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { | 12864 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { |
12875 ASSERT(!map()->is_observed()); | |
12876 ElementsKind from_kind = map()->elements_kind(); | 12865 ElementsKind from_kind = map()->elements_kind(); |
12877 | 12866 |
12878 if (IsFastHoleyElementsKind(from_kind)) { | 12867 if (IsFastHoleyElementsKind(from_kind)) { |
12879 to_kind = GetHoleyElementsKind(to_kind); | 12868 to_kind = GetHoleyElementsKind(to_kind); |
12880 } | 12869 } |
12881 | 12870 |
12882 if (from_kind == to_kind) return this; | 12871 if (from_kind == to_kind) return this; |
12883 // Don't update the site if to_kind isn't fast | 12872 // Don't update the site if to_kind isn't fast |
12884 if (IsFastElementsKind(to_kind)) { | 12873 if (IsFastElementsKind(to_kind)) { |
12885 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); | 12874 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); |
(...skipping 3649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16535 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16524 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16536 static const char* error_messages_[] = { | 16525 static const char* error_messages_[] = { |
16537 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16526 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16538 }; | 16527 }; |
16539 #undef ERROR_MESSAGES_TEXTS | 16528 #undef ERROR_MESSAGES_TEXTS |
16540 return error_messages_[reason]; | 16529 return error_messages_[reason]; |
16541 } | 16530 } |
16542 | 16531 |
16543 | 16532 |
16544 } } // namespace v8::internal | 16533 } } // namespace v8::internal |
OLD | NEW |