OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 895 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
906 __ bind(&non_function_call); | 906 __ bind(&non_function_call); |
907 // Set expected number of arguments to zero (not changing rax). | 907 // Set expected number of arguments to zero (not changing rax). |
908 __ movq(rbx, Immediate(0)); | 908 __ movq(rbx, Immediate(0)); |
909 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); | 909 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); |
910 __ Jump(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), | 910 __ Jump(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), |
911 RelocInfo::CODE_TARGET); | 911 RelocInfo::CODE_TARGET); |
912 } | 912 } |
913 | 913 |
914 | 914 |
915 static void Generate_JSConstructStubHelper(MacroAssembler* masm, | 915 static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
916 bool is_api_function) { | 916 bool is_api_function, |
| 917 bool count_constructions) { |
| 918 // Should never count constructions for api objects. |
| 919 ASSERT(!is_api_function || !count_constructions); |
| 920 |
917 // Enter a construct frame. | 921 // Enter a construct frame. |
918 __ EnterConstructFrame(); | 922 __ EnterConstructFrame(); |
919 | 923 |
920 // Store a smi-tagged arguments count on the stack. | 924 // Store a smi-tagged arguments count on the stack. |
921 __ Integer32ToSmi(rax, rax); | 925 __ Integer32ToSmi(rax, rax); |
922 __ push(rax); | 926 __ push(rax); |
923 | 927 |
924 // Push the function to invoke on the stack. | 928 // Push the function to invoke on the stack. |
925 __ push(rdi); | 929 __ push(rdi); |
926 | 930 |
(...skipping 24 matching lines...) Expand all Loading... |
951 __ j(not_equal, &rt_call); | 955 __ j(not_equal, &rt_call); |
952 | 956 |
953 // Check that the constructor is not constructing a JSFunction (see comments | 957 // Check that the constructor is not constructing a JSFunction (see comments |
954 // in Runtime_NewObject in runtime.cc). In which case the initial map's | 958 // in Runtime_NewObject in runtime.cc). In which case the initial map's |
955 // instance type would be JS_FUNCTION_TYPE. | 959 // instance type would be JS_FUNCTION_TYPE. |
956 // rdi: constructor | 960 // rdi: constructor |
957 // rax: initial map | 961 // rax: initial map |
958 __ CmpInstanceType(rax, JS_FUNCTION_TYPE); | 962 __ CmpInstanceType(rax, JS_FUNCTION_TYPE); |
959 __ j(equal, &rt_call); | 963 __ j(equal, &rt_call); |
960 | 964 |
| 965 if (count_constructions) { |
| 966 Label allocate; |
| 967 // Decrease generous allocation count. |
| 968 __ movq(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
| 969 __ decb(FieldOperand(rcx, SharedFunctionInfo::kConstructionCountOffset)); |
| 970 __ j(not_zero, &allocate); |
| 971 |
| 972 __ push(rax); |
| 973 __ push(rdi); |
| 974 |
| 975 __ push(rdi); // constructor |
| 976 // The call will replace the stub, so the countdown is only done once. |
| 977 __ CallRuntime(Runtime::kFinalizeInstanceSize, 1); |
| 978 |
| 979 __ pop(rdi); |
| 980 __ pop(rax); |
| 981 |
| 982 __ bind(&allocate); |
| 983 } |
| 984 |
961 // Now allocate the JSObject on the heap. | 985 // Now allocate the JSObject on the heap. |
962 __ movzxbq(rdi, FieldOperand(rax, Map::kInstanceSizeOffset)); | 986 __ movzxbq(rdi, FieldOperand(rax, Map::kInstanceSizeOffset)); |
963 __ shl(rdi, Immediate(kPointerSizeLog2)); | 987 __ shl(rdi, Immediate(kPointerSizeLog2)); |
964 // rdi: size of new object | 988 // rdi: size of new object |
965 __ AllocateInNewSpace(rdi, | 989 __ AllocateInNewSpace(rdi, |
966 rbx, | 990 rbx, |
967 rdi, | 991 rdi, |
968 no_reg, | 992 no_reg, |
969 &rt_call, | 993 &rt_call, |
970 NO_ALLOCATION_FLAGS); | 994 NO_ALLOCATION_FLAGS); |
971 // Allocated the JSObject, now initialize the fields. | 995 // Allocated the JSObject, now initialize the fields. |
972 // rax: initial map | 996 // rax: initial map |
973 // rbx: JSObject (not HeapObject tagged - the actual address). | 997 // rbx: JSObject (not HeapObject tagged - the actual address). |
974 // rdi: start of next object | 998 // rdi: start of next object |
975 __ movq(Operand(rbx, JSObject::kMapOffset), rax); | 999 __ movq(Operand(rbx, JSObject::kMapOffset), rax); |
976 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex); | 1000 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex); |
977 __ movq(Operand(rbx, JSObject::kPropertiesOffset), rcx); | 1001 __ movq(Operand(rbx, JSObject::kPropertiesOffset), rcx); |
978 __ movq(Operand(rbx, JSObject::kElementsOffset), rcx); | 1002 __ movq(Operand(rbx, JSObject::kElementsOffset), rcx); |
979 // Set extra fields in the newly allocated object. | 1003 // Set extra fields in the newly allocated object. |
980 // rax: initial map | 1004 // rax: initial map |
981 // rbx: JSObject | 1005 // rbx: JSObject |
982 // rdi: start of next object | 1006 // rdi: start of next object |
983 { Label loop, entry; | 1007 { Label loop, entry; |
984 __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); | 1008 // To allow for truncation. |
| 1009 if (count_constructions) { |
| 1010 __ LoadRoot(rdx, Heap::kOnePointerFillerMapRootIndex); |
| 1011 } else { |
| 1012 __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); |
| 1013 } |
985 __ lea(rcx, Operand(rbx, JSObject::kHeaderSize)); | 1014 __ lea(rcx, Operand(rbx, JSObject::kHeaderSize)); |
986 __ jmp(&entry); | 1015 __ jmp(&entry); |
987 __ bind(&loop); | 1016 __ bind(&loop); |
988 __ movq(Operand(rcx, 0), rdx); | 1017 __ movq(Operand(rcx, 0), rdx); |
989 __ addq(rcx, Immediate(kPointerSize)); | 1018 __ addq(rcx, Immediate(kPointerSize)); |
990 __ bind(&entry); | 1019 __ bind(&entry); |
991 __ cmpq(rcx, rdi); | 1020 __ cmpq(rcx, rdi); |
992 __ j(less, &loop); | 1021 __ j(less, &loop); |
993 } | 1022 } |
994 | 1023 |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1157 // Remove caller arguments from the stack and return. | 1186 // Remove caller arguments from the stack and return. |
1158 __ pop(rcx); | 1187 __ pop(rcx); |
1159 SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2); | 1188 SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2); |
1160 __ lea(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize)); | 1189 __ lea(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize)); |
1161 __ push(rcx); | 1190 __ push(rcx); |
1162 __ IncrementCounter(&Counters::constructed_objects, 1); | 1191 __ IncrementCounter(&Counters::constructed_objects, 1); |
1163 __ ret(0); | 1192 __ ret(0); |
1164 } | 1193 } |
1165 | 1194 |
1166 | 1195 |
| 1196 void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) { |
| 1197 Generate_JSConstructStubHelper(masm, false, true); |
| 1198 } |
| 1199 |
| 1200 |
1167 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { | 1201 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { |
1168 Generate_JSConstructStubHelper(masm, false); | 1202 Generate_JSConstructStubHelper(masm, false, false); |
1169 } | 1203 } |
1170 | 1204 |
1171 | 1205 |
1172 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { | 1206 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { |
1173 Generate_JSConstructStubHelper(masm, true); | 1207 Generate_JSConstructStubHelper(masm, true, false); |
1174 } | 1208 } |
1175 | 1209 |
1176 | 1210 |
1177 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 1211 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
1178 bool is_construct) { | 1212 bool is_construct) { |
1179 // Expects five C++ function parameters. | 1213 // Expects five C++ function parameters. |
1180 // - Address entry (ignored) | 1214 // - Address entry (ignored) |
1181 // - JSFunction* function ( | 1215 // - JSFunction* function ( |
1182 // - Object* receiver | 1216 // - Object* receiver |
1183 // - int argc | 1217 // - int argc |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1309 __ LeaveInternalFrame(); | 1343 __ LeaveInternalFrame(); |
1310 | 1344 |
1311 // Do a tail-call of the compiled function. | 1345 // Do a tail-call of the compiled function. |
1312 __ lea(rcx, FieldOperand(rax, Code::kHeaderSize)); | 1346 __ lea(rcx, FieldOperand(rax, Code::kHeaderSize)); |
1313 __ jmp(rcx); | 1347 __ jmp(rcx); |
1314 } | 1348 } |
1315 | 1349 |
1316 } } // namespace v8::internal | 1350 } } // namespace v8::internal |
1317 | 1351 |
1318 #endif // V8_TARGET_ARCH_X64 | 1352 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |