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 2905 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2916 bool has_pending_exception; | 2916 bool has_pending_exception; |
2917 Handle<Object> argv[] = { value }; | 2917 Handle<Object> argv[] = { value }; |
2918 Execution::Call( | 2918 Execution::Call( |
2919 isolate, setter, object, ARRAY_SIZE(argv), argv, &has_pending_exception); | 2919 isolate, setter, object, ARRAY_SIZE(argv), argv, &has_pending_exception); |
2920 // Check for pending exception and return the result. | 2920 // Check for pending exception and return the result. |
2921 if (has_pending_exception) return Handle<Object>(); | 2921 if (has_pending_exception) return Handle<Object>(); |
2922 return value; | 2922 return value; |
2923 } | 2923 } |
2924 | 2924 |
2925 | 2925 |
2926 bool JSReceiver::MayHaveIndexedCallbacksInPrototypeChain() { | |
2927 Heap* heap = GetHeap(); | |
2928 for (Object* pt = GetPrototype(); | |
2929 pt != heap->null_value(); | |
2930 pt = pt->GetPrototype(GetIsolate())) { | |
2931 if (pt->IsJSProxy()) { | |
2932 // Be conservative, don't walk into proxies. | |
2933 return true; | |
2934 } | |
2935 | |
2936 if (JSObject::cast(pt)->map()->has_element_callbacks()) { | |
2937 return true; | |
2938 } | |
2939 } | |
2940 | |
2941 return false; | |
2942 } | |
2943 | |
2944 | |
2926 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( | 2945 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( |
2927 uint32_t index, | 2946 uint32_t index, |
2928 Object* value, | 2947 Object* value, |
2929 bool* found, | 2948 bool* found, |
2930 StrictModeFlag strict_mode) { | 2949 StrictModeFlag strict_mode) { |
2931 Heap* heap = GetHeap(); | 2950 Heap* heap = GetHeap(); |
2932 for (Object* pt = GetPrototype(); | 2951 for (Object* pt = GetPrototype(); |
2933 pt != heap->null_value(); | 2952 pt != heap->null_value(); |
2934 pt = pt->GetPrototype(GetIsolate())) { | 2953 pt = pt->GetPrototype(GetIsolate())) { |
2935 if (pt->IsJSProxy()) { | 2954 if (pt->IsJSProxy()) { |
(...skipping 3261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6197 } | 6216 } |
6198 return true; | 6217 return true; |
6199 } | 6218 } |
6200 | 6219 |
6201 | 6220 |
6202 void JSObject::SetElementCallback(Handle<JSObject> object, | 6221 void JSObject::SetElementCallback(Handle<JSObject> object, |
6203 uint32_t index, | 6222 uint32_t index, |
6204 Handle<Object> structure, | 6223 Handle<Object> structure, |
6205 PropertyAttributes attributes) { | 6224 PropertyAttributes attributes) { |
6206 Heap* heap = object->GetHeap(); | 6225 Heap* heap = object->GetHeap(); |
6226 Handle<Map> old_map(object->map()); | |
6207 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); | 6227 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); |
6208 | 6228 |
6209 // Normalize elements to make this operation simple. | 6229 // Normalize elements to make this operation simple. |
6210 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | 6230 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
6211 ASSERT(object->HasDictionaryElements() || | 6231 ASSERT(object->HasDictionaryElements() || |
6212 object->HasDictionaryArgumentsElements()); | 6232 object->HasDictionaryArgumentsElements()); |
6233 bool map_changed = object->map() != *old_map; | |
6213 | 6234 |
6214 // Update the dictionary with the new CALLBACKS property. | 6235 // Update the dictionary with the new CALLBACKS property. |
6215 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, | 6236 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, |
6216 details); | 6237 details); |
6217 dictionary->set_requires_slow_elements(); | 6238 dictionary->set_requires_slow_elements(); |
6218 | 6239 |
6219 // Update the dictionary backing store on the object. | 6240 // Update the dictionary backing store on the object. |
6220 if (object->elements()->map() == heap->non_strict_arguments_elements_map()) { | 6241 if (object->elements()->map() == heap->non_strict_arguments_elements_map()) { |
6221 // Also delete any parameter alias. | 6242 // Also delete any parameter alias. |
6222 // | 6243 // |
6223 // TODO(kmillikin): when deleting the last parameter alias we could | 6244 // TODO(kmillikin): when deleting the last parameter alias we could |
6224 // switch to a direct backing store without the parameter map. This | 6245 // switch to a direct backing store without the parameter map. This |
6225 // would allow GC of the context. | 6246 // would allow GC of the context. |
6226 FixedArray* parameter_map = FixedArray::cast(object->elements()); | 6247 FixedArray* parameter_map = FixedArray::cast(object->elements()); |
6227 if (index < static_cast<uint32_t>(parameter_map->length()) - 2) { | 6248 if (index < static_cast<uint32_t>(parameter_map->length()) - 2) { |
6228 parameter_map->set(index + 2, heap->the_hole_value()); | 6249 parameter_map->set(index + 2, heap->the_hole_value()); |
6229 } | 6250 } |
6230 parameter_map->set(1, *dictionary); | 6251 parameter_map->set(1, *dictionary); |
6231 } else { | 6252 } else { |
6232 object->set_elements(*dictionary); | 6253 object->set_elements(*dictionary); |
6233 } | 6254 } |
6255 | |
6256 if (!object->map()->has_element_callbacks()) { | |
6257 if (!map_changed) { | |
6258 Handle<Map> new_map = Map::Copy(handle(object->map())); | |
6259 object->set_map(*new_map); | |
6260 } | |
6261 object->map()->set_has_element_callbacks(true); | |
danno
2013/10/23 12:22:11
This isn't quite right. You might "pollute" normal
| |
6262 } | |
6263 | |
6264 // If we are the array prototype object, rebuild the cache. | |
6265 Isolate* isolate = object->GetIsolate(); | |
6266 if (isolate->initial_array_prototype().is_identical_to(object)) { | |
6267 // Install the initial map, new_ek_map in the function prototype for | |
danno
2013/10/23 12:22:11
Is this comment correct?
| |
6268 // array. | |
6269 Handle<JSFunction> array_function( | |
6270 isolate->global_context()->array_function(), isolate); | |
6271 JSFunction::SetPrototype(array_function, object); | |
danno
2013/10/23 12:22:11
You are "rebuilding the cache" by side effect, whi
| |
6272 } else if (isolate->initial_object_prototype().is_identical_to(object)) { | |
6273 Handle<JSFunction> object_function( | |
6274 isolate->global_context()->object_function(), isolate); | |
6275 JSFunction::SetPrototype(object_function, object); | |
6276 } | |
6277 | |
6278 // TODO(mvstanton): With a dependency group we can avoid the need to | |
6279 // deoptimize code that doesn't depend on the changed maps. Address this | |
6280 // in a follow-up checkin. | |
6281 Deoptimizer::DeoptimizeAll(object->GetIsolate()); | |
danno
2013/10/23 12:22:11
Oh, *the humanity* Are you sure it can't be in thi
| |
6282 object->GetHeap()->ClearAllKeyedStoreICs(); | |
6234 } | 6283 } |
6235 | 6284 |
6236 | 6285 |
6237 void JSObject::SetPropertyCallback(Handle<JSObject> object, | 6286 void JSObject::SetPropertyCallback(Handle<JSObject> object, |
6238 Handle<Name> name, | 6287 Handle<Name> name, |
6239 Handle<Object> structure, | 6288 Handle<Object> structure, |
6240 PropertyAttributes attributes) { | 6289 PropertyAttributes attributes) { |
6241 // Normalize object to make this operation simple. | 6290 // Normalize object to make this operation simple. |
6242 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | 6291 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
6243 | 6292 |
(...skipping 4309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10553 if (--n == 0) { | 10602 if (--n == 0) { |
10554 info->set_target_cell(replace_with); | 10603 info->set_target_cell(replace_with); |
10555 return; | 10604 return; |
10556 } | 10605 } |
10557 } | 10606 } |
10558 UNREACHABLE(); | 10607 UNREACHABLE(); |
10559 } | 10608 } |
10560 | 10609 |
10561 | 10610 |
10562 void Code::ClearInlineCaches() { | 10611 void Code::ClearInlineCaches() { |
10612 ClearInlineCaches(NULL); | |
10613 } | |
10614 | |
10615 | |
10616 void Code::ClearInlineCaches(Code::Kind kind) { | |
10617 ClearInlineCaches(&kind); | |
10618 } | |
10619 | |
10620 | |
10621 void Code::ClearInlineCaches(Code::Kind* kind) { | |
10563 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | | 10622 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | |
10564 RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) | | 10623 RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) | |
10565 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID) | | 10624 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID) | |
10566 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_CONTEXT); | 10625 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_CONTEXT); |
10567 for (RelocIterator it(this, mask); !it.done(); it.next()) { | 10626 for (RelocIterator it(this, mask); !it.done(); it.next()) { |
10568 RelocInfo* info = it.rinfo(); | 10627 RelocInfo* info = it.rinfo(); |
10569 Code* target(Code::GetCodeFromTargetAddress(info->target_address())); | 10628 Code* target(Code::GetCodeFromTargetAddress(info->target_address())); |
10570 if (target->is_inline_cache_stub()) { | 10629 if (target->is_inline_cache_stub()) { |
10571 IC::Clear(this->GetIsolate(), info->pc()); | 10630 if (kind == NULL || *kind == target->kind()) { |
10631 IC::Clear(this->GetIsolate(), info->pc()); | |
10632 } | |
10572 } | 10633 } |
10573 } | 10634 } |
10574 } | 10635 } |
10575 | 10636 |
10576 | 10637 |
10577 void Code::ClearTypeFeedbackCells(Heap* heap) { | 10638 void Code::ClearTypeFeedbackCells(Heap* heap) { |
10578 if (kind() != FUNCTION) return; | 10639 if (kind() != FUNCTION) return; |
10579 Object* raw_info = type_feedback_info(); | 10640 Object* raw_info = type_feedback_info(); |
10580 if (raw_info->IsTypeFeedbackInfo()) { | 10641 if (raw_info->IsTypeFeedbackInfo()) { |
10581 TypeFeedbackCells* type_feedback_cells = | 10642 TypeFeedbackCells* type_feedback_cells = |
(...skipping 2149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12731 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { | 12792 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { |
12732 ASSERT(!map()->is_observed()); | 12793 ASSERT(!map()->is_observed()); |
12733 ElementsKind from_kind = map()->elements_kind(); | 12794 ElementsKind from_kind = map()->elements_kind(); |
12734 | 12795 |
12735 if (IsFastHoleyElementsKind(from_kind)) { | 12796 if (IsFastHoleyElementsKind(from_kind)) { |
12736 to_kind = GetHoleyElementsKind(to_kind); | 12797 to_kind = GetHoleyElementsKind(to_kind); |
12737 } | 12798 } |
12738 | 12799 |
12739 if (from_kind == to_kind) return this; | 12800 if (from_kind == to_kind) return this; |
12740 | 12801 |
12741 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); | 12802 // Don't update the site if to_kind isn't fast |
12742 if (maybe_failure->IsFailure()) return maybe_failure; | 12803 if (IsFastElementsKind(to_kind)) { |
12804 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); | |
12805 if (maybe_failure->IsFailure()) return maybe_failure; | |
12806 } | |
12743 | 12807 |
12744 Isolate* isolate = GetIsolate(); | 12808 Isolate* isolate = GetIsolate(); |
12745 if (elements() == isolate->heap()->empty_fixed_array() || | 12809 if (elements() == isolate->heap()->empty_fixed_array() || |
12746 (IsFastSmiOrObjectElementsKind(from_kind) && | 12810 (IsFastSmiOrObjectElementsKind(from_kind) && |
12747 IsFastSmiOrObjectElementsKind(to_kind)) || | 12811 IsFastSmiOrObjectElementsKind(to_kind)) || |
12748 (from_kind == FAST_DOUBLE_ELEMENTS && | 12812 (from_kind == FAST_DOUBLE_ELEMENTS && |
12749 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) { | 12813 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) { |
12750 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND); | 12814 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND); |
12751 // No change is needed to the elements() buffer, the transition | 12815 // No change is needed to the elements() buffer, the transition |
12752 // only requires a map change. | 12816 // only requires a map change. |
(...skipping 3621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
16374 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16438 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16375 static const char* error_messages_[] = { | 16439 static const char* error_messages_[] = { |
16376 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16440 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16377 }; | 16441 }; |
16378 #undef ERROR_MESSAGES_TEXTS | 16442 #undef ERROR_MESSAGES_TEXTS |
16379 return error_messages_[reason]; | 16443 return error_messages_[reason]; |
16380 } | 16444 } |
16381 | 16445 |
16382 | 16446 |
16383 } } // namespace v8::internal | 16447 } } // namespace v8::internal |
OLD | NEW |