OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 #if V8_TARGET_ARCH_S390 | 5 #if V8_TARGET_ARCH_S390 |
6 | 6 |
7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 | 514 |
515 static void Generate_JSConstructStubHelper(MacroAssembler* masm, | 515 static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
516 bool is_api_function, | 516 bool is_api_function, |
517 bool create_implicit_receiver, | 517 bool create_implicit_receiver, |
518 bool check_derived_construct) { | 518 bool check_derived_construct) { |
519 // ----------- S t a t e ------------- | 519 // ----------- S t a t e ------------- |
520 // -- r2 : number of arguments | 520 // -- r2 : number of arguments |
521 // -- r3 : constructor function | 521 // -- r3 : constructor function |
522 // -- r4 : allocation site or undefined | 522 // -- r4 : allocation site or undefined |
523 // -- r5 : new target | 523 // -- r5 : new target |
| 524 // -- cp : context |
524 // -- lr : return address | 525 // -- lr : return address |
525 // -- sp[...]: constructor arguments | 526 // -- sp[...]: constructor arguments |
526 // ----------------------------------- | 527 // ----------------------------------- |
527 | 528 |
528 Isolate* isolate = masm->isolate(); | 529 Isolate* isolate = masm->isolate(); |
529 | 530 |
530 // Enter a construct frame. | 531 // Enter a construct frame. |
531 { | 532 { |
532 FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT); | 533 FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT); |
533 | 534 |
534 // Preserve the incoming parameters on the stack. | 535 // Preserve the incoming parameters on the stack. |
535 __ AssertUndefinedOrAllocationSite(r4, r6); | 536 __ AssertUndefinedOrAllocationSite(r4, r6); |
536 | 537 |
537 if (!create_implicit_receiver) { | 538 if (!create_implicit_receiver) { |
538 __ SmiTag(r6, r2); | 539 __ SmiTag(r6, r2); |
539 __ LoadAndTestP(r6, r6); | 540 __ LoadAndTestP(r6, r6); |
540 __ Push(r4, r6); | 541 __ Push(cp, r4, r6); |
541 __ PushRoot(Heap::kTheHoleValueRootIndex); | 542 __ PushRoot(Heap::kTheHoleValueRootIndex); |
542 } else { | 543 } else { |
543 __ SmiTag(r2); | 544 __ SmiTag(r2); |
544 __ Push(r4, r2); | 545 __ Push(cp, r4, r2); |
545 | 546 |
546 // Allocate the new receiver object. | 547 // Allocate the new receiver object. |
547 __ Push(r3, r5); | 548 __ Push(r3, r5); |
548 FastNewObjectStub stub(masm->isolate()); | 549 FastNewObjectStub stub(masm->isolate()); |
549 __ CallStub(&stub); | 550 __ CallStub(&stub); |
550 __ LoadRR(r6, r2); | 551 __ LoadRR(r6, r2); |
551 __ Pop(r3, r5); | 552 __ Pop(r3, r5); |
552 | 553 |
553 // ----------- S t a t e ------------- | 554 // ----------- S t a t e ------------- |
554 // -- r3: constructor function | 555 // -- r3: constructor function |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 | 608 |
608 // Store offset of return address for deoptimizer. | 609 // Store offset of return address for deoptimizer. |
609 if (create_implicit_receiver && !is_api_function) { | 610 if (create_implicit_receiver && !is_api_function) { |
610 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); | 611 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); |
611 } | 612 } |
612 | 613 |
613 // Restore context from the frame. | 614 // Restore context from the frame. |
614 // r2: result | 615 // r2: result |
615 // sp[0]: receiver | 616 // sp[0]: receiver |
616 // sp[1]: number of arguments (smi-tagged) | 617 // sp[1]: number of arguments (smi-tagged) |
617 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 618 __ LoadP(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset)); |
618 | 619 |
619 if (create_implicit_receiver) { | 620 if (create_implicit_receiver) { |
620 // If the result is an object (in the ECMA sense), we should get rid | 621 // If the result is an object (in the ECMA sense), we should get rid |
621 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 | 622 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 |
622 // on page 74. | 623 // on page 74. |
623 Label use_receiver, exit; | 624 Label use_receiver, exit; |
624 | 625 |
625 // If the result is a smi, it is *not* an object in the ECMA sense. | 626 // If the result is a smi, it is *not* an object in the ECMA sense. |
626 // r2: result | 627 // r2: result |
627 // sp[0]: receiver | 628 // sp[0]: receiver |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
731 bool is_construct) { | 732 bool is_construct) { |
732 // Called from Generate_JS_Entry | 733 // Called from Generate_JS_Entry |
733 // r2: new.target | 734 // r2: new.target |
734 // r3: function | 735 // r3: function |
735 // r4: receiver | 736 // r4: receiver |
736 // r5: argc | 737 // r5: argc |
737 // r6: argv | 738 // r6: argv |
738 // r0,r7-r9, cp may be clobbered | 739 // r0,r7-r9, cp may be clobbered |
739 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 740 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
740 | 741 |
741 // Clear the context before we push it when entering the internal frame. | |
742 __ LoadImmP(cp, Operand::Zero()); | |
743 | |
744 // Enter an internal frame. | 742 // Enter an internal frame. |
745 { | 743 { |
746 // FrameScope ends up calling MacroAssembler::EnterFrame here | 744 // FrameScope ends up calling MacroAssembler::EnterFrame here |
747 FrameScope scope(masm, StackFrame::INTERNAL); | 745 FrameScope scope(masm, StackFrame::INTERNAL); |
748 | 746 |
749 // Setup the context (we need to use the caller context from the isolate). | 747 // Setup the context (we need to use the caller context from the isolate). |
750 ExternalReference context_address(Isolate::kContextAddress, | 748 ExternalReference context_address(Isolate::kContextAddress, |
751 masm->isolate()); | 749 masm->isolate()); |
752 __ mov(cp, Operand(context_address)); | 750 __ mov(cp, Operand(context_address)); |
753 __ LoadP(cp, MemOperand(cp)); | 751 __ LoadP(cp, MemOperand(cp)); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
834 // o sp: stack pointer | 832 // o sp: stack pointer |
835 // o lr: return address | 833 // o lr: return address |
836 // | 834 // |
837 // The function builds an interpreter frame. See InterpreterFrameConstants in | 835 // The function builds an interpreter frame. See InterpreterFrameConstants in |
838 // frames.h for its layout. | 836 // frames.h for its layout. |
839 void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { | 837 void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { |
840 // Open a frame scope to indicate that there is a frame on the stack. The | 838 // Open a frame scope to indicate that there is a frame on the stack. The |
841 // MANUAL indicates that the scope shouldn't actually generate code to set up | 839 // MANUAL indicates that the scope shouldn't actually generate code to set up |
842 // the frame (that is done below). | 840 // the frame (that is done below). |
843 FrameScope frame_scope(masm, StackFrame::MANUAL); | 841 FrameScope frame_scope(masm, StackFrame::MANUAL); |
844 __ PushFixedFrame(r3); | 842 __ PushStandardFrame(r3); |
845 __ AddP(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); | |
846 | 843 |
847 // Get the bytecode array from the function object and load the pointer to the | 844 // Get the bytecode array from the function object and load the pointer to the |
848 // first entry into kInterpreterBytecodeRegister. | 845 // first entry into kInterpreterBytecodeRegister. |
849 __ LoadP(r2, FieldMemOperand(r3, JSFunction::kSharedFunctionInfoOffset)); | 846 __ LoadP(r2, FieldMemOperand(r3, JSFunction::kSharedFunctionInfoOffset)); |
| 847 Label array_done; |
| 848 Register debug_info = r4; |
| 849 DCHECK(!debug_info.is(r2)); |
| 850 __ LoadP(debug_info, |
| 851 FieldMemOperand(r2, SharedFunctionInfo::kDebugInfoOffset)); |
| 852 // Load original bytecode array or the debug copy. |
850 __ LoadP(kInterpreterBytecodeArrayRegister, | 853 __ LoadP(kInterpreterBytecodeArrayRegister, |
851 FieldMemOperand(r2, SharedFunctionInfo::kFunctionDataOffset)); | 854 FieldMemOperand(r2, SharedFunctionInfo::kFunctionDataOffset)); |
| 855 __ CmpSmiLiteral(debug_info, DebugInfo::uninitialized(), r0); |
| 856 __ beq(&array_done); |
| 857 __ LoadP(kInterpreterBytecodeArrayRegister, |
| 858 FieldMemOperand(debug_info, DebugInfo::kAbstractCodeIndex)); |
| 859 __ bind(&array_done); |
852 | 860 |
853 if (FLAG_debug_code) { | 861 if (FLAG_debug_code) { |
854 // Check function data field is actually a BytecodeArray object. | 862 // Check function data field is actually a BytecodeArray object. |
855 __ TestIfSmi(kInterpreterBytecodeArrayRegister); | 863 __ TestIfSmi(kInterpreterBytecodeArrayRegister); |
856 __ Assert(ne, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry); | 864 __ Assert(ne, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry); |
857 __ CompareObjectType(kInterpreterBytecodeArrayRegister, r2, no_reg, | 865 __ CompareObjectType(kInterpreterBytecodeArrayRegister, r2, no_reg, |
858 BYTECODE_ARRAY_TYPE); | 866 BYTECODE_ARRAY_TYPE); |
859 __ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry); | 867 __ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry); |
860 } | 868 } |
861 | 869 |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1171 __ MultiPush(r14.bit() | r2.bit() | r3.bit() | r5.bit() | fp.bit()); | 1179 __ MultiPush(r14.bit() | r2.bit() | r3.bit() | r5.bit() | fp.bit()); |
1172 __ PrepareCallCFunction(2, 0, r4); | 1180 __ PrepareCallCFunction(2, 0, r4); |
1173 __ mov(r3, Operand(ExternalReference::isolate_address(masm->isolate()))); | 1181 __ mov(r3, Operand(ExternalReference::isolate_address(masm->isolate()))); |
1174 __ CallCFunction( | 1182 __ CallCFunction( |
1175 ExternalReference::get_mark_code_as_executed_function(masm->isolate()), | 1183 ExternalReference::get_mark_code_as_executed_function(masm->isolate()), |
1176 2); | 1184 2); |
1177 __ MultiPop(r14.bit() | r2.bit() | r3.bit() | r5.bit() | fp.bit()); | 1185 __ MultiPop(r14.bit() | r2.bit() | r3.bit() | r5.bit() | fp.bit()); |
1178 __ LoadRR(ip, r2); | 1186 __ LoadRR(ip, r2); |
1179 | 1187 |
1180 // Perform prologue operations usually performed by the young code stub. | 1188 // Perform prologue operations usually performed by the young code stub. |
1181 __ PushFixedFrame(r3); | 1189 __ PushStandardFrame(r3); |
1182 __ la(fp, MemOperand(sp, StandardFrameConstants::kFixedFrameSizeFromFp)); | |
1183 | 1190 |
1184 // Jump to point after the code-age stub. | 1191 // Jump to point after the code-age stub. |
1185 __ AddP(r2, ip, Operand(kNoCodeAgeSequenceLength)); | 1192 __ AddP(r2, ip, Operand(kNoCodeAgeSequenceLength)); |
1186 __ Jump(r2); | 1193 __ Jump(r2); |
1187 } | 1194 } |
1188 | 1195 |
1189 void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) { | 1196 void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) { |
1190 GenerateMakeCodeYoungAgainCommon(masm); | 1197 GenerateMakeCodeYoungAgainCommon(masm); |
1191 } | 1198 } |
1192 | 1199 |
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1925 ExternalReference debug_is_active = | 1932 ExternalReference debug_is_active = |
1926 ExternalReference::debug_is_active_address(masm->isolate()); | 1933 ExternalReference::debug_is_active_address(masm->isolate()); |
1927 __ mov(scratch1, Operand(debug_is_active)); | 1934 __ mov(scratch1, Operand(debug_is_active)); |
1928 __ LoadlB(scratch1, MemOperand(scratch1)); | 1935 __ LoadlB(scratch1, MemOperand(scratch1)); |
1929 __ CmpP(scratch1, Operand::Zero()); | 1936 __ CmpP(scratch1, Operand::Zero()); |
1930 __ bne(&done); | 1937 __ bne(&done); |
1931 | 1938 |
1932 // Drop possible interpreter handler/stub frame. | 1939 // Drop possible interpreter handler/stub frame. |
1933 { | 1940 { |
1934 Label no_interpreter_frame; | 1941 Label no_interpreter_frame; |
1935 __ LoadP(scratch3, MemOperand(fp, StandardFrameConstants::kMarkerOffset)); | 1942 __ LoadP(scratch3, |
| 1943 MemOperand(fp, CommonFrameConstants::kContextOrFrameTypeOffset)); |
1936 __ CmpSmiLiteral(scratch3, Smi::FromInt(StackFrame::STUB), r0); | 1944 __ CmpSmiLiteral(scratch3, Smi::FromInt(StackFrame::STUB), r0); |
1937 __ bne(&no_interpreter_frame); | 1945 __ bne(&no_interpreter_frame); |
1938 __ LoadP(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 1946 __ LoadP(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
1939 __ bind(&no_interpreter_frame); | 1947 __ bind(&no_interpreter_frame); |
1940 } | 1948 } |
1941 | 1949 |
1942 // Check if next frame is an arguments adaptor frame. | 1950 // Check if next frame is an arguments adaptor frame. |
| 1951 Register caller_args_count_reg = scratch1; |
1943 Label no_arguments_adaptor, formal_parameter_count_loaded; | 1952 Label no_arguments_adaptor, formal_parameter_count_loaded; |
1944 __ LoadP(scratch2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 1953 __ LoadP(scratch2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
1945 __ LoadP(scratch3, | 1954 __ LoadP( |
1946 MemOperand(scratch2, StandardFrameConstants::kContextOffset)); | 1955 scratch3, |
| 1956 MemOperand(scratch2, CommonFrameConstants::kContextOrFrameTypeOffset)); |
1947 __ CmpSmiLiteral(scratch3, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0); | 1957 __ CmpSmiLiteral(scratch3, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0); |
1948 __ bne(&no_arguments_adaptor); | 1958 __ bne(&no_arguments_adaptor); |
1949 | 1959 |
1950 // Drop arguments adaptor frame and load arguments count. | 1960 // Drop current frame and load arguments count from arguments adaptor frame. |
1951 __ LoadRR(fp, scratch2); | 1961 __ LoadRR(fp, scratch2); |
1952 __ LoadP(scratch1, | 1962 __ LoadP(caller_args_count_reg, |
1953 MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 1963 MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
1954 __ SmiUntag(scratch1); | 1964 __ SmiUntag(caller_args_count_reg); |
1955 __ b(&formal_parameter_count_loaded); | 1965 __ b(&formal_parameter_count_loaded); |
1956 | 1966 |
1957 __ bind(&no_arguments_adaptor); | 1967 __ bind(&no_arguments_adaptor); |
1958 // Load caller's formal parameter count | 1968 // Load caller's formal parameter count |
1959 __ LoadP(scratch1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1969 __ LoadP(scratch1, |
| 1970 MemOperand(fp, ArgumentsAdaptorFrameConstants::kFunctionOffset)); |
1960 __ LoadP(scratch1, | 1971 __ LoadP(scratch1, |
1961 FieldMemOperand(scratch1, JSFunction::kSharedFunctionInfoOffset)); | 1972 FieldMemOperand(scratch1, JSFunction::kSharedFunctionInfoOffset)); |
1962 __ LoadW(scratch1, | 1973 __ LoadW(caller_args_count_reg, |
1963 FieldMemOperand(scratch1, | 1974 FieldMemOperand(scratch1, |
1964 SharedFunctionInfo::kFormalParameterCountOffset)); | 1975 SharedFunctionInfo::kFormalParameterCountOffset)); |
1965 #if !V8_TARGET_ARCH_S390X | 1976 #if !V8_TARGET_ARCH_S390X |
1966 __ SmiUntag(scratch1); | 1977 __ SmiUntag(caller_args_count_reg); |
1967 #endif | 1978 #endif |
1968 | 1979 |
1969 __ bind(&formal_parameter_count_loaded); | 1980 __ bind(&formal_parameter_count_loaded); |
1970 | 1981 |
1971 // Calculate the end of destination area where we will put the arguments | 1982 ParameterCount callee_args_count(args_reg); |
1972 // after we drop current frame. We AddP kPointerSize to count the receiver | 1983 __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2, |
1973 // argument which is not included into formal parameters count. | 1984 scratch3); |
1974 Register dst_reg = scratch2; | |
1975 __ ShiftLeftP(dst_reg, scratch1, Operand(kPointerSizeLog2)); | |
1976 __ AddP(dst_reg, fp, dst_reg); | |
1977 __ AddP(dst_reg, dst_reg, | |
1978 Operand(StandardFrameConstants::kCallerSPOffset + kPointerSize)); | |
1979 | |
1980 Register src_reg = scratch1; | |
1981 __ ShiftLeftP(src_reg, args_reg, Operand(kPointerSizeLog2)); | |
1982 __ AddP(src_reg, sp, src_reg); | |
1983 // Count receiver argument as well (not included in args_reg). | |
1984 __ AddP(src_reg, src_reg, Operand(kPointerSize)); | |
1985 | |
1986 if (FLAG_debug_code) { | |
1987 __ CmpLogicalP(src_reg, dst_reg); | |
1988 __ Check(lt, kStackAccessBelowStackPointer); | |
1989 } | |
1990 | |
1991 // Restore caller's frame pointer and return address now as they will be | |
1992 // overwritten by the copying loop. | |
1993 __ RestoreFrameStateForTailCall(); | |
1994 | |
1995 // Now copy callee arguments to the caller frame going backwards to avoid | |
1996 // callee arguments corruption (source and destination areas could overlap). | |
1997 | |
1998 // Both src_reg and dst_reg are pointing to the word after the one to copy, | |
1999 // so they must be pre-decremented in the loop. | |
2000 Register tmp_reg = scratch3; | |
2001 Label loop; | |
2002 DCHECK(!src_reg.is(r1)); | |
2003 DCHECK(!dst_reg.is(r1)); | |
2004 DCHECK(!tmp_reg.is(r1)); | |
2005 | |
2006 __ AddP(r1, args_reg, Operand(1)); // +1 for receiver | |
2007 __ bind(&loop); | |
2008 __ lay(src_reg, MemOperand(src_reg, -kPointerSize)); | |
2009 __ LoadP(tmp_reg, MemOperand(src_reg)); | |
2010 __ lay(dst_reg, MemOperand(dst_reg, -kPointerSize)); | |
2011 __ StoreP(tmp_reg, MemOperand(dst_reg)); | |
2012 __ BranchOnCount(r1, &loop); | |
2013 | |
2014 // Leave current frame. | |
2015 __ LoadRR(sp, dst_reg); | |
2016 | |
2017 __ bind(&done); | 1985 __ bind(&done); |
2018 } | 1986 } |
2019 } // namespace | 1987 } // namespace |
2020 | 1988 |
2021 // static | 1989 // static |
2022 void Builtins::Generate_CallFunction(MacroAssembler* masm, | 1990 void Builtins::Generate_CallFunction(MacroAssembler* masm, |
2023 ConvertReceiverMode mode, | 1991 ConvertReceiverMode mode, |
2024 TailCallMode tail_call_mode) { | 1992 TailCallMode tail_call_mode) { |
2025 // ----------- S t a t e ------------- | 1993 // ----------- S t a t e ------------- |
2026 // -- r2 : the number of arguments (not including the receiver) | 1994 // -- r2 : the number of arguments (not including the receiver) |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2254 | 2222 |
2255 Label non_callable, non_function, non_smi; | 2223 Label non_callable, non_function, non_smi; |
2256 __ JumpIfSmi(r3, &non_callable); | 2224 __ JumpIfSmi(r3, &non_callable); |
2257 __ bind(&non_smi); | 2225 __ bind(&non_smi); |
2258 __ CompareObjectType(r3, r6, r7, JS_FUNCTION_TYPE); | 2226 __ CompareObjectType(r3, r6, r7, JS_FUNCTION_TYPE); |
2259 __ Jump(masm->isolate()->builtins()->CallFunction(mode, tail_call_mode), | 2227 __ Jump(masm->isolate()->builtins()->CallFunction(mode, tail_call_mode), |
2260 RelocInfo::CODE_TARGET, eq); | 2228 RelocInfo::CODE_TARGET, eq); |
2261 __ CmpP(r7, Operand(JS_BOUND_FUNCTION_TYPE)); | 2229 __ CmpP(r7, Operand(JS_BOUND_FUNCTION_TYPE)); |
2262 __ Jump(masm->isolate()->builtins()->CallBoundFunction(tail_call_mode), | 2230 __ Jump(masm->isolate()->builtins()->CallBoundFunction(tail_call_mode), |
2263 RelocInfo::CODE_TARGET, eq); | 2231 RelocInfo::CODE_TARGET, eq); |
| 2232 |
| 2233 // Check if target has a [[Call]] internal method. |
| 2234 __ LoadlB(r6, FieldMemOperand(r6, Map::kBitFieldOffset)); |
| 2235 __ TestBit(r6, Map::kIsCallable); |
| 2236 __ beq(&non_callable); |
| 2237 |
2264 __ CmpP(r7, Operand(JS_PROXY_TYPE)); | 2238 __ CmpP(r7, Operand(JS_PROXY_TYPE)); |
2265 __ bne(&non_function); | 2239 __ bne(&non_function); |
2266 | 2240 |
2267 // 0. Prepare for tail call if necessary. | 2241 // 0. Prepare for tail call if necessary. |
2268 if (tail_call_mode == TailCallMode::kAllow) { | 2242 if (tail_call_mode == TailCallMode::kAllow) { |
2269 PrepareForTailCall(masm, r2, r5, r6, r7); | 2243 PrepareForTailCall(masm, r2, r5, r6, r7); |
2270 } | 2244 } |
2271 | 2245 |
2272 // 1. Runtime fallback for Proxy [[Call]]. | 2246 // 1. Runtime fallback for Proxy [[Call]]. |
2273 __ Push(r3); | 2247 __ Push(r3); |
2274 // Increase the arguments size to include the pushed function and the | 2248 // Increase the arguments size to include the pushed function and the |
2275 // existing receiver on the stack. | 2249 // existing receiver on the stack. |
2276 __ AddP(r2, r2, Operand(2)); | 2250 __ AddP(r2, r2, Operand(2)); |
2277 // Tail-call to the runtime. | 2251 // Tail-call to the runtime. |
2278 __ JumpToExternalReference( | 2252 __ JumpToExternalReference( |
2279 ExternalReference(Runtime::kJSProxyCall, masm->isolate())); | 2253 ExternalReference(Runtime::kJSProxyCall, masm->isolate())); |
2280 | 2254 |
2281 // 2. Call to something else, which might have a [[Call]] internal method (if | 2255 // 2. Call to something else, which might have a [[Call]] internal method (if |
2282 // not we raise an exception). | 2256 // not we raise an exception). |
2283 __ bind(&non_function); | 2257 __ bind(&non_function); |
2284 // Check if target has a [[Call]] internal method. | |
2285 __ LoadlB(r6, FieldMemOperand(r6, Map::kBitFieldOffset)); | |
2286 __ TestBit(r6, Map::kIsCallable, r0); | |
2287 __ beq(&non_callable); | |
2288 // Overwrite the original receiver the (original) target. | 2258 // Overwrite the original receiver the (original) target. |
2289 __ ShiftLeftP(r7, r2, Operand(kPointerSizeLog2)); | 2259 __ ShiftLeftP(r7, r2, Operand(kPointerSizeLog2)); |
2290 __ StoreP(r3, MemOperand(sp, r7)); | 2260 __ StoreP(r3, MemOperand(sp, r7)); |
2291 // Let the "call_as_function_delegate" take care of the rest. | 2261 // Let the "call_as_function_delegate" take care of the rest. |
2292 __ LoadNativeContextSlot(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, r3); | 2262 __ LoadNativeContextSlot(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, r3); |
2293 __ Jump(masm->isolate()->builtins()->CallFunction( | 2263 __ Jump(masm->isolate()->builtins()->CallFunction( |
2294 ConvertReceiverMode::kNotNullOrUndefined, tail_call_mode), | 2264 ConvertReceiverMode::kNotNullOrUndefined, tail_call_mode), |
2295 RelocInfo::CODE_TARGET); | 2265 RelocInfo::CODE_TARGET); |
2296 | 2266 |
2297 // 3. Call to something that is not callable. | 2267 // 3. Call to something that is not callable. |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2553 __ bkpt(0); | 2523 __ bkpt(0); |
2554 } | 2524 } |
2555 } | 2525 } |
2556 | 2526 |
2557 #undef __ | 2527 #undef __ |
2558 | 2528 |
2559 } // namespace internal | 2529 } // namespace internal |
2560 } // namespace v8 | 2530 } // namespace v8 |
2561 | 2531 |
2562 #endif // V8_TARGET_ARCH_S390 | 2532 #endif // V8_TARGET_ARCH_S390 |
OLD | NEW |