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 |