| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 1079 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1090 __ EnterCallRuntimeFrame(0); | 1090 __ EnterCallRuntimeFrame(0); |
| 1091 __ movq(RDI, FieldAddress(CTX, Context::isolate_offset())); | 1091 __ movq(RDI, FieldAddress(CTX, Context::isolate_offset())); |
| 1092 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1); | 1092 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1); |
| 1093 __ LeaveCallRuntimeFrame(); | 1093 __ LeaveCallRuntimeFrame(); |
| 1094 __ ret(); | 1094 __ ret(); |
| 1095 } | 1095 } |
| 1096 | 1096 |
| 1097 | 1097 |
| 1098 // Called for inline allocation of objects. | 1098 // Called for inline allocation of objects. |
| 1099 // Input parameters: | 1099 // Input parameters: |
| 1100 // RSP + 16 : type arguments object (only if class is parameterized). | 1100 // RSP + 8 : type arguments object (only if class is parameterized). |
| 1101 // RSP + 8 : type arguments of instantiator (only if class is parameterized). | |
| 1102 // RSP : points to return address. | 1101 // RSP : points to return address. |
| 1103 void StubCode::GenerateAllocationStubForClass(Assembler* assembler, | 1102 void StubCode::GenerateAllocationStubForClass(Assembler* assembler, |
| 1104 const Class& cls) { | 1103 const Class& cls) { |
| 1105 const intptr_t kObjectTypeArgumentsOffset = 2 * kWordSize; | 1104 const intptr_t kObjectTypeArgumentsOffset = 1 * kWordSize; |
| 1106 const intptr_t kInstantiatorTypeArgumentsOffset = 1 * kWordSize; | |
| 1107 // The generated code is different if the class is parameterized. | 1105 // The generated code is different if the class is parameterized. |
| 1108 const bool is_cls_parameterized = cls.NumTypeArguments() > 0; | 1106 const bool is_cls_parameterized = cls.NumTypeArguments() > 0; |
| 1109 ASSERT(!is_cls_parameterized || | 1107 ASSERT(!is_cls_parameterized || |
| 1110 (cls.type_arguments_field_offset() != Class::kNoTypeArguments)); | 1108 (cls.type_arguments_field_offset() != Class::kNoTypeArguments)); |
| 1111 // kInlineInstanceSize is a constant used as a threshold for determining | 1109 // kInlineInstanceSize is a constant used as a threshold for determining |
| 1112 // when the object initialization should be done as a loop or as | 1110 // when the object initialization should be done as a loop or as |
| 1113 // straight line code. | 1111 // straight line code. |
| 1114 const int kInlineInstanceSize = 12; // In words. | 1112 const int kInlineInstanceSize = 12; // In words. |
| 1115 const intptr_t instance_size = cls.instance_size(); | 1113 const intptr_t instance_size = cls.instance_size(); |
| 1116 ASSERT(instance_size > 0); | 1114 ASSERT(instance_size > 0); |
| 1117 __ LoadObject(R12, Object::null_object(), PP); | 1115 __ LoadObject(R12, Object::null_object(), PP); |
| 1118 Label slow_case_with_type_arguments; | 1116 Label slow_case_with_type_arguments; |
| 1119 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { | 1117 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { |
| 1120 Label slow_case_reload_type_arguments; | 1118 Label slow_case_reload_type_arguments; |
| 1121 if (is_cls_parameterized) { | 1119 if (is_cls_parameterized) { |
| 1122 // Instantiation of the type arguments vector is only required if an | |
| 1123 // instantiator is provided (not kNoInstantiator, but may be null). | |
| 1124 __ movq(RDX, Address(RSP, kObjectTypeArgumentsOffset)); | 1120 __ movq(RDX, Address(RSP, kObjectTypeArgumentsOffset)); |
| 1125 __ movq(RDI, Address(RSP, kInstantiatorTypeArgumentsOffset)); | |
| 1126 Label type_arguments_ready; | |
| 1127 __ cmpq(RDI, Immediate(Smi::RawValue(StubCode::kNoInstantiator))); | |
| 1128 __ j(EQUAL, &type_arguments_ready, Assembler::kNearJump); | |
| 1129 // Lookup instantiator RDI in instantiations array of type arguments RDX | |
| 1130 // and, if found, use cached instantiated type arguments. | |
| 1131 __ movq(RAX, FieldAddress(RDX, TypeArguments::instantiations_offset())); | |
| 1132 __ movq(RBX, FieldAddress(RAX, Array::length_offset())); | |
| 1133 __ leaq(RAX, FieldAddress(RAX, Array::data_offset())); | |
| 1134 __ leaq(RBX, Address(RAX, RBX, TIMES_4, 0)); // RBX is smi. | |
| 1135 Label loop, found; | |
| 1136 __ Bind(&loop); | |
| 1137 __ cmpq(RAX, RBX); | |
| 1138 __ j(ABOVE_EQUAL, &slow_case_reload_type_arguments); | |
| 1139 __ movq(RDX, Address(RAX, 0 * kWordSize)); // Cached instantiator. | |
| 1140 __ cmpq(RDX, RDI); | |
| 1141 __ j(EQUAL, &found, Assembler::kNearJump); | |
| 1142 __ cmpq(RDX, Immediate(Smi::RawValue(StubCode::kNoInstantiator))); | |
| 1143 __ j(EQUAL, &slow_case_reload_type_arguments); | |
| 1144 __ addq(RAX, Immediate(2 * kWordSize)); | |
| 1145 __ jmp(&loop, Assembler::kNearJump); | |
| 1146 __ Bind(&found); | |
| 1147 __ movq(RDX, Address(RAX, 1 * kWordSize)); // Cached instantiated args. | |
| 1148 __ movq(RDI, Immediate(Smi::RawValue(StubCode::kNoInstantiator))); | |
| 1149 __ Bind(&type_arguments_ready); | |
| 1150 // RDX: instantiated type arguments. | 1121 // RDX: instantiated type arguments. |
| 1151 // RDI: kNoInstantiator. | |
| 1152 } | 1122 } |
| 1153 // Allocate the object and update top to point to | 1123 // Allocate the object and update top to point to |
| 1154 // next object start and initialize the allocated object. | 1124 // next object start and initialize the allocated object. |
| 1155 // RDX: instantiated type arguments (if is_cls_parameterized). | 1125 // RDX: instantiated type arguments (if is_cls_parameterized). |
| 1156 // RDI: kNoInstantiator (if is_cls_parameterized). | |
| 1157 Heap* heap = Isolate::Current()->heap(); | 1126 Heap* heap = Isolate::Current()->heap(); |
| 1158 __ movq(RCX, Immediate(heap->TopAddress())); | 1127 __ movq(RCX, Immediate(heap->TopAddress())); |
| 1159 __ movq(RAX, Address(RCX, 0)); | 1128 __ movq(RAX, Address(RCX, 0)); |
| 1160 __ leaq(RBX, Address(RAX, instance_size)); | 1129 __ leaq(RBX, Address(RAX, instance_size)); |
| 1161 // Check if the allocation fits into the remaining space. | 1130 // Check if the allocation fits into the remaining space. |
| 1162 // RAX: potential new object start. | 1131 // RAX: potential new object start. |
| 1163 // RBX: potential next object start. | 1132 // RBX: potential next object start. |
| 1164 // RCX: heap top address. | 1133 // RCX: heap top address. |
| 1165 __ movq(R13, Immediate(heap->EndAddress())); | 1134 __ movq(R13, Immediate(heap->EndAddress())); |
| 1166 __ cmpq(RBX, Address(R13, 0)); | 1135 __ cmpq(RBX, Address(R13, 0)); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1220 } | 1189 } |
| 1221 // Done allocating and initializing the instance. | 1190 // Done allocating and initializing the instance. |
| 1222 // RAX: new object. | 1191 // RAX: new object. |
| 1223 __ addq(RAX, Immediate(kHeapObjectTag)); | 1192 __ addq(RAX, Immediate(kHeapObjectTag)); |
| 1224 __ ret(); | 1193 __ ret(); |
| 1225 | 1194 |
| 1226 __ Bind(&slow_case_reload_type_arguments); | 1195 __ Bind(&slow_case_reload_type_arguments); |
| 1227 } | 1196 } |
| 1228 if (is_cls_parameterized) { | 1197 if (is_cls_parameterized) { |
| 1229 __ movq(RDX, Address(RSP, kObjectTypeArgumentsOffset)); | 1198 __ movq(RDX, Address(RSP, kObjectTypeArgumentsOffset)); |
| 1230 __ movq(RDI, Address(RSP, kInstantiatorTypeArgumentsOffset)); | |
| 1231 } | 1199 } |
| 1232 __ Bind(&slow_case_with_type_arguments); | 1200 __ Bind(&slow_case_with_type_arguments); |
| 1233 // If is_cls_parameterized: | 1201 // If is_cls_parameterized: |
| 1234 // RDX: new object type arguments (instantiated or not). | 1202 // RDX: new object type arguments. |
| 1235 // RDI: instantiator type arguments or kNoInstantiator. | |
| 1236 // Create a stub frame. | 1203 // Create a stub frame. |
| 1237 __ EnterStubFrame(true); // Uses PP to access class object. | 1204 __ EnterStubFrame(true); // Uses PP to access class object. |
| 1238 __ pushq(R12); // Setup space on stack for return value. | 1205 __ pushq(R12); // Setup space on stack for return value. |
| 1239 __ PushObject(cls, PP); // Push class of object to be allocated. | 1206 __ PushObject(cls, PP); // Push class of object to be allocated. |
| 1240 if (is_cls_parameterized) { | 1207 if (is_cls_parameterized) { |
| 1241 __ pushq(RDX); // Push type arguments of object to be allocated. | 1208 __ pushq(RDX); // Push type arguments of object to be allocated. |
| 1242 __ pushq(RDI); // Push type arguments of instantiator. | |
| 1243 } else { | 1209 } else { |
| 1244 __ pushq(R12); // Push null type arguments. | 1210 __ pushq(R12); // Push null type arguments. |
| 1245 __ pushq(Immediate(Smi::RawValue(StubCode::kNoInstantiator))); | |
| 1246 } | 1211 } |
| 1247 __ CallRuntime(kAllocateObjectRuntimeEntry, 3); // Allocate object. | 1212 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object. |
| 1248 __ popq(RAX); // Pop argument (instantiator). | |
| 1249 __ popq(RAX); // Pop argument (type arguments of object). | 1213 __ popq(RAX); // Pop argument (type arguments of object). |
| 1250 __ popq(RAX); // Pop argument (class of object). | 1214 __ popq(RAX); // Pop argument (class of object). |
| 1251 __ popq(RAX); // Pop result (newly allocated object). | 1215 __ popq(RAX); // Pop result (newly allocated object). |
| 1252 // RAX: new object | 1216 // RAX: new object |
| 1253 // Restore the frame pointer. | 1217 // Restore the frame pointer. |
| 1254 __ LeaveStubFrame(); | 1218 __ LeaveStubFrame(); |
| 1255 __ ret(); | 1219 __ ret(); |
| 1256 } | 1220 } |
| 1257 | 1221 |
| 1258 | 1222 |
| (...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2136 | 2100 |
| 2137 __ movq(left, Address(RSP, 2 * kWordSize)); | 2101 __ movq(left, Address(RSP, 2 * kWordSize)); |
| 2138 __ movq(right, Address(RSP, 1 * kWordSize)); | 2102 __ movq(right, Address(RSP, 1 * kWordSize)); |
| 2139 GenerateIdenticalWithNumberCheckStub(assembler, left, right); | 2103 GenerateIdenticalWithNumberCheckStub(assembler, left, right); |
| 2140 __ ret(); | 2104 __ ret(); |
| 2141 } | 2105 } |
| 2142 | 2106 |
| 2143 } // namespace dart | 2107 } // namespace dart |
| 2144 | 2108 |
| 2145 #endif // defined TARGET_ARCH_X64 | 2109 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |