| 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 |