| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/ic/ic.h" | 5 #include "src/ic/ic.h" |
| 6 | 6 |
| 7 #include <iostream> | 7 #include <iostream> |
| 8 | 8 |
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
| 10 #include "src/api-arguments-inl.h" | 10 #include "src/api-arguments-inl.h" |
| (...skipping 2090 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2101 if (accessors->IsAccessorInfo()) { | 2101 if (accessors->IsAccessorInfo()) { |
| 2102 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); | 2102 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); |
| 2103 DCHECK(v8::ToCData<Address>(info->setter()) != 0); | 2103 DCHECK(v8::ToCData<Address>(info->setter()) != 0); |
| 2104 DCHECK(!AccessorInfo::cast(*accessors)->is_special_data_property() || | 2104 DCHECK(!AccessorInfo::cast(*accessors)->is_special_data_property() || |
| 2105 lookup->HolderIsReceiverOrHiddenPrototype()); | 2105 lookup->HolderIsReceiverOrHiddenPrototype()); |
| 2106 DCHECK(AccessorInfo::IsCompatibleReceiverMap(isolate(), info, | 2106 DCHECK(AccessorInfo::IsCompatibleReceiverMap(isolate(), info, |
| 2107 receiver_map())); | 2107 receiver_map())); |
| 2108 DCHECK(!info->is_sloppy() || receiver->IsJSReceiver()); | 2108 DCHECK(!info->is_sloppy() || receiver->IsJSReceiver()); |
| 2109 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreCallback); | 2109 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreCallback); |
| 2110 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); | 2110 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); |
| 2111 // TODO(ishell): don't hard-code language mode into the handler because |
| 2112 // this handler can be re-used through megamorphic stub cache for wrong |
| 2113 // language mode. |
| 2114 // Better pass vector/slot to Runtime::kStoreCallbackProperty and |
| 2115 // let it decode the language mode from the IC kind. |
| 2111 Handle<Code> code = compiler.CompileStoreCallback( | 2116 Handle<Code> code = compiler.CompileStoreCallback( |
| 2112 receiver, lookup->name(), info, language_mode()); | 2117 receiver, lookup->name(), info, language_mode()); |
| 2113 return code; | 2118 return code; |
| 2114 } else { | 2119 } else { |
| 2115 DCHECK(accessors->IsAccessorPair()); | 2120 DCHECK(accessors->IsAccessorPair()); |
| 2116 Handle<Object> setter(Handle<AccessorPair>::cast(accessors)->setter(), | 2121 Handle<Object> setter(Handle<AccessorPair>::cast(accessors)->setter(), |
| 2117 isolate()); | 2122 isolate()); |
| 2118 DCHECK(setter->IsJSFunction() || setter->IsFunctionTemplateInfo()); | 2123 DCHECK(setter->IsJSFunction() || setter->IsFunctionTemplateInfo()); |
| 2119 CallOptimization call_optimization(setter); | 2124 CallOptimization call_optimization(setter); |
| 2120 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); | 2125 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); |
| (...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2644 ic.UpdateState(receiver, key); | 2649 ic.UpdateState(receiver, key); |
| 2645 RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value)); | 2650 RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value)); |
| 2646 } | 2651 } |
| 2647 | 2652 |
| 2648 | 2653 |
| 2649 RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) { | 2654 RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) { |
| 2650 HandleScope scope(isolate); | 2655 HandleScope scope(isolate); |
| 2651 DCHECK_EQ(5, args.length()); | 2656 DCHECK_EQ(5, args.length()); |
| 2652 // Runtime functions don't follow the IC's calling convention. | 2657 // Runtime functions don't follow the IC's calling convention. |
| 2653 Handle<Object> value = args.at(0); | 2658 Handle<Object> value = args.at(0); |
| 2654 // slot and vector parameters are not used. | 2659 Handle<Smi> slot = args.at<Smi>(1); |
| 2660 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2); |
| 2655 Handle<Object> object = args.at(3); | 2661 Handle<Object> object = args.at(3); |
| 2656 Handle<Object> key = args.at(4); | 2662 Handle<Object> key = args.at(4); |
| 2657 LanguageMode language_mode; | 2663 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); |
| 2658 KeyedStoreICNexus nexus(isolate); | 2664 LanguageMode language_mode = vector->GetLanguageMode(vector_slot); |
| 2659 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); | |
| 2660 language_mode = ic.language_mode(); | |
| 2661 RETURN_RESULT_OR_FAILURE( | 2665 RETURN_RESULT_OR_FAILURE( |
| 2662 isolate, | 2666 isolate, |
| 2663 Runtime::SetObjectProperty(isolate, object, key, value, language_mode)); | 2667 Runtime::SetObjectProperty(isolate, object, key, value, language_mode)); |
| 2664 } | 2668 } |
| 2665 | 2669 |
| 2666 | 2670 |
| 2667 RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) { | 2671 RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) { |
| 2668 HandleScope scope(isolate); | 2672 HandleScope scope(isolate); |
| 2673 DCHECK_EQ(6, args.length()); |
| 2669 // Runtime functions don't follow the IC's calling convention. | 2674 // Runtime functions don't follow the IC's calling convention. |
| 2670 Handle<Object> object = args.at(0); | 2675 Handle<Object> object = args.at(0); |
| 2671 Handle<Object> key = args.at(1); | 2676 Handle<Object> key = args.at(1); |
| 2672 Handle<Object> value = args.at(2); | 2677 Handle<Object> value = args.at(2); |
| 2673 Handle<Map> map = args.at<Map>(3); | 2678 Handle<Map> map = args.at<Map>(3); |
| 2674 LanguageMode language_mode; | 2679 Handle<Smi> slot = args.at<Smi>(4); |
| 2675 KeyedStoreICNexus nexus(isolate); | 2680 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(5); |
| 2676 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); | 2681 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); |
| 2677 language_mode = ic.language_mode(); | 2682 LanguageMode language_mode = vector->GetLanguageMode(vector_slot); |
| 2678 if (object->IsJSObject()) { | 2683 if (object->IsJSObject()) { |
| 2679 JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), | 2684 JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), |
| 2680 map->elements_kind()); | 2685 map->elements_kind()); |
| 2681 } | 2686 } |
| 2682 RETURN_RESULT_OR_FAILURE( | 2687 RETURN_RESULT_OR_FAILURE( |
| 2683 isolate, | 2688 isolate, |
| 2684 Runtime::SetObjectProperty(isolate, object, key, value, language_mode)); | 2689 Runtime::SetObjectProperty(isolate, object, key, value, language_mode)); |
| 2685 } | 2690 } |
| 2686 | 2691 |
| 2687 | 2692 |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3074 } | 3079 } |
| 3075 | 3080 |
| 3076 // Throw a reference error. | 3081 // Throw a reference error. |
| 3077 THROW_NEW_ERROR_RETURN_FAILURE( | 3082 THROW_NEW_ERROR_RETURN_FAILURE( |
| 3078 isolate, NewReferenceError(MessageTemplate::kNotDefined, it.name())); | 3083 isolate, NewReferenceError(MessageTemplate::kNotDefined, it.name())); |
| 3079 } | 3084 } |
| 3080 | 3085 |
| 3081 | 3086 |
| 3082 RUNTIME_FUNCTION(Runtime_StorePropertyWithInterceptor) { | 3087 RUNTIME_FUNCTION(Runtime_StorePropertyWithInterceptor) { |
| 3083 HandleScope scope(isolate); | 3088 HandleScope scope(isolate); |
| 3084 DCHECK(args.length() == 3); | 3089 DCHECK_EQ(5, args.length()); |
| 3085 StoreICNexus nexus(isolate); | 3090 // Runtime functions don't follow the IC's calling convention. |
| 3086 StoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); | 3091 Handle<Object> value = args.at(0); |
| 3087 Handle<JSObject> receiver = args.at<JSObject>(0); | 3092 Handle<Smi> slot = args.at<Smi>(1); |
| 3088 Handle<Name> name = args.at<Name>(1); | 3093 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2); |
| 3089 Handle<Object> value = args.at(2); | 3094 Handle<JSObject> receiver = args.at<JSObject>(3); |
| 3095 Handle<Name> name = args.at<Name>(4); |
| 3096 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); |
| 3097 LanguageMode language_mode = vector->GetLanguageMode(vector_slot); |
| 3090 | 3098 |
| 3091 DCHECK(receiver->HasNamedInterceptor()); | 3099 DCHECK(receiver->HasNamedInterceptor()); |
| 3092 InterceptorInfo* interceptor = receiver->GetNamedInterceptor(); | 3100 InterceptorInfo* interceptor = receiver->GetNamedInterceptor(); |
| 3093 DCHECK(!interceptor->non_masking()); | 3101 DCHECK(!interceptor->non_masking()); |
| 3094 PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver, | 3102 PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver, |
| 3095 *receiver, Object::DONT_THROW); | 3103 *receiver, Object::DONT_THROW); |
| 3096 | 3104 |
| 3097 v8::GenericNamedPropertySetterCallback setter = | 3105 v8::GenericNamedPropertySetterCallback setter = |
| 3098 v8::ToCData<v8::GenericNamedPropertySetterCallback>( | 3106 v8::ToCData<v8::GenericNamedPropertySetterCallback>( |
| 3099 interceptor->setter()); | 3107 interceptor->setter()); |
| 3100 Handle<Object> result = arguments.Call(setter, name, value); | 3108 Handle<Object> result = arguments.Call(setter, name, value); |
| 3101 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 3109 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
| 3102 if (!result.is_null()) return *value; | 3110 if (!result.is_null()) return *value; |
| 3103 | 3111 |
| 3104 LookupIterator it(receiver, name, receiver); | 3112 LookupIterator it(receiver, name, receiver); |
| 3105 // Skip past any access check on the receiver. | 3113 // Skip past any access check on the receiver. |
| 3106 if (it.state() == LookupIterator::ACCESS_CHECK) { | 3114 if (it.state() == LookupIterator::ACCESS_CHECK) { |
| 3107 DCHECK(it.HasAccess()); | 3115 DCHECK(it.HasAccess()); |
| 3108 it.Next(); | 3116 it.Next(); |
| 3109 } | 3117 } |
| 3110 // Skip past the interceptor on the receiver. | 3118 // Skip past the interceptor on the receiver. |
| 3111 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); | 3119 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); |
| 3112 it.Next(); | 3120 it.Next(); |
| 3113 | 3121 |
| 3114 MAYBE_RETURN(Object::SetProperty(&it, value, ic.language_mode(), | 3122 MAYBE_RETURN(Object::SetProperty(&it, value, language_mode, |
| 3115 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED), | 3123 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED), |
| 3116 isolate->heap()->exception()); | 3124 isolate->heap()->exception()); |
| 3117 return *value; | 3125 return *value; |
| 3118 } | 3126 } |
| 3119 | 3127 |
| 3120 | 3128 |
| 3121 RUNTIME_FUNCTION(Runtime_LoadElementWithInterceptor) { | 3129 RUNTIME_FUNCTION(Runtime_LoadElementWithInterceptor) { |
| 3122 // TODO(verwaest): This should probably get the holder and receiver as input. | 3130 // TODO(verwaest): This should probably get the holder and receiver as input. |
| 3123 HandleScope scope(isolate); | 3131 HandleScope scope(isolate); |
| 3124 Handle<JSObject> receiver = args.at<JSObject>(0); | 3132 Handle<JSObject> receiver = args.at<JSObject>(0); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3140 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); | 3148 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); |
| 3141 it.Next(); | 3149 it.Next(); |
| 3142 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | 3150 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
| 3143 Object::GetProperty(&it)); | 3151 Object::GetProperty(&it)); |
| 3144 } | 3152 } |
| 3145 | 3153 |
| 3146 return *result; | 3154 return *result; |
| 3147 } | 3155 } |
| 3148 } // namespace internal | 3156 } // namespace internal |
| 3149 } // namespace v8 | 3157 } // namespace v8 |
| OLD | NEW |