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