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 #include <assert.h> // For assert | 5 #include <assert.h> // For assert |
6 #include <limits.h> // For LONG_MIN, LONG_MAX. | 6 #include <limits.h> // For LONG_MIN, LONG_MAX. |
7 | 7 |
8 #if V8_TARGET_ARCH_S390 | 8 #if V8_TARGET_ARCH_S390 |
9 | 9 |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 push(r14); | 551 push(r14); |
552 StoreBufferOverflowStub store_buffer_overflow(isolate(), fp_mode); | 552 StoreBufferOverflowStub store_buffer_overflow(isolate(), fp_mode); |
553 CallStub(&store_buffer_overflow); | 553 CallStub(&store_buffer_overflow); |
554 pop(r14); | 554 pop(r14); |
555 bind(&done); | 555 bind(&done); |
556 if (and_then == kReturnAtEnd) { | 556 if (and_then == kReturnAtEnd) { |
557 Ret(); | 557 Ret(); |
558 } | 558 } |
559 } | 559 } |
560 | 560 |
561 void MacroAssembler::PushFixedFrame(Register marker_reg) { | 561 void MacroAssembler::PushCommonFrame(Register marker_reg) { |
| 562 int fp_delta = 0; |
562 CleanseP(r14); | 563 CleanseP(r14); |
563 if (marker_reg.is_valid()) { | 564 if (marker_reg.is_valid()) { |
564 Push(r14, fp, cp, marker_reg); | 565 Push(r14, fp, marker_reg); |
| 566 fp_delta = 1; |
565 } else { | 567 } else { |
566 Push(r14, fp, cp); | 568 Push(r14, fp); |
| 569 fp_delta = 0; |
| 570 } |
| 571 la(fp, MemOperand(sp, fp_delta * kPointerSize)); |
| 572 } |
| 573 |
| 574 void MacroAssembler::PopCommonFrame(Register marker_reg) { |
| 575 if (marker_reg.is_valid()) { |
| 576 Pop(r14, fp, marker_reg); |
| 577 } else { |
| 578 Pop(r14, fp); |
567 } | 579 } |
568 } | 580 } |
569 | 581 |
570 void MacroAssembler::PopFixedFrame(Register marker_reg) { | 582 void MacroAssembler::PushStandardFrame(Register function_reg) { |
571 if (marker_reg.is_valid()) { | 583 int fp_delta = 0; |
572 Pop(r14, fp, cp, marker_reg); | 584 CleanseP(r14); |
| 585 if (function_reg.is_valid()) { |
| 586 Push(r14, fp, cp, function_reg); |
| 587 fp_delta = 2; |
573 } else { | 588 } else { |
574 Pop(r14, fp, cp); | 589 Push(r14, fp, cp); |
| 590 fp_delta = 1; |
575 } | 591 } |
| 592 la(fp, MemOperand(sp, fp_delta * kPointerSize)); |
576 } | 593 } |
577 | 594 |
578 void MacroAssembler::RestoreFrameStateForTailCall() { | 595 void MacroAssembler::RestoreFrameStateForTailCall() { |
579 // if (FLAG_enable_embedded_constant_pool) { | 596 // if (FLAG_enable_embedded_constant_pool) { |
580 // LoadP(kConstantPoolRegister, | 597 // LoadP(kConstantPoolRegister, |
581 // MemOperand(fp, StandardFrameConstants::kConstantPoolOffset)); | 598 // MemOperand(fp, StandardFrameConstants::kConstantPoolOffset)); |
582 // set_constant_pool_available(false); | 599 // set_constant_pool_available(false); |
583 // } | 600 // } |
584 DCHECK(!FLAG_enable_embedded_constant_pool); | 601 DCHECK(!FLAG_enable_embedded_constant_pool); |
585 LoadP(r14, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); | 602 LoadP(r14, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
861 case kRoundToMinusInf: | 878 case kRoundToMinusInf: |
862 m = Condition(7); | 879 m = Condition(7); |
863 break; | 880 break; |
864 default: | 881 default: |
865 UNIMPLEMENTED(); | 882 UNIMPLEMENTED(); |
866 break; | 883 break; |
867 } | 884 } |
868 clgdbr(m, Condition(0), dst, double_input); | 885 clgdbr(m, Condition(0), dst, double_input); |
869 ldgr(double_dst, dst); | 886 ldgr(double_dst, dst); |
870 } | 887 } |
| 888 |
| 889 #endif |
| 890 |
| 891 #if !V8_TARGET_ARCH_S390X |
| 892 void MacroAssembler::ShiftLeftPair(Register dst_low, Register dst_high, |
| 893 Register src_low, Register src_high, |
| 894 Register scratch, Register shift) { |
| 895 DCHECK(!AreAliased(dst_low, src_high, shift)); |
| 896 DCHECK(!AreAliased(dst_high, src_low, shift)); |
| 897 UNIMPLEMENTED(); |
| 898 } |
| 899 |
| 900 void MacroAssembler::ShiftLeftPair(Register dst_low, Register dst_high, |
| 901 Register src_low, Register src_high, |
| 902 uint32_t shift) { |
| 903 DCHECK(!AreAliased(dst_low, src_high)); |
| 904 DCHECK(!AreAliased(dst_high, src_low)); |
| 905 UNIMPLEMENTED(); |
| 906 Label less_than_32; |
| 907 Label done; |
| 908 } |
| 909 |
| 910 void MacroAssembler::ShiftRightPair(Register dst_low, Register dst_high, |
| 911 Register src_low, Register src_high, |
| 912 Register scratch, Register shift) { |
| 913 DCHECK(!AreAliased(dst_low, src_high, shift)); |
| 914 DCHECK(!AreAliased(dst_high, src_low, shift)); |
| 915 UNIMPLEMENTED(); |
| 916 } |
| 917 |
| 918 void MacroAssembler::ShiftRightPair(Register dst_low, Register dst_high, |
| 919 Register src_low, Register src_high, |
| 920 uint32_t shift) { |
| 921 DCHECK(!AreAliased(dst_low, src_high)); |
| 922 DCHECK(!AreAliased(dst_high, src_low)); |
| 923 UNIMPLEMENTED(); |
| 924 } |
| 925 |
| 926 void MacroAssembler::ShiftRightArithPair(Register dst_low, Register dst_high, |
| 927 Register src_low, Register src_high, |
| 928 Register scratch, Register shift) { |
| 929 DCHECK(!AreAliased(dst_low, src_high, shift)); |
| 930 DCHECK(!AreAliased(dst_high, src_low, shift)); |
| 931 UNIMPLEMENTED(); |
| 932 } |
| 933 |
| 934 void MacroAssembler::ShiftRightArithPair(Register dst_low, Register dst_high, |
| 935 Register src_low, Register src_high, |
| 936 uint32_t shift) { |
| 937 DCHECK(!AreAliased(dst_low, src_high)); |
| 938 DCHECK(!AreAliased(dst_high, src_low)); |
| 939 UNIMPLEMENTED(); |
| 940 } |
871 #endif | 941 #endif |
872 | 942 |
873 void MacroAssembler::MovDoubleToInt64(Register dst, DoubleRegister src) { | 943 void MacroAssembler::MovDoubleToInt64(Register dst, DoubleRegister src) { |
874 lgdr(dst, src); | 944 lgdr(dst, src); |
875 } | 945 } |
876 | 946 |
877 void MacroAssembler::MovInt64ToDouble(DoubleRegister dst, Register src) { | 947 void MacroAssembler::MovInt64ToDouble(DoubleRegister dst, Register src) { |
878 ldgr(dst, src); | 948 ldgr(dst, src); |
879 } | 949 } |
880 | 950 |
881 void MacroAssembler::StubPrologue(Register base, int prologue_offset) { | 951 void MacroAssembler::StubPrologue(StackFrame::Type type, Register base, |
882 PushFixedFrame(); | 952 int prologue_offset) { |
883 Push(Smi::FromInt(StackFrame::STUB)); | 953 LoadSmiLiteral(r1, Smi::FromInt(type)); |
884 // Adjust FP to point to saved FP. | 954 PushCommonFrame(r1); |
885 la(fp, MemOperand(sp, StandardFrameConstants::kFixedFrameSizeFromFp)); | |
886 } | 955 } |
887 | 956 |
888 void MacroAssembler::Prologue(bool code_pre_aging, Register base, | 957 void MacroAssembler::Prologue(bool code_pre_aging, Register base, |
889 int prologue_offset) { | 958 int prologue_offset) { |
890 DCHECK(!base.is(no_reg)); | 959 DCHECK(!base.is(no_reg)); |
891 { | 960 { |
892 PredictableCodeSizeScope predictible_code_size_scope( | 961 PredictableCodeSizeScope predictible_code_size_scope( |
893 this, kNoCodeAgeSequenceLength); | 962 this, kNoCodeAgeSequenceLength); |
894 // The following instructions must remain together and unmodified | 963 // The following instructions must remain together and unmodified |
895 // for code aging to work properly. | 964 // for code aging to work properly. |
896 if (code_pre_aging) { | 965 if (code_pre_aging) { |
897 // Pre-age the code. | 966 // Pre-age the code. |
898 // This matches the code found in PatchPlatformCodeAge() | 967 // This matches the code found in PatchPlatformCodeAge() |
899 Code* stub = Code::GetPreAgedCodeAgeStub(isolate()); | 968 Code* stub = Code::GetPreAgedCodeAgeStub(isolate()); |
900 intptr_t target = reinterpret_cast<intptr_t>(stub->instruction_start()); | 969 intptr_t target = reinterpret_cast<intptr_t>(stub->instruction_start()); |
901 nop(); | 970 nop(); |
902 CleanseP(r14); | 971 CleanseP(r14); |
903 Push(r14); | 972 Push(r14); |
904 mov(r2, Operand(target)); | 973 mov(r2, Operand(target)); |
905 Call(r2); | 974 Call(r2); |
906 for (int i = 0; i < kNoCodeAgeSequenceLength - kCodeAgingSequenceLength; | 975 for (int i = 0; i < kNoCodeAgeSequenceLength - kCodeAgingSequenceLength; |
907 i += 2) { | 976 i += 2) { |
908 // TODO(joransiu): Create nop function to pad | 977 // TODO(joransiu): Create nop function to pad |
909 // (kNoCodeAgeSequenceLength - kCodeAgingSequenceLength) bytes. | 978 // (kNoCodeAgeSequenceLength - kCodeAgingSequenceLength) bytes. |
910 nop(); // 2-byte nops(). | 979 nop(); // 2-byte nops(). |
911 } | 980 } |
912 } else { | 981 } else { |
913 // This matches the code found in GetNoCodeAgeSequence() | 982 // This matches the code found in GetNoCodeAgeSequence() |
914 PushFixedFrame(r3); | 983 PushStandardFrame(r3); |
915 // Adjust fp to point to saved fp. | |
916 la(fp, MemOperand(sp, StandardFrameConstants::kFixedFrameSizeFromFp)); | |
917 } | 984 } |
918 } | 985 } |
919 } | 986 } |
920 | 987 |
921 void MacroAssembler::EmitLoadTypeFeedbackVector(Register vector) { | 988 void MacroAssembler::EmitLoadTypeFeedbackVector(Register vector) { |
922 LoadP(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 989 LoadP(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
923 LoadP(vector, FieldMemOperand(vector, JSFunction::kSharedFunctionInfoOffset)); | 990 LoadP(vector, FieldMemOperand(vector, JSFunction::kSharedFunctionInfoOffset)); |
924 LoadP(vector, | 991 LoadP(vector, |
925 FieldMemOperand(vector, SharedFunctionInfo::kFeedbackVectorOffset)); | 992 FieldMemOperand(vector, SharedFunctionInfo::kFeedbackVectorOffset)); |
926 } | 993 } |
927 | 994 |
928 void MacroAssembler::EnterFrame(StackFrame::Type type, | 995 void MacroAssembler::EnterFrame(StackFrame::Type type, |
929 bool load_constant_pool_pointer_reg) { | 996 bool load_constant_pool_pointer_reg) { |
930 // We create a stack frame with: | 997 // We create a stack frame with: |
931 // Return Addr <-- old sp | 998 // Return Addr <-- old sp |
932 // Old FP <-- new fp | 999 // Old FP <-- new fp |
933 // CP | 1000 // CP |
934 // type | 1001 // type |
935 // CodeObject <-- new sp | 1002 // CodeObject <-- new sp |
936 | 1003 |
937 LoadSmiLiteral(ip, Smi::FromInt(type)); | 1004 LoadSmiLiteral(ip, Smi::FromInt(type)); |
938 PushFixedFrame(ip); | 1005 PushCommonFrame(ip); |
939 | 1006 |
940 mov(r0, Operand(CodeObject())); | 1007 if (type == StackFrame::INTERNAL) { |
941 push(r0); | 1008 mov(r0, Operand(CodeObject())); |
942 // Adjust FP to point to saved FP | 1009 push(r0); |
943 la(fp, MemOperand( | 1010 } |
944 sp, StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize)); | |
945 } | 1011 } |
946 | 1012 |
947 int MacroAssembler::LeaveFrame(StackFrame::Type type, int stack_adjustment) { | 1013 int MacroAssembler::LeaveFrame(StackFrame::Type type, int stack_adjustment) { |
948 // Drop the execution stack down to the frame pointer and restore | 1014 // Drop the execution stack down to the frame pointer and restore |
949 // the caller frame pointer, return address and constant pool pointer. | 1015 // the caller frame pointer, return address and constant pool pointer. |
950 LoadP(r14, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); | 1016 LoadP(r14, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); |
951 lay(r1, MemOperand( | 1017 lay(r1, MemOperand( |
952 fp, StandardFrameConstants::kCallerSPOffset + stack_adjustment)); | 1018 fp, StandardFrameConstants::kCallerSPOffset + stack_adjustment)); |
953 LoadP(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 1019 LoadP(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
954 LoadRR(sp, r1); | 1020 LoadRR(sp, r1); |
(...skipping 29 matching lines...) Expand all Loading... |
984 // Set up the frame structure on the stack. | 1050 // Set up the frame structure on the stack. |
985 DCHECK_EQ(2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement); | 1051 DCHECK_EQ(2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement); |
986 DCHECK_EQ(1 * kPointerSize, ExitFrameConstants::kCallerPCOffset); | 1052 DCHECK_EQ(1 * kPointerSize, ExitFrameConstants::kCallerPCOffset); |
987 DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); | 1053 DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); |
988 DCHECK(stack_space > 0); | 1054 DCHECK(stack_space > 0); |
989 | 1055 |
990 // This is an opportunity to build a frame to wrap | 1056 // This is an opportunity to build a frame to wrap |
991 // all of the pushes that have happened inside of V8 | 1057 // all of the pushes that have happened inside of V8 |
992 // since we were called from C code | 1058 // since we were called from C code |
993 CleanseP(r14); | 1059 CleanseP(r14); |
994 Push(r14, fp); | 1060 LoadSmiLiteral(r1, Smi::FromInt(StackFrame::EXIT)); |
995 LoadRR(fp, sp); | 1061 PushCommonFrame(r1); |
996 // Reserve room for saved entry sp and code object. | 1062 // Reserve room for saved entry sp and code object. |
997 lay(sp, MemOperand(sp, -ExitFrameConstants::kFrameSize)); | 1063 lay(sp, MemOperand(fp, -ExitFrameConstants::kFixedFrameSizeFromFp)); |
998 | 1064 |
999 if (emit_debug_code()) { | 1065 if (emit_debug_code()) { |
1000 StoreP(MemOperand(fp, ExitFrameConstants::kSPOffset), Operand::Zero(), r1); | 1066 StoreP(MemOperand(fp, ExitFrameConstants::kSPOffset), Operand::Zero(), r1); |
1001 } | 1067 } |
1002 mov(r1, Operand(CodeObject())); | 1068 mov(r1, Operand(CodeObject())); |
1003 StoreP(r1, MemOperand(fp, ExitFrameConstants::kCodeOffset)); | 1069 StoreP(r1, MemOperand(fp, ExitFrameConstants::kCodeOffset)); |
1004 | 1070 |
1005 // Save the frame pointer and the context in top. | 1071 // Save the frame pointer and the context in top. |
1006 mov(r1, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); | 1072 mov(r1, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); |
1007 StoreP(fp, MemOperand(r1)); | 1073 StoreP(fp, MemOperand(r1)); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1063 #endif | 1129 #endif |
1064 } | 1130 } |
1065 | 1131 |
1066 void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count, | 1132 void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count, |
1067 bool restore_context, | 1133 bool restore_context, |
1068 bool argument_count_is_length) { | 1134 bool argument_count_is_length) { |
1069 // Optionally restore all double registers. | 1135 // Optionally restore all double registers. |
1070 if (save_doubles) { | 1136 if (save_doubles) { |
1071 // Calculate the stack location of the saved doubles and restore them. | 1137 // Calculate the stack location of the saved doubles and restore them. |
1072 const int kNumRegs = kNumCallerSavedDoubles; | 1138 const int kNumRegs = kNumCallerSavedDoubles; |
1073 lay(r5, MemOperand(fp, -(ExitFrameConstants::kFrameSize + | 1139 lay(r5, MemOperand(fp, -(ExitFrameConstants::kFixedFrameSizeFromFp + |
1074 kNumRegs * kDoubleSize))); | 1140 kNumRegs * kDoubleSize))); |
1075 MultiPopDoubles(kCallerSavedDoubles, r5); | 1141 MultiPopDoubles(kCallerSavedDoubles, r5); |
1076 } | 1142 } |
1077 | 1143 |
1078 // Clear top frame. | 1144 // Clear top frame. |
1079 mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); | 1145 mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); |
1080 StoreP(MemOperand(ip), Operand(0, kRelocInfo_NONEPTR), r0); | 1146 StoreP(MemOperand(ip), Operand(0, kRelocInfo_NONEPTR), r0); |
1081 | 1147 |
1082 // Restore current context from top and clear it in debug mode. | 1148 // Restore current context from top and clear it in debug mode. |
1083 if (restore_context) { | 1149 if (restore_context) { |
(...skipping 17 matching lines...) Expand all Loading... |
1101 } | 1167 } |
1102 | 1168 |
1103 void MacroAssembler::MovFromFloatResult(const DoubleRegister dst) { | 1169 void MacroAssembler::MovFromFloatResult(const DoubleRegister dst) { |
1104 Move(dst, d0); | 1170 Move(dst, d0); |
1105 } | 1171 } |
1106 | 1172 |
1107 void MacroAssembler::MovFromFloatParameter(const DoubleRegister dst) { | 1173 void MacroAssembler::MovFromFloatParameter(const DoubleRegister dst) { |
1108 Move(dst, d0); | 1174 Move(dst, d0); |
1109 } | 1175 } |
1110 | 1176 |
| 1177 void MacroAssembler::PrepareForTailCall(const ParameterCount& callee_args_count, |
| 1178 Register caller_args_count_reg, |
| 1179 Register scratch0, Register scratch1) { |
| 1180 #if DEBUG |
| 1181 if (callee_args_count.is_reg()) { |
| 1182 DCHECK(!AreAliased(callee_args_count.reg(), caller_args_count_reg, scratch0, |
| 1183 scratch1)); |
| 1184 } else { |
| 1185 DCHECK(!AreAliased(caller_args_count_reg, scratch0, scratch1)); |
| 1186 } |
| 1187 #endif |
| 1188 |
| 1189 // Calculate the end of destination area where we will put the arguments |
| 1190 // after we drop current frame. We AddP kPointerSize to count the receiver |
| 1191 // argument which is not included into formal parameters count. |
| 1192 Register dst_reg = scratch0; |
| 1193 ShiftLeftP(dst_reg, caller_args_count_reg, Operand(kPointerSizeLog2)); |
| 1194 AddP(dst_reg, fp, dst_reg); |
| 1195 AddP(dst_reg, dst_reg, |
| 1196 Operand(StandardFrameConstants::kCallerSPOffset + kPointerSize)); |
| 1197 |
| 1198 Register src_reg = caller_args_count_reg; |
| 1199 // Calculate the end of source area. +kPointerSize is for the receiver. |
| 1200 if (callee_args_count.is_reg()) { |
| 1201 ShiftLeftP(src_reg, callee_args_count.reg(), Operand(kPointerSizeLog2)); |
| 1202 AddP(src_reg, sp, src_reg); |
| 1203 AddP(src_reg, src_reg, Operand(kPointerSize)); |
| 1204 } else { |
| 1205 mov(src_reg, Operand((callee_args_count.immediate() + 1) * kPointerSize)); |
| 1206 AddP(src_reg, src_reg, sp); |
| 1207 } |
| 1208 |
| 1209 if (FLAG_debug_code) { |
| 1210 CmpLogicalP(src_reg, dst_reg); |
| 1211 Check(lt, kStackAccessBelowStackPointer); |
| 1212 } |
| 1213 |
| 1214 // Restore caller's frame pointer and return address now as they will be |
| 1215 // overwritten by the copying loop. |
| 1216 RestoreFrameStateForTailCall(); |
| 1217 |
| 1218 // Now copy callee arguments to the caller frame going backwards to avoid |
| 1219 // callee arguments corruption (source and destination areas could overlap). |
| 1220 |
| 1221 // Both src_reg and dst_reg are pointing to the word after the one to copy, |
| 1222 // so they must be pre-decremented in the loop. |
| 1223 Register tmp_reg = scratch1; |
| 1224 Label loop; |
| 1225 if (callee_args_count.is_reg()) { |
| 1226 AddP(tmp_reg, callee_args_count.reg(), Operand(1)); // +1 for receiver |
| 1227 } else { |
| 1228 mov(tmp_reg, Operand(callee_args_count.immediate() + 1)); |
| 1229 } |
| 1230 LoadRR(r1, tmp_reg); |
| 1231 bind(&loop); |
| 1232 LoadP(tmp_reg, MemOperand(src_reg, -kPointerSize)); |
| 1233 StoreP(tmp_reg, MemOperand(dst_reg, -kPointerSize)); |
| 1234 lay(src_reg, MemOperand(src_reg, -kPointerSize)); |
| 1235 lay(dst_reg, MemOperand(dst_reg, -kPointerSize)); |
| 1236 BranchOnCount(r1, &loop); |
| 1237 |
| 1238 // Leave current frame. |
| 1239 LoadRR(sp, dst_reg); |
| 1240 } |
| 1241 |
1111 void MacroAssembler::InvokePrologue(const ParameterCount& expected, | 1242 void MacroAssembler::InvokePrologue(const ParameterCount& expected, |
1112 const ParameterCount& actual, Label* done, | 1243 const ParameterCount& actual, Label* done, |
1113 bool* definitely_mismatches, | 1244 bool* definitely_mismatches, |
1114 InvokeFlag flag, | 1245 InvokeFlag flag, |
1115 const CallWrapper& call_wrapper) { | 1246 const CallWrapper& call_wrapper) { |
1116 bool definitely_matches = false; | 1247 bool definitely_matches = false; |
1117 *definitely_mismatches = false; | 1248 *definitely_mismatches = false; |
1118 Label regular_invoke; | 1249 Label regular_invoke; |
1119 | 1250 |
1120 // Check whether the expected and actual arguments count match. If not, | 1251 // Check whether the expected and actual arguments count match. If not, |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1372 } | 1503 } |
1373 | 1504 |
1374 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, | 1505 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, |
1375 Register scratch, Label* miss) { | 1506 Register scratch, Label* miss) { |
1376 Label same_contexts; | 1507 Label same_contexts; |
1377 | 1508 |
1378 DCHECK(!holder_reg.is(scratch)); | 1509 DCHECK(!holder_reg.is(scratch)); |
1379 DCHECK(!holder_reg.is(ip)); | 1510 DCHECK(!holder_reg.is(ip)); |
1380 DCHECK(!scratch.is(ip)); | 1511 DCHECK(!scratch.is(ip)); |
1381 | 1512 |
1382 // Load current lexical context from the stack frame. | 1513 // Load current lexical context from the active StandardFrame, which |
1383 LoadP(scratch, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1514 // may require crawling past STUB frames. |
| 1515 Label load_context; |
| 1516 Label has_context; |
| 1517 DCHECK(!ip.is(scratch)); |
| 1518 LoadRR(ip, fp); |
| 1519 bind(&load_context); |
| 1520 LoadP(scratch, |
| 1521 MemOperand(ip, CommonFrameConstants::kContextOrFrameTypeOffset)); |
| 1522 JumpIfNotSmi(scratch, &has_context); |
| 1523 LoadP(ip, MemOperand(ip, CommonFrameConstants::kCallerFPOffset)); |
| 1524 b(&load_context); |
| 1525 bind(&has_context); |
| 1526 |
1384 // In debug mode, make sure the lexical context is set. | 1527 // In debug mode, make sure the lexical context is set. |
1385 #ifdef DEBUG | 1528 #ifdef DEBUG |
1386 CmpP(scratch, Operand::Zero()); | 1529 CmpP(scratch, Operand::Zero()); |
1387 Check(ne, kWeShouldNotHaveAnEmptyLexicalContext); | 1530 Check(ne, kWeShouldNotHaveAnEmptyLexicalContext); |
1388 #endif | 1531 #endif |
1389 | 1532 |
1390 // Load the native context of the current context. | 1533 // Load the native context of the current context. |
1391 LoadP(scratch, ContextMemOperand(scratch, Context::NATIVE_CONTEXT_INDEX)); | 1534 LoadP(scratch, ContextMemOperand(scratch, Context::NATIVE_CONTEXT_INDEX)); |
1392 | 1535 |
1393 // Check the context is a native context. | 1536 // Check the context is a native context. |
(...skipping 3896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5290 } | 5433 } |
5291 if (mag.shift > 0) ShiftRightArith(result, result, Operand(mag.shift)); | 5434 if (mag.shift > 0) ShiftRightArith(result, result, Operand(mag.shift)); |
5292 ExtractBit(r0, dividend, 31); | 5435 ExtractBit(r0, dividend, 31); |
5293 AddP(result, r0); | 5436 AddP(result, r0); |
5294 } | 5437 } |
5295 | 5438 |
5296 } // namespace internal | 5439 } // namespace internal |
5297 } // namespace v8 | 5440 } // namespace v8 |
5298 | 5441 |
5299 #endif // V8_TARGET_ARCH_S390 | 5442 #endif // V8_TARGET_ARCH_S390 |
OLD | NEW |