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 6212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6223 return !AccessorInfo::cast(obj)->prohibits_overwriting(); | 6223 return !AccessorInfo::cast(obj)->prohibits_overwriting(); |
6224 } | 6224 } |
6225 if (obj->IsAccessorPair()) { | 6225 if (obj->IsAccessorPair()) { |
6226 return !AccessorPair::cast(obj)->prohibits_overwriting(); | 6226 return !AccessorPair::cast(obj)->prohibits_overwriting(); |
6227 } | 6227 } |
6228 } | 6228 } |
6229 return true; | 6229 return true; |
6230 } | 6230 } |
6231 | 6231 |
6232 | 6232 |
| 6233 bool Map::DictionaryElementsInPrototypeChain() { |
| 6234 Heap* heap = GetHeap(); |
| 6235 |
| 6236 if (IsDictionaryElementsKind(elements_kind())) { |
| 6237 return true; |
| 6238 } |
| 6239 |
| 6240 for (Object* prototype = this->prototype(); |
| 6241 prototype != heap->null_value(); |
| 6242 prototype = prototype->GetPrototype(GetIsolate())) { |
| 6243 if (prototype->IsJSProxy()) { |
| 6244 // Be conservative, don't walk into proxies. |
| 6245 return true; |
| 6246 } |
| 6247 |
| 6248 if (IsDictionaryElementsKind( |
| 6249 JSObject::cast(prototype)->map()->elements_kind())) { |
| 6250 return true; |
| 6251 } |
| 6252 } |
| 6253 |
| 6254 return false; |
| 6255 } |
| 6256 |
6233 void JSObject::SetElementCallback(Handle<JSObject> object, | 6257 void JSObject::SetElementCallback(Handle<JSObject> object, |
6234 uint32_t index, | 6258 uint32_t index, |
6235 Handle<Object> structure, | 6259 Handle<Object> structure, |
6236 PropertyAttributes attributes) { | 6260 PropertyAttributes attributes) { |
6237 Heap* heap = object->GetHeap(); | 6261 Heap* heap = object->GetHeap(); |
6238 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); | 6262 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); |
6239 | 6263 |
6240 // Normalize elements to make this operation simple. | 6264 // Normalize elements to make this operation simple. |
6241 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | 6265 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
6242 ASSERT(object->HasDictionaryElements() || | 6266 ASSERT(object->HasDictionaryElements() || |
(...skipping 4327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10570 if (--n == 0) { | 10594 if (--n == 0) { |
10571 info->set_target_cell(replace_with); | 10595 info->set_target_cell(replace_with); |
10572 return; | 10596 return; |
10573 } | 10597 } |
10574 } | 10598 } |
10575 UNREACHABLE(); | 10599 UNREACHABLE(); |
10576 } | 10600 } |
10577 | 10601 |
10578 | 10602 |
10579 void Code::ClearInlineCaches() { | 10603 void Code::ClearInlineCaches() { |
| 10604 ClearInlineCaches(NULL); |
| 10605 } |
| 10606 |
| 10607 |
| 10608 void Code::ClearInlineCaches(Code::Kind kind) { |
| 10609 ClearInlineCaches(&kind); |
| 10610 } |
| 10611 |
| 10612 |
| 10613 void Code::ClearInlineCaches(Code::Kind* kind) { |
10580 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | | 10614 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | |
10581 RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) | | 10615 RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) | |
10582 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID) | | 10616 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID) | |
10583 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_CONTEXT); | 10617 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_CONTEXT); |
10584 for (RelocIterator it(this, mask); !it.done(); it.next()) { | 10618 for (RelocIterator it(this, mask); !it.done(); it.next()) { |
10585 RelocInfo* info = it.rinfo(); | 10619 RelocInfo* info = it.rinfo(); |
10586 Code* target(Code::GetCodeFromTargetAddress(info->target_address())); | 10620 Code* target(Code::GetCodeFromTargetAddress(info->target_address())); |
10587 if (target->is_inline_cache_stub()) { | 10621 if (target->is_inline_cache_stub()) { |
10588 IC::Clear(this->GetIsolate(), info->pc()); | 10622 if (kind == NULL || *kind == target->kind()) { |
| 10623 IC::Clear(this->GetIsolate(), info->pc()); |
| 10624 } |
10589 } | 10625 } |
10590 } | 10626 } |
10591 } | 10627 } |
10592 | 10628 |
10593 | 10629 |
10594 void Code::ClearTypeFeedbackCells(Heap* heap) { | 10630 void Code::ClearTypeFeedbackCells(Heap* heap) { |
10595 if (kind() != FUNCTION) return; | 10631 if (kind() != FUNCTION) return; |
10596 Object* raw_info = type_feedback_info(); | 10632 Object* raw_info = type_feedback_info(); |
10597 if (raw_info->IsTypeFeedbackInfo()) { | 10633 if (raw_info->IsTypeFeedbackInfo()) { |
10598 TypeFeedbackCells* type_feedback_cells = | 10634 TypeFeedbackCells* type_feedback_cells = |
(...skipping 1152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11751 pt = pt->GetPrototype(isolate)) { | 11787 pt = pt->GetPrototype(isolate)) { |
11752 if (JSReceiver::cast(pt) == *object) { | 11788 if (JSReceiver::cast(pt) == *object) { |
11753 // Cycle detected. | 11789 // Cycle detected. |
11754 Handle<Object> error = isolate->factory()->NewError( | 11790 Handle<Object> error = isolate->factory()->NewError( |
11755 "cyclic_proto", HandleVector<Object>(NULL, 0)); | 11791 "cyclic_proto", HandleVector<Object>(NULL, 0)); |
11756 isolate->Throw(*error); | 11792 isolate->Throw(*error); |
11757 return Handle<Object>(); | 11793 return Handle<Object>(); |
11758 } | 11794 } |
11759 } | 11795 } |
11760 | 11796 |
| 11797 bool dictionary_elements_in_chain = |
| 11798 object->map()->DictionaryElementsInPrototypeChain(); |
11761 Handle<JSObject> real_receiver = object; | 11799 Handle<JSObject> real_receiver = object; |
11762 | 11800 |
11763 if (skip_hidden_prototypes) { | 11801 if (skip_hidden_prototypes) { |
11764 // Find the first object in the chain whose prototype object is not | 11802 // Find the first object in the chain whose prototype object is not |
11765 // hidden and set the new prototype on that object. | 11803 // hidden and set the new prototype on that object. |
11766 Object* current_proto = real_receiver->GetPrototype(); | 11804 Object* current_proto = real_receiver->GetPrototype(); |
11767 while (current_proto->IsJSObject() && | 11805 while (current_proto->IsJSObject() && |
11768 JSObject::cast(current_proto)->map()->is_hidden_prototype()) { | 11806 JSObject::cast(current_proto)->map()->is_hidden_prototype()) { |
11769 real_receiver = handle(JSObject::cast(current_proto), isolate); | 11807 real_receiver = handle(JSObject::cast(current_proto), isolate); |
11770 current_proto = current_proto->GetPrototype(isolate); | 11808 current_proto = current_proto->GetPrototype(isolate); |
(...skipping 12 matching lines...) Expand all Loading... |
11783 | 11821 |
11784 Handle<Map> new_map = Map::GetPrototypeTransition(map, value); | 11822 Handle<Map> new_map = Map::GetPrototypeTransition(map, value); |
11785 if (new_map.is_null()) { | 11823 if (new_map.is_null()) { |
11786 new_map = Map::Copy(map); | 11824 new_map = Map::Copy(map); |
11787 Map::PutPrototypeTransition(map, value, new_map); | 11825 Map::PutPrototypeTransition(map, value, new_map); |
11788 new_map->set_prototype(*value); | 11826 new_map->set_prototype(*value); |
11789 } | 11827 } |
11790 ASSERT(new_map->prototype() == *value); | 11828 ASSERT(new_map->prototype() == *value); |
11791 real_receiver->set_map(*new_map); | 11829 real_receiver->set_map(*new_map); |
11792 | 11830 |
| 11831 if (!dictionary_elements_in_chain && |
| 11832 new_map->DictionaryElementsInPrototypeChain()) { |
| 11833 // If the prototype chain didn't previously have element callbacks, then |
| 11834 // KeyedStoreICs need to be cleared to ensure any that involve this |
| 11835 // map go generic. |
| 11836 object->GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC); |
| 11837 } |
| 11838 |
11793 heap->ClearInstanceofCache(); | 11839 heap->ClearInstanceofCache(); |
11794 ASSERT(size == object->Size()); | 11840 ASSERT(size == object->Size()); |
11795 return value; | 11841 return value; |
11796 } | 11842 } |
11797 | 11843 |
11798 | 11844 |
11799 MaybeObject* JSObject::EnsureCanContainElements(Arguments* args, | 11845 MaybeObject* JSObject::EnsureCanContainElements(Arguments* args, |
11800 uint32_t first_arg, | 11846 uint32_t first_arg, |
11801 uint32_t arg_count, | 11847 uint32_t arg_count, |
11802 EnsureElementsMode mode) { | 11848 EnsureElementsMode mode) { |
(...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12771 | 12817 |
12772 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { | 12818 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { |
12773 ASSERT(!map()->is_observed()); | 12819 ASSERT(!map()->is_observed()); |
12774 ElementsKind from_kind = map()->elements_kind(); | 12820 ElementsKind from_kind = map()->elements_kind(); |
12775 | 12821 |
12776 if (IsFastHoleyElementsKind(from_kind)) { | 12822 if (IsFastHoleyElementsKind(from_kind)) { |
12777 to_kind = GetHoleyElementsKind(to_kind); | 12823 to_kind = GetHoleyElementsKind(to_kind); |
12778 } | 12824 } |
12779 | 12825 |
12780 if (from_kind == to_kind) return this; | 12826 if (from_kind == to_kind) return this; |
12781 | 12827 // Don't update the site if to_kind isn't fast |
12782 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); | 12828 if (IsFastElementsKind(to_kind)) { |
12783 if (maybe_failure->IsFailure()) return maybe_failure; | 12829 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); |
| 12830 if (maybe_failure->IsFailure()) return maybe_failure; |
| 12831 } |
12784 | 12832 |
12785 Isolate* isolate = GetIsolate(); | 12833 Isolate* isolate = GetIsolate(); |
12786 if (elements() == isolate->heap()->empty_fixed_array() || | 12834 if (elements() == isolate->heap()->empty_fixed_array() || |
12787 (IsFastSmiOrObjectElementsKind(from_kind) && | 12835 (IsFastSmiOrObjectElementsKind(from_kind) && |
12788 IsFastSmiOrObjectElementsKind(to_kind)) || | 12836 IsFastSmiOrObjectElementsKind(to_kind)) || |
12789 (from_kind == FAST_DOUBLE_ELEMENTS && | 12837 (from_kind == FAST_DOUBLE_ELEMENTS && |
12790 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) { | 12838 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) { |
12791 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND); | 12839 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND); |
12792 // No change is needed to the elements() buffer, the transition | 12840 // No change is needed to the elements() buffer, the transition |
12793 // only requires a map change. | 12841 // only requires a map change. |
(...skipping 3602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16396 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16444 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16397 static const char* error_messages_[] = { | 16445 static const char* error_messages_[] = { |
16398 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16446 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16399 }; | 16447 }; |
16400 #undef ERROR_MESSAGES_TEXTS | 16448 #undef ERROR_MESSAGES_TEXTS |
16401 return error_messages_[reason]; | 16449 return error_messages_[reason]; |
16402 } | 16450 } |
16403 | 16451 |
16404 | 16452 |
16405 } } // namespace v8::internal | 16453 } } // namespace v8::internal |
OLD | NEW |