| 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 |