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 |