OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
794 Register scratch2, | 794 Register scratch2, |
795 Register scratch3, | 795 Register scratch3, |
796 Handle<JSObject> interceptor_holder, | 796 Handle<JSObject> interceptor_holder, |
797 LookupResult* lookup, | 797 LookupResult* lookup, |
798 Handle<String> name, | 798 Handle<String> name, |
799 const CallOptimization& optimization, | 799 const CallOptimization& optimization, |
800 Label* miss_label) { | 800 Label* miss_label) { |
801 ASSERT(optimization.is_constant_call()); | 801 ASSERT(optimization.is_constant_call()); |
802 ASSERT(!lookup->holder()->IsGlobalObject()); | 802 ASSERT(!lookup->holder()->IsGlobalObject()); |
803 Counters* counters = masm->isolate()->counters(); | 803 Counters* counters = masm->isolate()->counters(); |
804 int depth1 = kInvalidProtoDepth; | 804 |
805 int depth2 = kInvalidProtoDepth; | 805 bool can_do_fast_api_call = !lookup->holder()->IsGlobalObject() && |
806 bool can_do_fast_api_call = false; | 806 optimization.is_simple_api_call() && |
807 if (optimization.is_simple_api_call() && | 807 optimization.IsCompatibleReceiver(object); |
808 !lookup->holder()->IsGlobalObject()) { | |
809 depth1 = optimization.GetPrototypeDepthOfExpectedType( | |
810 object, interceptor_holder); | |
811 if (depth1 == kInvalidProtoDepth) { | |
812 depth2 = optimization.GetPrototypeDepthOfExpectedType( | |
813 interceptor_holder, Handle<JSObject>(lookup->holder())); | |
814 } | |
815 can_do_fast_api_call = | |
816 depth1 != kInvalidProtoDepth || depth2 != kInvalidProtoDepth; | |
817 } | |
818 | 808 |
819 __ IncrementCounter(counters->call_const_interceptor(), 1, | 809 __ IncrementCounter(counters->call_const_interceptor(), 1, |
820 scratch1, scratch2); | 810 scratch1, scratch2); |
821 | 811 |
822 if (can_do_fast_api_call) { | 812 if (can_do_fast_api_call) { |
823 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1, | 813 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1, |
824 scratch1, scratch2); | 814 scratch1, scratch2); |
825 ReserveSpaceForFastApiCall(masm, scratch1); | 815 ReserveSpaceForFastApiCall(masm, scratch1); |
826 } | 816 } |
827 | 817 |
828 // Check that the maps from receiver to interceptor's holder | 818 // Check that the maps from receiver to interceptor's holder |
829 // haven't changed and thus we can invoke interceptor. | 819 // haven't changed and thus we can invoke interceptor. |
830 Label miss_cleanup; | 820 Label miss_cleanup; |
831 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; | 821 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; |
| 822 int depth = can_do_fast_api_call ? 0 : kInvalidProtoDepth; |
832 Register holder = | 823 Register holder = |
833 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, | 824 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, |
834 scratch1, scratch2, scratch3, | 825 scratch1, scratch2, scratch3, |
835 name, depth1, miss); | 826 name, depth, miss); |
836 | 827 |
837 // Invoke an interceptor and if it provides a value, | 828 // Invoke an interceptor and if it provides a value, |
838 // branch to |regular_invoke|. | 829 // branch to |regular_invoke|. |
839 Label regular_invoke; | 830 Label regular_invoke; |
840 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, scratch2, | 831 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, scratch2, |
841 ®ular_invoke); | 832 ®ular_invoke); |
842 | 833 |
843 // Interceptor returned nothing for this property. Try to use cached | 834 // Interceptor returned nothing for this property. Try to use cached |
844 // constant function. | 835 // constant function. |
845 | 836 |
846 // Check that the maps from interceptor's holder to constant function's | 837 // Check that the maps from interceptor's holder to constant function's |
847 // holder haven't changed and thus we can use cached constant function. | 838 // holder haven't changed and thus we can use cached constant function. |
| 839 // TODO(2268): Switch to return holder once embedders have adapted. |
848 if (*interceptor_holder != lookup->holder()) { | 840 if (*interceptor_holder != lookup->holder()) { |
849 stub_compiler_->CheckPrototypes(interceptor_holder, receiver, | 841 stub_compiler_->CheckPrototypes(interceptor_holder, receiver, |
850 Handle<JSObject>(lookup->holder()), | 842 Handle<JSObject>(lookup->holder()), |
851 scratch1, scratch2, scratch3, | 843 scratch1, scratch2, scratch3, |
852 name, depth2, miss); | 844 name, kInvalidProtoDepth, miss); |
853 } else { | |
854 // CheckPrototypes has a side effect of fetching a 'holder' | |
855 // for API (object which is instanceof for the signature). It's | |
856 // safe to omit it here, as if present, it should be fetched | |
857 // by the previous CheckPrototypes. | |
858 ASSERT(depth2 == kInvalidProtoDepth); | |
859 } | 845 } |
860 | 846 |
861 // Invoke function. | 847 // Invoke function. |
862 if (can_do_fast_api_call) { | 848 if (can_do_fast_api_call) { |
863 GenerateFastApiDirectCall(masm, optimization, arguments_.immediate()); | 849 GenerateFastApiDirectCall(masm, optimization, arguments_.immediate()); |
864 } else { | 850 } else { |
865 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 851 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) |
866 ? CALL_AS_FUNCTION | 852 ? CALL_AS_FUNCTION |
867 : CALL_AS_METHOD; | 853 : CALL_AS_METHOD; |
868 __ InvokeFunction(optimization.constant_function(), arguments_, | 854 __ InvokeFunction(optimization.constant_function(), arguments_, |
(...skipping 1548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2417 Handle<JSFunction> function, | 2403 Handle<JSFunction> function, |
2418 Handle<String> name) { | 2404 Handle<String> name) { |
2419 Counters* counters = isolate()->counters(); | 2405 Counters* counters = isolate()->counters(); |
2420 | 2406 |
2421 ASSERT(optimization.is_simple_api_call()); | 2407 ASSERT(optimization.is_simple_api_call()); |
2422 // Bail out if object is a global object as we don't want to | 2408 // Bail out if object is a global object as we don't want to |
2423 // repatch it to global receiver. | 2409 // repatch it to global receiver. |
2424 if (object->IsGlobalObject()) return Handle<Code>::null(); | 2410 if (object->IsGlobalObject()) return Handle<Code>::null(); |
2425 if (!cell.is_null()) return Handle<Code>::null(); | 2411 if (!cell.is_null()) return Handle<Code>::null(); |
2426 if (!object->IsJSObject()) return Handle<Code>::null(); | 2412 if (!object->IsJSObject()) return Handle<Code>::null(); |
2427 int depth = optimization.GetPrototypeDepthOfExpectedType( | 2413 if (!optimization.IsCompatibleReceiver(object)) return Handle<Code>::null(); |
2428 Handle<JSObject>::cast(object), holder); | |
2429 if (depth == kInvalidProtoDepth) return Handle<Code>::null(); | |
2430 | 2414 |
2431 Label miss, miss_before_stack_reserved; | 2415 Label miss, miss_before_stack_reserved; |
2432 GenerateNameCheck(name, &miss_before_stack_reserved); | 2416 GenerateNameCheck(name, &miss_before_stack_reserved); |
2433 | 2417 |
2434 // Get the receiver from the stack. | 2418 // Get the receiver from the stack. |
2435 const int argc = arguments().immediate(); | 2419 const int argc = arguments().immediate(); |
2436 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 2420 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
2437 | 2421 |
2438 // Check that the receiver isn't a smi. | 2422 // Check that the receiver isn't a smi. |
2439 __ JumpIfSmi(r1, &miss_before_stack_reserved); | 2423 __ JumpIfSmi(r1, &miss_before_stack_reserved); |
2440 | 2424 |
2441 __ IncrementCounter(counters->call_const(), 1, r0, r3); | 2425 __ IncrementCounter(counters->call_const(), 1, r0, r3); |
2442 __ IncrementCounter(counters->call_const_fast_api(), 1, r0, r3); | 2426 __ IncrementCounter(counters->call_const_fast_api(), 1, r0, r3); |
2443 | 2427 |
2444 ReserveSpaceForFastApiCall(masm(), r0); | 2428 ReserveSpaceForFastApiCall(masm(), r0); |
2445 | 2429 |
2446 // Check that the maps haven't changed and find a Holder as a side effect. | 2430 // Check that the maps haven't changed and find holder as a side effect. |
| 2431 // TODO(2268): Switch to return holder once embedders have adapted. |
2447 CheckPrototypes(Handle<JSObject>::cast(object), r1, holder, r0, r3, r4, name, | 2432 CheckPrototypes(Handle<JSObject>::cast(object), r1, holder, r0, r3, r4, name, |
2448 depth, &miss); | 2433 0, &miss); |
2449 | 2434 |
2450 GenerateFastApiDirectCall(masm(), optimization, argc); | 2435 GenerateFastApiDirectCall(masm(), optimization, argc); |
2451 | 2436 |
2452 __ bind(&miss); | 2437 __ bind(&miss); |
2453 FreeSpaceForFastApiCall(masm()); | 2438 FreeSpaceForFastApiCall(masm()); |
2454 | 2439 |
2455 __ bind(&miss_before_stack_reserved); | 2440 __ bind(&miss_before_stack_reserved); |
2456 GenerateMissBranch(); | 2441 GenerateMissBranch(); |
2457 | 2442 |
2458 // Return the generated code. | 2443 // Return the generated code. |
(...skipping 2364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4823 __ Jump(ic_slow, RelocInfo::CODE_TARGET); | 4808 __ Jump(ic_slow, RelocInfo::CODE_TARGET); |
4824 } | 4809 } |
4825 } | 4810 } |
4826 | 4811 |
4827 | 4812 |
4828 #undef __ | 4813 #undef __ |
4829 | 4814 |
4830 } } // namespace v8::internal | 4815 } } // namespace v8::internal |
4831 | 4816 |
4832 #endif // V8_TARGET_ARCH_ARM | 4817 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |