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 |