Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(832)

Side by Side Diff: src/ic/ic.cc

Issue 1810083003: Inline fast-path interceptor access in the IC utilities (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/api.h" 8 #include "src/api.h"
9 #include "src/api-arguments.h" 9 #include "src/api-arguments.h"
10 #include "src/arguments.h" 10 #include "src/arguments.h"
(...skipping 1404 matching lines...) Expand 10 before | Expand all | Expand 10 after
1415 switch (it->state()) { 1415 switch (it->state()) {
1416 case LookupIterator::NOT_FOUND: 1416 case LookupIterator::NOT_FOUND:
1417 case LookupIterator::TRANSITION: 1417 case LookupIterator::TRANSITION:
1418 UNREACHABLE(); 1418 UNREACHABLE();
1419 case LookupIterator::JSPROXY: 1419 case LookupIterator::JSPROXY:
1420 return false; 1420 return false;
1421 case LookupIterator::INTERCEPTOR: { 1421 case LookupIterator::INTERCEPTOR: {
1422 Handle<JSObject> holder = it->GetHolder<JSObject>(); 1422 Handle<JSObject> holder = it->GetHolder<JSObject>();
1423 InterceptorInfo* info = holder->GetNamedInterceptor(); 1423 InterceptorInfo* info = holder->GetNamedInterceptor();
1424 if (it->HolderIsReceiverOrHiddenPrototype()) { 1424 if (it->HolderIsReceiverOrHiddenPrototype()) {
1425 if (!info->setter()->IsUndefined()) return true; 1425 return !info->non_masking() && receiver.is_identical_to(holder) &&
1426 !info->setter()->IsUndefined();
1426 } else if (!info->getter()->IsUndefined() || 1427 } else if (!info->getter()->IsUndefined() ||
1427 !info->query()->IsUndefined()) { 1428 !info->query()->IsUndefined()) {
1428 return false; 1429 return false;
1429 } 1430 }
1430 break; 1431 break;
1431 } 1432 }
1432 case LookupIterator::ACCESS_CHECK: 1433 case LookupIterator::ACCESS_CHECK:
1433 if (it->GetHolder<JSObject>()->IsAccessCheckNeeded()) return false; 1434 if (it->GetHolder<JSObject>()->IsAccessCheckNeeded()) return false;
1434 break; 1435 break;
1435 case LookupIterator::ACCESSOR: 1436 case LookupIterator::ACCESSOR:
(...skipping 1364 matching lines...) Expand 10 before | Expand all | Expand 10 after
2800 PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver, 2801 PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver,
2801 *holder, Object::DONT_THROW); 2802 *holder, Object::DONT_THROW);
2802 2803
2803 v8::GenericNamedPropertyGetterCallback getter = 2804 v8::GenericNamedPropertyGetterCallback getter =
2804 v8::ToCData<v8::GenericNamedPropertyGetterCallback>( 2805 v8::ToCData<v8::GenericNamedPropertyGetterCallback>(
2805 interceptor->getter()); 2806 interceptor->getter());
2806 Handle<Object> result = arguments.Call(getter, name); 2807 Handle<Object> result = arguments.Call(getter, name);
2807 2808
2808 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); 2809 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
2809 2810
2810 Handle<Object> result_internal; 2811 if (!result.is_null()) return *result;
2811 if (result.is_null()) { 2812 return isolate->heap()->no_interceptor_result_sentinel();
2812 return isolate->heap()->no_interceptor_result_sentinel();
2813 }
2814 return *result;
2815 } 2813 }
2816 2814
2817 2815
2818 /** 2816 /**
2819 * Loads a property with an interceptor performing post interceptor 2817 * Loads a property with an interceptor performing post interceptor
2820 * lookup if interceptor failed. 2818 * lookup if interceptor failed.
2821 */ 2819 */
2822 RUNTIME_FUNCTION(Runtime_LoadPropertyWithInterceptor) { 2820 RUNTIME_FUNCTION(Runtime_LoadPropertyWithInterceptor) {
2823 HandleScope scope(isolate); 2821 HandleScope scope(isolate);
2824 DCHECK(args.length() == NamedLoadHandlerCompiler::kInterceptorArgsLength); 2822 DCHECK(args.length() == NamedLoadHandlerCompiler::kInterceptorArgsLength);
2825 Handle<Name> name = 2823 Handle<Name> name =
2826 args.at<Name>(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex); 2824 args.at<Name>(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex);
2827 Handle<JSObject> receiver = 2825 Handle<JSObject> receiver =
2828 args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex); 2826 args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex);
2829 Handle<JSObject> holder = 2827 Handle<JSObject> holder =
2830 args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex); 2828 args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex);
2831 2829
2832 Handle<Object> result; 2830 InterceptorInfo* interceptor = holder->GetNamedInterceptor();
2831 PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver,
2832 *holder, Object::DONT_THROW);
2833
2834 v8::GenericNamedPropertyGetterCallback getter =
2835 v8::ToCData<v8::GenericNamedPropertyGetterCallback>(
2836 interceptor->getter());
2837 Handle<Object> result = arguments.Call(getter, name);
2838
2839 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
2840
2841 if (!result.is_null()) return *result;
2842
2833 LookupIterator it(receiver, name, holder); 2843 LookupIterator it(receiver, name, holder);
2834 // TODO(conradw): Investigate strong mode semantics for this. 2844 // Skip any lookup work until we hit the (possibly non-masking) interceptor.
2845 while (it.state() != LookupIterator::INTERCEPTOR ||
2846 !it.GetHolder<JSObject>().is_identical_to(holder)) {
2847 DCHECK(it.state() != LookupIterator::ACCESS_CHECK || it.HasAccess());
2848 it.Next();
2849 }
2850 // Skip past the interceptor.
2851 it.Next();
2835 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it)); 2852 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it));
2836 2853
2837 if (it.IsFound()) return *result; 2854 if (it.IsFound()) return *result;
2838 2855
2839 // Return the undefined result if the reference error should not be thrown.
2840 // Note that both keyed and non-keyed loads may end up here.
2841 LoadICNexus nexus(isolate); 2856 LoadICNexus nexus(isolate);
2842 LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); 2857 LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
2843 if (!ic.ShouldThrowReferenceError(it.GetReceiver())) { 2858 if (!ic.ShouldThrowReferenceError(it.GetReceiver())) {
2844 return isolate->heap()->undefined_value(); 2859 return isolate->heap()->undefined_value();
2845 } 2860 }
2846 2861
2847 // Throw a reference error. 2862 // Throw a reference error.
2848 THROW_NEW_ERROR_RETURN_FAILURE( 2863 THROW_NEW_ERROR_RETURN_FAILURE(
2849 isolate, NewReferenceError(MessageTemplate::kNotDefined, it.name())); 2864 isolate, NewReferenceError(MessageTemplate::kNotDefined, it.name()));
2850 } 2865 }
2851 2866
2852 2867
2853 RUNTIME_FUNCTION(Runtime_StorePropertyWithInterceptor) { 2868 RUNTIME_FUNCTION(Runtime_StorePropertyWithInterceptor) {
2854 HandleScope scope(isolate); 2869 HandleScope scope(isolate);
2855 DCHECK(args.length() == 3); 2870 DCHECK(args.length() == 3);
2856 StoreICNexus nexus(isolate); 2871 StoreICNexus nexus(isolate);
2857 StoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); 2872 StoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
2858 Handle<JSObject> receiver = args.at<JSObject>(0); 2873 Handle<JSObject> receiver = args.at<JSObject>(0);
2859 Handle<Name> name = args.at<Name>(1); 2874 Handle<Name> name = args.at<Name>(1);
2860 Handle<Object> value = args.at<Object>(2); 2875 Handle<Object> value = args.at<Object>(2);
2861 #ifdef DEBUG 2876
2862 PrototypeIterator iter(isolate, receiver, 2877 DCHECK(receiver->HasNamedInterceptor());
2863 PrototypeIterator::START_AT_RECEIVER, 2878 InterceptorInfo* interceptor = receiver->GetNamedInterceptor();
2864 PrototypeIterator::END_AT_NON_HIDDEN); 2879 DCHECK(!interceptor->non_masking());
2865 bool found = false; 2880 PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver,
2866 for (; !iter.IsAtEnd(); iter.Advance()) { 2881 *receiver, Object::DONT_THROW);
2867 Handle<Object> current = PrototypeIterator::GetCurrent(iter); 2882
2868 if (current->IsJSObject() && 2883 v8::GenericNamedPropertySetterCallback setter =
2869 Handle<JSObject>::cast(current)->HasNamedInterceptor()) { 2884 v8::ToCData<v8::GenericNamedPropertySetterCallback>(
2870 found = true; 2885 interceptor->setter());
2871 break; 2886 Handle<Object> result = arguments.Call(setter, name, value);
2872 } 2887 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
2888 if (!result.is_null()) return *value;
2889
2890 LookupIterator it(receiver, name, receiver);
2891 // Skip past any access check on the receiver.
2892 if (it.state() == LookupIterator::ACCESS_CHECK) {
2893 DCHECK(it.HasAccess());
2894 it.Next();
2873 } 2895 }
2874 DCHECK(found); 2896 // Skip past the interceptor on the receiver.
2875 #endif 2897 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state());
2876 Handle<Object> result; 2898 it.Next();
2877 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2899
2878 isolate, result, 2900 MAYBE_RETURN(Object::SetProperty(&it, value, ic.language_mode(),
2879 JSObject::SetProperty(receiver, name, value, ic.language_mode())); 2901 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED),
2880 return *result; 2902 isolate->heap()->exception());
2903 return *value;
2881 } 2904 }
2882 2905
2883 2906
2884 RUNTIME_FUNCTION(Runtime_LoadElementWithInterceptor) { 2907 RUNTIME_FUNCTION(Runtime_LoadElementWithInterceptor) {
2885 // TODO(verwaest): This should probably get the holder and receiver as input. 2908 // TODO(verwaest): This should probably get the holder and receiver as input.
2886 HandleScope scope(isolate); 2909 HandleScope scope(isolate);
2887 Handle<JSObject> receiver = args.at<JSObject>(0); 2910 Handle<JSObject> receiver = args.at<JSObject>(0);
2888 DCHECK(args.smi_at(1) >= 0); 2911 DCHECK(args.smi_at(1) >= 0);
2889 uint32_t index = args.smi_at(1); 2912 uint32_t index = args.smi_at(1);
2890 2913
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2936 KeyedLoadICNexus nexus(vector, vector_slot); 2959 KeyedLoadICNexus nexus(vector, vector_slot);
2937 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); 2960 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
2938 ic.UpdateState(receiver, key); 2961 ic.UpdateState(receiver, key);
2939 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); 2962 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
2940 } 2963 }
2941 2964
2942 return *result; 2965 return *result;
2943 } 2966 }
2944 } // namespace internal 2967 } // namespace internal
2945 } // namespace v8 2968 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698