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 2930 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2941 bool has_pending_exception; | 2941 bool has_pending_exception; |
2942 Handle<Object> argv[] = { value }; | 2942 Handle<Object> argv[] = { value }; |
2943 Execution::Call( | 2943 Execution::Call( |
2944 isolate, setter, object, ARRAY_SIZE(argv), argv, &has_pending_exception); | 2944 isolate, setter, object, ARRAY_SIZE(argv), argv, &has_pending_exception); |
2945 // Check for pending exception and return the result. | 2945 // Check for pending exception and return the result. |
2946 if (has_pending_exception) return Handle<Object>(); | 2946 if (has_pending_exception) return Handle<Object>(); |
2947 return value; | 2947 return value; |
2948 } | 2948 } |
2949 | 2949 |
2950 | 2950 |
| 2951 bool JSReceiver::MayHaveIndexedCallbacksInPrototypeChain() { |
| 2952 Heap* heap = GetHeap(); |
| 2953 for (Object* pt = GetPrototype(); |
| 2954 pt != heap->null_value(); |
| 2955 pt = pt->GetPrototype(GetIsolate())) { |
| 2956 if (pt->IsJSProxy()) { |
| 2957 // Be conservative, don't walk into proxies. |
| 2958 return true; |
| 2959 } |
| 2960 |
| 2961 if (JSObject::cast(pt)->map()->has_element_callbacks()) { |
| 2962 return true; |
| 2963 } |
| 2964 } |
| 2965 |
| 2966 return false; |
| 2967 } |
| 2968 |
| 2969 |
2951 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( | 2970 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( |
2952 uint32_t index, | 2971 uint32_t index, |
2953 Object* value, | 2972 Object* value, |
2954 bool* found, | 2973 bool* found, |
2955 StrictModeFlag strict_mode) { | 2974 StrictModeFlag strict_mode) { |
2956 Heap* heap = GetHeap(); | 2975 Heap* heap = GetHeap(); |
2957 for (Object* pt = GetPrototype(); | 2976 for (Object* pt = GetPrototype(); |
2958 pt != heap->null_value(); | 2977 pt != heap->null_value(); |
2959 pt = pt->GetPrototype(GetIsolate())) { | 2978 pt = pt->GetPrototype(GetIsolate())) { |
2960 if (pt->IsJSProxy()) { | 2979 if (pt->IsJSProxy()) { |
(...skipping 3261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6222 } | 6241 } |
6223 return true; | 6242 return true; |
6224 } | 6243 } |
6225 | 6244 |
6226 | 6245 |
6227 void JSObject::SetElementCallback(Handle<JSObject> object, | 6246 void JSObject::SetElementCallback(Handle<JSObject> object, |
6228 uint32_t index, | 6247 uint32_t index, |
6229 Handle<Object> structure, | 6248 Handle<Object> structure, |
6230 PropertyAttributes attributes) { | 6249 PropertyAttributes attributes) { |
6231 Heap* heap = object->GetHeap(); | 6250 Heap* heap = object->GetHeap(); |
| 6251 Handle<Map> old_map(object->map()); |
6232 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); | 6252 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); |
6233 | 6253 |
6234 // Normalize elements to make this operation simple. | 6254 // Normalize elements to make this operation simple. |
6235 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | 6255 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
6236 ASSERT(object->HasDictionaryElements() || | 6256 ASSERT(object->HasDictionaryElements() || |
6237 object->HasDictionaryArgumentsElements()); | 6257 object->HasDictionaryArgumentsElements()); |
| 6258 bool map_changed = object->map() != *old_map; |
6238 | 6259 |
6239 // Update the dictionary with the new CALLBACKS property. | 6260 // Update the dictionary with the new CALLBACKS property. |
6240 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, | 6261 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, |
6241 details); | 6262 details); |
6242 dictionary->set_requires_slow_elements(); | 6263 dictionary->set_requires_slow_elements(); |
6243 | 6264 |
6244 // Update the dictionary backing store on the object. | 6265 // Update the dictionary backing store on the object. |
6245 if (object->elements()->map() == heap->non_strict_arguments_elements_map()) { | 6266 if (object->elements()->map() == heap->non_strict_arguments_elements_map()) { |
6246 // Also delete any parameter alias. | 6267 // Also delete any parameter alias. |
6247 // | 6268 // |
6248 // TODO(kmillikin): when deleting the last parameter alias we could | 6269 // TODO(kmillikin): when deleting the last parameter alias we could |
6249 // switch to a direct backing store without the parameter map. This | 6270 // switch to a direct backing store without the parameter map. This |
6250 // would allow GC of the context. | 6271 // would allow GC of the context. |
6251 FixedArray* parameter_map = FixedArray::cast(object->elements()); | 6272 FixedArray* parameter_map = FixedArray::cast(object->elements()); |
6252 if (index < static_cast<uint32_t>(parameter_map->length()) - 2) { | 6273 if (index < static_cast<uint32_t>(parameter_map->length()) - 2) { |
6253 parameter_map->set(index + 2, heap->the_hole_value()); | 6274 parameter_map->set(index + 2, heap->the_hole_value()); |
6254 } | 6275 } |
6255 parameter_map->set(1, *dictionary); | 6276 parameter_map->set(1, *dictionary); |
6256 } else { | 6277 } else { |
6257 object->set_elements(*dictionary); | 6278 object->set_elements(*dictionary); |
6258 } | 6279 } |
| 6280 |
| 6281 if (!object->map()->has_element_callbacks()) { |
| 6282 if (!map_changed) { |
| 6283 Handle<Map> new_map = Map::Copy(handle(object->map())); |
| 6284 object->set_map(*new_map); |
| 6285 } |
| 6286 object->map()->set_has_element_callbacks(true); |
| 6287 } |
| 6288 |
| 6289 // If we are the array prototype object, rebuild the cache. |
| 6290 Isolate* isolate = object->GetIsolate(); |
| 6291 if (isolate->initial_array_prototype().is_identical_to(object)) { |
| 6292 // Install the initial map, new_ek_map in the function prototype for |
| 6293 // array. |
| 6294 Handle<JSFunction> array_function( |
| 6295 isolate->global_context()->array_function(), isolate); |
| 6296 JSFunction::SetPrototype(array_function, object); |
| 6297 } else if (isolate->initial_object_prototype().is_identical_to(object)) { |
| 6298 Handle<JSFunction> object_function( |
| 6299 isolate->global_context()->object_function(), isolate); |
| 6300 JSFunction::SetPrototype(object_function, object); |
| 6301 } |
| 6302 |
| 6303 // TODO(mvstanton): With a dependency group we can avoid the need to |
| 6304 // deoptimize code that doesn't depend on the changed maps. Address this |
| 6305 // in a follow-up checkin. |
| 6306 Deoptimizer::DeoptimizeAll(object->GetIsolate()); |
| 6307 object->GetHeap()->ClearAllKeyedStoreICs(); |
6259 } | 6308 } |
6260 | 6309 |
6261 | 6310 |
6262 void JSObject::SetPropertyCallback(Handle<JSObject> object, | 6311 void JSObject::SetPropertyCallback(Handle<JSObject> object, |
6263 Handle<Name> name, | 6312 Handle<Name> name, |
6264 Handle<Object> structure, | 6313 Handle<Object> structure, |
6265 PropertyAttributes attributes) { | 6314 PropertyAttributes attributes) { |
6266 // Normalize object to make this operation simple. | 6315 // Normalize object to make this operation simple. |
6267 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | 6316 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
6268 | 6317 |
(...skipping 4301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10570 if (--n == 0) { | 10619 if (--n == 0) { |
10571 info->set_target_cell(replace_with); | 10620 info->set_target_cell(replace_with); |
10572 return; | 10621 return; |
10573 } | 10622 } |
10574 } | 10623 } |
10575 UNREACHABLE(); | 10624 UNREACHABLE(); |
10576 } | 10625 } |
10577 | 10626 |
10578 | 10627 |
10579 void Code::ClearInlineCaches() { | 10628 void Code::ClearInlineCaches() { |
| 10629 ClearInlineCaches(NULL); |
| 10630 } |
| 10631 |
| 10632 |
| 10633 void Code::ClearInlineCaches(Code::Kind kind) { |
| 10634 ClearInlineCaches(&kind); |
| 10635 } |
| 10636 |
| 10637 |
| 10638 void Code::ClearInlineCaches(Code::Kind* kind) { |
10580 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | | 10639 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | |
10581 RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) | | 10640 RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) | |
10582 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID) | | 10641 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID) | |
10583 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_CONTEXT); | 10642 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_CONTEXT); |
10584 for (RelocIterator it(this, mask); !it.done(); it.next()) { | 10643 for (RelocIterator it(this, mask); !it.done(); it.next()) { |
10585 RelocInfo* info = it.rinfo(); | 10644 RelocInfo* info = it.rinfo(); |
10586 Code* target(Code::GetCodeFromTargetAddress(info->target_address())); | 10645 Code* target(Code::GetCodeFromTargetAddress(info->target_address())); |
10587 if (target->is_inline_cache_stub()) { | 10646 if (target->is_inline_cache_stub()) { |
10588 IC::Clear(this->GetIsolate(), info->pc()); | 10647 if (kind == NULL || *kind == target->kind()) { |
| 10648 IC::Clear(this->GetIsolate(), info->pc()); |
| 10649 } |
10589 } | 10650 } |
10590 } | 10651 } |
10591 } | 10652 } |
10592 | 10653 |
10593 | 10654 |
10594 void Code::ClearTypeFeedbackCells(Heap* heap) { | 10655 void Code::ClearTypeFeedbackCells(Heap* heap) { |
10595 if (kind() != FUNCTION) return; | 10656 if (kind() != FUNCTION) return; |
10596 Object* raw_info = type_feedback_info(); | 10657 Object* raw_info = type_feedback_info(); |
10597 if (raw_info->IsTypeFeedbackInfo()) { | 10658 if (raw_info->IsTypeFeedbackInfo()) { |
10598 TypeFeedbackCells* type_feedback_cells = | 10659 TypeFeedbackCells* type_feedback_cells = |
(...skipping 2149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12748 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { | 12809 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { |
12749 ASSERT(!map()->is_observed()); | 12810 ASSERT(!map()->is_observed()); |
12750 ElementsKind from_kind = map()->elements_kind(); | 12811 ElementsKind from_kind = map()->elements_kind(); |
12751 | 12812 |
12752 if (IsFastHoleyElementsKind(from_kind)) { | 12813 if (IsFastHoleyElementsKind(from_kind)) { |
12753 to_kind = GetHoleyElementsKind(to_kind); | 12814 to_kind = GetHoleyElementsKind(to_kind); |
12754 } | 12815 } |
12755 | 12816 |
12756 if (from_kind == to_kind) return this; | 12817 if (from_kind == to_kind) return this; |
12757 | 12818 |
12758 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); | 12819 // Don't update the site if to_kind isn't fast |
12759 if (maybe_failure->IsFailure()) return maybe_failure; | 12820 if (IsFastElementsKind(to_kind)) { |
| 12821 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); |
| 12822 if (maybe_failure->IsFailure()) return maybe_failure; |
| 12823 } |
12760 | 12824 |
12761 Isolate* isolate = GetIsolate(); | 12825 Isolate* isolate = GetIsolate(); |
12762 if (elements() == isolate->heap()->empty_fixed_array() || | 12826 if (elements() == isolate->heap()->empty_fixed_array() || |
12763 (IsFastSmiOrObjectElementsKind(from_kind) && | 12827 (IsFastSmiOrObjectElementsKind(from_kind) && |
12764 IsFastSmiOrObjectElementsKind(to_kind)) || | 12828 IsFastSmiOrObjectElementsKind(to_kind)) || |
12765 (from_kind == FAST_DOUBLE_ELEMENTS && | 12829 (from_kind == FAST_DOUBLE_ELEMENTS && |
12766 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) { | 12830 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) { |
12767 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND); | 12831 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND); |
12768 // No change is needed to the elements() buffer, the transition | 12832 // No change is needed to the elements() buffer, the transition |
12769 // only requires a map change. | 12833 // only requires a map change. |
(...skipping 3616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16386 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16450 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16387 static const char* error_messages_[] = { | 16451 static const char* error_messages_[] = { |
16388 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16452 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16389 }; | 16453 }; |
16390 #undef ERROR_MESSAGES_TEXTS | 16454 #undef ERROR_MESSAGES_TEXTS |
16391 return error_messages_[reason]; | 16455 return error_messages_[reason]; |
16392 } | 16456 } |
16393 | 16457 |
16394 | 16458 |
16395 } } // namespace v8::internal | 16459 } } // namespace v8::internal |
OLD | NEW |