OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_X64 | 5 #if V8_TARGET_ARCH_X64 |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.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 1037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1048 __ DropUnderReturnAddress(1, rbx); // Drop one slot under return address. | 1048 __ DropUnderReturnAddress(1, rbx); // Drop one slot under return address. |
1049 __ decp(rax); // One fewer argument (first argument is new receiver). | 1049 __ decp(rax); // One fewer argument (first argument is new receiver). |
1050 } | 1050 } |
1051 | 1051 |
1052 // 4. Call the callable. | 1052 // 4. Call the callable. |
1053 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 1053 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
1054 } | 1054 } |
1055 | 1055 |
1056 | 1056 |
1057 static void Generate_PushAppliedArguments(MacroAssembler* masm, | 1057 static void Generate_PushAppliedArguments(MacroAssembler* masm, |
| 1058 const int vectorOffset, |
1058 const int argumentsOffset, | 1059 const int argumentsOffset, |
1059 const int indexOffset, | 1060 const int indexOffset, |
1060 const int limitOffset) { | 1061 const int limitOffset) { |
1061 Register receiver = LoadDescriptor::ReceiverRegister(); | 1062 Register receiver = LoadDescriptor::ReceiverRegister(); |
1062 Register key = LoadDescriptor::NameRegister(); | 1063 Register key = LoadDescriptor::NameRegister(); |
1063 Register slot = LoadDescriptor::SlotRegister(); | 1064 Register slot = LoadDescriptor::SlotRegister(); |
1064 Register vector = LoadWithVectorDescriptor::VectorRegister(); | 1065 Register vector = LoadWithVectorDescriptor::VectorRegister(); |
1065 | 1066 |
1066 // Copy all arguments from the array to the stack. | 1067 // Copy all arguments from the array to the stack. |
1067 Label entry, loop; | 1068 Label entry, loop; |
1068 __ movp(key, Operand(rbp, indexOffset)); | 1069 __ movp(key, Operand(rbp, indexOffset)); |
1069 __ jmp(&entry); | 1070 __ jmp(&entry); |
1070 __ bind(&loop); | 1071 __ bind(&loop); |
1071 __ movp(receiver, Operand(rbp, argumentsOffset)); // load arguments | 1072 __ movp(receiver, Operand(rbp, argumentsOffset)); // load arguments |
1072 | 1073 |
1073 // Use inline caching to speed up access to arguments. | 1074 // Use inline caching to speed up access to arguments. |
1074 Code::Kind kinds[] = {Code::KEYED_LOAD_IC}; | 1075 int slot_index = TypeFeedbackVector::PushAppliedArgumentsIndex(); |
1075 FeedbackVectorSpec spec(0, 1, kinds); | 1076 __ Move(slot, Smi::FromInt(slot_index)); |
1076 Handle<TypeFeedbackVector> feedback_vector = | 1077 __ movp(vector, Operand(rbp, vectorOffset)); |
1077 masm->isolate()->factory()->NewTypeFeedbackVector(&spec); | |
1078 int index = feedback_vector->GetIndex(FeedbackVectorICSlot(0)); | |
1079 __ Move(slot, Smi::FromInt(index)); | |
1080 __ Move(vector, feedback_vector); | |
1081 Handle<Code> ic = | 1078 Handle<Code> ic = |
1082 KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode(); | 1079 KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode(); |
1083 __ Call(ic, RelocInfo::CODE_TARGET); | 1080 __ Call(ic, RelocInfo::CODE_TARGET); |
1084 // It is important that we do not have a test instruction after the | 1081 // It is important that we do not have a test instruction after the |
1085 // call. A test instruction after the call is used to indicate that | 1082 // call. A test instruction after the call is used to indicate that |
1086 // we have generated an inline version of the keyed load. In this | 1083 // we have generated an inline version of the keyed load. In this |
1087 // case, we know that we are not generating a test instruction next. | 1084 // case, we know that we are not generating a test instruction next. |
1088 | 1085 |
1089 // Push the nth argument. | 1086 // Push the nth argument. |
1090 __ Push(rax); | 1087 __ Push(rax); |
(...skipping 26 matching lines...) Expand all Loading... |
1117 FrameScope frame_scope(masm, StackFrame::INTERNAL); | 1114 FrameScope frame_scope(masm, StackFrame::INTERNAL); |
1118 // Stack frame: | 1115 // Stack frame: |
1119 // rbp : Old base pointer | 1116 // rbp : Old base pointer |
1120 // rbp[8] : return address | 1117 // rbp[8] : return address |
1121 // rbp[16] : function arguments | 1118 // rbp[16] : function arguments |
1122 // rbp[24] : receiver | 1119 // rbp[24] : receiver |
1123 // rbp[32] : function | 1120 // rbp[32] : function |
1124 static const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; | 1121 static const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; |
1125 static const int kReceiverOffset = kArgumentsOffset + kPointerSize; | 1122 static const int kReceiverOffset = kArgumentsOffset + kPointerSize; |
1126 static const int kFunctionOffset = kReceiverOffset + kPointerSize; | 1123 static const int kFunctionOffset = kReceiverOffset + kPointerSize; |
| 1124 static const int kVectorOffset = |
| 1125 InternalFrameConstants::kCodeOffset - 1 * kPointerSize; |
| 1126 |
| 1127 // Push the vector. |
| 1128 __ movp(rdi, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
| 1129 __ movp(rdi, FieldOperand(rdi, SharedFunctionInfo::kFeedbackVectorOffset)); |
| 1130 __ Push(rdi); |
1127 | 1131 |
1128 __ Push(Operand(rbp, kFunctionOffset)); | 1132 __ Push(Operand(rbp, kFunctionOffset)); |
1129 __ Push(Operand(rbp, kArgumentsOffset)); | 1133 __ Push(Operand(rbp, kArgumentsOffset)); |
1130 if (targetIsArgument) { | 1134 if (targetIsArgument) { |
1131 __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX, | 1135 __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX, |
1132 CALL_FUNCTION); | 1136 CALL_FUNCTION); |
1133 } else { | 1137 } else { |
1134 __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION); | 1138 __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION); |
1135 } | 1139 } |
1136 | 1140 |
1137 Generate_CheckStackOverflow(masm, kFunctionOffset, kRaxIsSmiTagged); | 1141 Generate_CheckStackOverflow(masm, kFunctionOffset, kRaxIsSmiTagged); |
1138 | 1142 |
1139 // Push current index and limit, and receiver. | 1143 // Push current index and limit, and receiver. |
1140 const int kLimitOffset = | 1144 const int kLimitOffset = kVectorOffset - 1 * kPointerSize; |
1141 StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize; | |
1142 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; | 1145 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; |
1143 __ Push(rax); // limit | 1146 __ Push(rax); // limit |
1144 __ Push(Immediate(0)); // index | 1147 __ Push(Immediate(0)); // index |
1145 __ Push(Operand(rbp, kReceiverOffset)); // receiver | 1148 __ Push(Operand(rbp, kReceiverOffset)); // receiver |
1146 | 1149 |
1147 // Loop over the arguments array, pushing each value to the stack | 1150 // Loop over the arguments array, pushing each value to the stack |
1148 Generate_PushAppliedArguments(masm, kArgumentsOffset, kIndexOffset, | 1151 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, |
1149 kLimitOffset); | 1152 kIndexOffset, kLimitOffset); |
1150 | 1153 |
1151 // Call the callable. | 1154 // Call the callable. |
1152 // TODO(bmeurer): This should be a tail call according to ES6. | 1155 // TODO(bmeurer): This should be a tail call according to ES6. |
1153 __ movp(rdi, Operand(rbp, kFunctionOffset)); | 1156 __ movp(rdi, Operand(rbp, kFunctionOffset)); |
1154 __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 1157 __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
1155 | 1158 |
1156 // Leave internal frame. | 1159 // Leave internal frame. |
1157 } | 1160 } |
1158 __ ret(kStackSize * kPointerSize); // remove this, receiver, and arguments | 1161 __ ret(kStackSize * kPointerSize); // remove this, receiver, and arguments |
1159 } | 1162 } |
(...skipping 14 matching lines...) Expand all Loading... |
1174 // Stack frame: | 1177 // Stack frame: |
1175 // rbp : Old base pointer | 1178 // rbp : Old base pointer |
1176 // rbp[8] : return address | 1179 // rbp[8] : return address |
1177 // rbp[16] : original constructor (new.target) | 1180 // rbp[16] : original constructor (new.target) |
1178 // rbp[24] : arguments | 1181 // rbp[24] : arguments |
1179 // rbp[32] : constructor | 1182 // rbp[32] : constructor |
1180 static const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; | 1183 static const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; |
1181 static const int kArgumentsOffset = kNewTargetOffset + kPointerSize; | 1184 static const int kArgumentsOffset = kNewTargetOffset + kPointerSize; |
1182 static const int kFunctionOffset = kArgumentsOffset + kPointerSize; | 1185 static const int kFunctionOffset = kArgumentsOffset + kPointerSize; |
1183 | 1186 |
| 1187 static const int kVectorOffset = |
| 1188 InternalFrameConstants::kCodeOffset - 1 * kPointerSize; |
| 1189 |
| 1190 // Push the vector. |
| 1191 __ movp(rdi, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
| 1192 __ movp(rdi, FieldOperand(rdi, SharedFunctionInfo::kFeedbackVectorOffset)); |
| 1193 __ Push(rdi); |
| 1194 |
1184 // If newTarget is not supplied, set it to constructor | 1195 // If newTarget is not supplied, set it to constructor |
1185 Label validate_arguments; | 1196 Label validate_arguments; |
1186 __ movp(rax, Operand(rbp, kNewTargetOffset)); | 1197 __ movp(rax, Operand(rbp, kNewTargetOffset)); |
1187 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); | 1198 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); |
1188 __ j(not_equal, &validate_arguments, Label::kNear); | 1199 __ j(not_equal, &validate_arguments, Label::kNear); |
1189 __ movp(rax, Operand(rbp, kFunctionOffset)); | 1200 __ movp(rax, Operand(rbp, kFunctionOffset)); |
1190 __ movp(Operand(rbp, kNewTargetOffset), rax); | 1201 __ movp(Operand(rbp, kNewTargetOffset), rax); |
1191 | 1202 |
1192 // Validate arguments | 1203 // Validate arguments |
1193 __ bind(&validate_arguments); | 1204 __ bind(&validate_arguments); |
1194 __ Push(Operand(rbp, kFunctionOffset)); | 1205 __ Push(Operand(rbp, kFunctionOffset)); |
1195 __ Push(Operand(rbp, kArgumentsOffset)); | 1206 __ Push(Operand(rbp, kArgumentsOffset)); |
1196 __ Push(Operand(rbp, kNewTargetOffset)); | 1207 __ Push(Operand(rbp, kNewTargetOffset)); |
1197 __ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX, | 1208 __ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX, |
1198 CALL_FUNCTION); | 1209 CALL_FUNCTION); |
1199 | 1210 |
1200 Generate_CheckStackOverflow(masm, kFunctionOffset, kRaxIsSmiTagged); | 1211 Generate_CheckStackOverflow(masm, kFunctionOffset, kRaxIsSmiTagged); |
1201 | 1212 |
1202 // Push current index and limit. | 1213 // Push current index and limit. |
1203 const int kLimitOffset = | 1214 const int kLimitOffset = kVectorOffset - 1 * kPointerSize; |
1204 StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize; | |
1205 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; | 1215 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; |
1206 __ Push(rax); // limit | 1216 __ Push(rax); // limit |
1207 __ Push(Immediate(0)); // index | 1217 __ Push(Immediate(0)); // index |
1208 // Push the constructor function as callee. | 1218 // Push the constructor function as callee. |
1209 __ Push(Operand(rbp, kFunctionOffset)); | 1219 __ Push(Operand(rbp, kFunctionOffset)); |
1210 | 1220 |
1211 // Loop over the arguments array, pushing each value to the stack | 1221 // Loop over the arguments array, pushing each value to the stack |
1212 Generate_PushAppliedArguments( | 1222 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, |
1213 masm, kArgumentsOffset, kIndexOffset, kLimitOffset); | 1223 kIndexOffset, kLimitOffset); |
1214 | 1224 |
1215 // Use undefined feedback vector | 1225 // Use undefined feedback vector |
1216 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); | 1226 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); |
1217 __ movp(rdi, Operand(rbp, kFunctionOffset)); | 1227 __ movp(rdi, Operand(rbp, kFunctionOffset)); |
1218 __ movp(rcx, Operand(rbp, kNewTargetOffset)); | 1228 __ movp(rcx, Operand(rbp, kNewTargetOffset)); |
1219 | 1229 |
1220 // Call the function. | 1230 // Call the function. |
1221 CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL); | 1231 CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL); |
1222 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 1232 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
1223 | 1233 |
(...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1809 __ ret(0); | 1819 __ ret(0); |
1810 } | 1820 } |
1811 | 1821 |
1812 | 1822 |
1813 #undef __ | 1823 #undef __ |
1814 | 1824 |
1815 } // namespace internal | 1825 } // namespace internal |
1816 } // namespace v8 | 1826 } // namespace v8 |
1817 | 1827 |
1818 #endif // V8_TARGET_ARCH_X64 | 1828 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |