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 |
5617 LookupResult result(isolate); | 5623 LookupResult result(isolate); |
5618 object->map()->LookupTransition(*object, | 5624 object->map()->LookupTransition(*object, |
5619 isolate->heap()->observed_symbol(), | 5625 isolate->heap()->observed_symbol(), |
5620 &result); | 5626 &result); |
5621 | 5627 |
5622 Handle<Map> new_map; | 5628 Handle<Map> new_map; |
5623 if (result.IsTransition()) { | 5629 if (result.IsTransition()) { |
5624 new_map = handle(result.GetTransitionTarget()); | 5630 new_map = handle(result.GetTransitionTarget()); |
5625 ASSERT(new_map->is_observed()); | 5631 ASSERT(new_map->is_observed()); |
5626 } else if (object->map()->CanHaveMoreTransitions()) { | 5632 } else if (object->map()->CanHaveMoreTransitions()) { |
5627 new_map = Map::CopyForObserved(handle(object->map())); | 5633 new_map = Map::CopyForObserved(handle(object->map())); |
5628 } else { | 5634 } else { |
5629 new_map = Map::Copy(handle(object->map())); | 5635 new_map = Map::Copy(handle(object->map())); |
5630 new_map->set_is_observed(); | 5636 new_map->set_is_observed(true); |
5631 } | 5637 } |
5632 object->set_map(*new_map); | 5638 object->set_map(*new_map); |
5633 } | 5639 } |
5634 | 5640 |
5635 | 5641 |
5636 Handle<JSObject> JSObject::Copy(Handle<JSObject> object, | 5642 Handle<JSObject> JSObject::Copy(Handle<JSObject> object, |
5637 Handle<AllocationSite> site) { | 5643 Handle<AllocationSite> site) { |
5638 Isolate* isolate = object->GetIsolate(); | 5644 Isolate* isolate = object->GetIsolate(); |
5639 CALL_HEAP_FUNCTION(isolate, | 5645 CALL_HEAP_FUNCTION(isolate, |
5640 isolate->heap()->CopyJSObject(*object, *site), JSObject); | 5646 isolate->heap()->CopyJSObject(*object, *site), JSObject); |
(...skipping 1317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6958 } else { | 6964 } else { |
6959 new_map = Map::Copy(map); | 6965 new_map = Map::Copy(map); |
6960 } | 6966 } |
6961 | 6967 |
6962 Handle<TransitionArray> transitions = | 6968 Handle<TransitionArray> transitions = |
6963 Map::AddTransition(map, isolate->factory()->observed_symbol(), new_map, | 6969 Map::AddTransition(map, isolate->factory()->observed_symbol(), new_map, |
6964 FULL_TRANSITION); | 6970 FULL_TRANSITION); |
6965 | 6971 |
6966 map->set_transitions(*transitions); | 6972 map->set_transitions(*transitions); |
6967 | 6973 |
6968 new_map->set_is_observed(); | 6974 new_map->set_is_observed(true); |
6969 | 6975 |
6970 if (map->owns_descriptors()) { | 6976 if (map->owns_descriptors()) { |
6971 new_map->InitializeDescriptors(map->instance_descriptors()); | 6977 new_map->InitializeDescriptors(map->instance_descriptors()); |
6972 map->set_owns_descriptors(false); | 6978 map->set_owns_descriptors(false); |
6973 } | 6979 } |
6974 | 6980 |
6975 new_map->SetBackPointer(*map); | 6981 new_map->SetBackPointer(*map); |
6976 return new_map; | 6982 return new_map; |
6977 } | 6983 } |
6978 | 6984 |
(...skipping 4234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11213 #endif // ENABLE_DISASSEMBLER | 11219 #endif // ENABLE_DISASSEMBLER |
11214 | 11220 |
11215 | 11221 |
11216 MaybeObject* JSObject::SetFastElementsCapacityAndLength( | 11222 MaybeObject* JSObject::SetFastElementsCapacityAndLength( |
11217 int capacity, | 11223 int capacity, |
11218 int length, | 11224 int length, |
11219 SetFastElementsCapacitySmiMode smi_mode) { | 11225 SetFastElementsCapacitySmiMode smi_mode) { |
11220 Heap* heap = GetHeap(); | 11226 Heap* heap = GetHeap(); |
11221 // We should never end in here with a pixel or external array. | 11227 // We should never end in here with a pixel or external array. |
11222 ASSERT(!HasExternalArrayElements()); | 11228 ASSERT(!HasExternalArrayElements()); |
| 11229 ASSERT(!map()->is_observed()); |
11223 | 11230 |
11224 // Allocate a new fast elements backing store. | 11231 // Allocate a new fast elements backing store. |
11225 FixedArray* new_elements; | 11232 FixedArray* new_elements; |
11226 MaybeObject* maybe = heap->AllocateUninitializedFixedArray(capacity); | 11233 MaybeObject* maybe = heap->AllocateUninitializedFixedArray(capacity); |
11227 if (!maybe->To(&new_elements)) return maybe; | 11234 if (!maybe->To(&new_elements)) return maybe; |
11228 | 11235 |
11229 ElementsKind elements_kind = GetElementsKind(); | 11236 ElementsKind elements_kind = GetElementsKind(); |
11230 ElementsKind new_elements_kind; | 11237 ElementsKind new_elements_kind; |
11231 // The resized array has FAST_*_SMI_ELEMENTS if the capacity mode forces it, | 11238 // The resized array has FAST_*_SMI_ELEMENTS if the capacity mode forces it, |
11232 // or if it's allowed and the old elements array contained only SMIs. | 11239 // 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... |
11297 | 11304 |
11298 return false; | 11305 return false; |
11299 } | 11306 } |
11300 | 11307 |
11301 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( | 11308 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( |
11302 int capacity, | 11309 int capacity, |
11303 int length) { | 11310 int length) { |
11304 Heap* heap = GetHeap(); | 11311 Heap* heap = GetHeap(); |
11305 // We should never end in here with a pixel or external array. | 11312 // We should never end in here with a pixel or external array. |
11306 ASSERT(!HasExternalArrayElements()); | 11313 ASSERT(!HasExternalArrayElements()); |
| 11314 ASSERT(!map()->is_observed()); |
11307 | 11315 |
11308 FixedArrayBase* elems; | 11316 FixedArrayBase* elems; |
11309 { MaybeObject* maybe_obj = | 11317 { MaybeObject* maybe_obj = |
11310 heap->AllocateUninitializedFixedDoubleArray(capacity); | 11318 heap->AllocateUninitializedFixedDoubleArray(capacity); |
11311 if (!maybe_obj->To(&elems)) return maybe_obj; | 11319 if (!maybe_obj->To(&elems)) return maybe_obj; |
11312 } | 11320 } |
11313 | 11321 |
11314 ElementsKind elements_kind = GetElementsKind(); | 11322 ElementsKind elements_kind = GetElementsKind(); |
11315 ElementsKind new_elements_kind = elements_kind; | 11323 ElementsKind new_elements_kind = elements_kind; |
11316 if (IsHoleyElementsKind(elements_kind)) { | 11324 if (IsHoleyElementsKind(elements_kind)) { |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11445 List<uint32_t> indices; | 11453 List<uint32_t> indices; |
11446 List<Handle<Object> > old_values; | 11454 List<Handle<Object> > old_values; |
11447 Handle<Object> old_length_handle(self->length(), isolate); | 11455 Handle<Object> old_length_handle(self->length(), isolate); |
11448 Handle<Object> new_length_handle(len, isolate); | 11456 Handle<Object> new_length_handle(len, isolate); |
11449 uint32_t old_length = 0; | 11457 uint32_t old_length = 0; |
11450 CHECK(old_length_handle->ToArrayIndex(&old_length)); | 11458 CHECK(old_length_handle->ToArrayIndex(&old_length)); |
11451 uint32_t new_length = 0; | 11459 uint32_t new_length = 0; |
11452 if (!new_length_handle->ToArrayIndex(&new_length)) | 11460 if (!new_length_handle->ToArrayIndex(&new_length)) |
11453 return Failure::InternalError(); | 11461 return Failure::InternalError(); |
11454 | 11462 |
| 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()); |
11455 static const PropertyAttributes kNoAttrFilter = NONE; | 11467 static const PropertyAttributes kNoAttrFilter = NONE; |
11456 int num_elements = self->NumberOfLocalElements(kNoAttrFilter); | 11468 int num_elements = self->NumberOfLocalElements(kNoAttrFilter); |
11457 if (num_elements > 0) { | 11469 if (num_elements > 0) { |
11458 if (old_length == static_cast<uint32_t>(num_elements)) { | 11470 if (old_length == static_cast<uint32_t>(num_elements)) { |
11459 // Simple case for arrays without holes. | 11471 // Simple case for arrays without holes. |
11460 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) { | 11472 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) { |
11461 if (!GetOldValue(isolate, self, i, &old_values, &indices)) break; | 11473 if (!GetOldValue(isolate, self, i, &old_values, &indices)) break; |
11462 } | 11474 } |
11463 } else { | 11475 } else { |
11464 // For sparse arrays, only iterate over existing elements. | 11476 // 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. | |
11467 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements); | 11477 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements); |
11468 self->GetLocalElementKeys(*keys, kNoAttrFilter); | 11478 self->GetLocalElementKeys(*keys, kNoAttrFilter); |
11469 while (num_elements-- > 0) { | 11479 while (num_elements-- > 0) { |
11470 uint32_t index = NumberToUint32(keys->get(num_elements)); | 11480 uint32_t index = NumberToUint32(keys->get(num_elements)); |
11471 if (index < new_length) break; | 11481 if (index < new_length) break; |
11472 if (!GetOldValue(isolate, self, index, &old_values, &indices)) break; | 11482 if (!GetOldValue(isolate, self, index, &old_values, &indices)) break; |
11473 } | 11483 } |
11474 } | 11484 } |
11475 } | 11485 } |
11476 | 11486 |
(...skipping 1378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12855 ElementsKindToString(to_kind)); | 12865 ElementsKindToString(to_kind)); |
12856 } | 12866 } |
12857 site->set_transition_info(Smi::FromInt(to_kind)); | 12867 site->set_transition_info(Smi::FromInt(to_kind)); |
12858 } | 12868 } |
12859 } | 12869 } |
12860 return this; | 12870 return this; |
12861 } | 12871 } |
12862 | 12872 |
12863 | 12873 |
12864 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { | 12874 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { |
| 12875 ASSERT(!map()->is_observed()); |
12865 ElementsKind from_kind = map()->elements_kind(); | 12876 ElementsKind from_kind = map()->elements_kind(); |
12866 | 12877 |
12867 if (IsFastHoleyElementsKind(from_kind)) { | 12878 if (IsFastHoleyElementsKind(from_kind)) { |
12868 to_kind = GetHoleyElementsKind(to_kind); | 12879 to_kind = GetHoleyElementsKind(to_kind); |
12869 } | 12880 } |
12870 | 12881 |
12871 if (from_kind == to_kind) return this; | 12882 if (from_kind == to_kind) return this; |
12872 // Don't update the site if to_kind isn't fast | 12883 // Don't update the site if to_kind isn't fast |
12873 if (IsFastElementsKind(to_kind)) { | 12884 if (IsFastElementsKind(to_kind)) { |
12874 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); | 12885 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); |
(...skipping 3649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16524 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16535 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16525 static const char* error_messages_[] = { | 16536 static const char* error_messages_[] = { |
16526 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16537 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16527 }; | 16538 }; |
16528 #undef ERROR_MESSAGES_TEXTS | 16539 #undef ERROR_MESSAGES_TEXTS |
16529 return error_messages_[reason]; | 16540 return error_messages_[reason]; |
16530 } | 16541 } |
16531 | 16542 |
16532 | 16543 |
16533 } } // namespace v8::internal | 16544 } } // namespace v8::internal |
OLD | NEW |