| 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_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 1269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1280 __ TraceSimMsg("UpdateStoreBufferStub return"); | 1280 __ TraceSimMsg("UpdateStoreBufferStub return"); |
| 1281 // Restore callee-saved registers, tear down frame. | 1281 // Restore callee-saved registers, tear down frame. |
| 1282 __ LeaveCallRuntimeFrame(); | 1282 __ LeaveCallRuntimeFrame(); |
| 1283 __ Ret(); | 1283 __ Ret(); |
| 1284 } | 1284 } |
| 1285 | 1285 |
| 1286 | 1286 |
| 1287 // Called for inline allocation of objects. | 1287 // Called for inline allocation of objects. |
| 1288 // Input parameters: | 1288 // Input parameters: |
| 1289 // RA : return address. | 1289 // RA : return address. |
| 1290 // SP + 4 : type arguments object (only if class is parameterized). | 1290 // SP + 0 : type arguments object (only if class is parameterized). |
| 1291 // SP + 0 : type arguments of instantiator (only if class is parameterized). | |
| 1292 void StubCode::GenerateAllocationStubForClass(Assembler* assembler, | 1291 void StubCode::GenerateAllocationStubForClass(Assembler* assembler, |
| 1293 const Class& cls) { | 1292 const Class& cls) { |
| 1294 __ TraceSimMsg("AllocationStubForClass"); | 1293 __ TraceSimMsg("AllocationStubForClass"); |
| 1295 // The generated code is different if the class is parameterized. | 1294 // The generated code is different if the class is parameterized. |
| 1296 const bool is_cls_parameterized = cls.NumTypeArguments() > 0; | 1295 const bool is_cls_parameterized = cls.NumTypeArguments() > 0; |
| 1297 ASSERT(!is_cls_parameterized || | 1296 ASSERT(!is_cls_parameterized || |
| 1298 (cls.type_arguments_field_offset() != Class::kNoTypeArguments)); | 1297 (cls.type_arguments_field_offset() != Class::kNoTypeArguments)); |
| 1299 // kInlineInstanceSize is a constant used as a threshold for determining | 1298 // kInlineInstanceSize is a constant used as a threshold for determining |
| 1300 // when the object initialization should be done as a loop or as | 1299 // when the object initialization should be done as a loop or as |
| 1301 // straight line code. | 1300 // straight line code. |
| 1302 const int kInlineInstanceSize = 12; | 1301 const int kInlineInstanceSize = 12; |
| 1303 const intptr_t instance_size = cls.instance_size(); | 1302 const intptr_t instance_size = cls.instance_size(); |
| 1304 ASSERT(instance_size > 0); | 1303 ASSERT(instance_size > 0); |
| 1305 Label slow_case_with_type_arguments; | 1304 Label slow_case_with_type_arguments; |
| 1306 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { | 1305 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { |
| 1307 Label slow_case_reload_type_arguments; | 1306 Label slow_case_reload_type_arguments; |
| 1308 if (is_cls_parameterized) { | 1307 if (is_cls_parameterized) { |
| 1309 // Instantiation of the type arguments vector is only required if an | 1308 __ lw(T1, Address(SP, 0 * kWordSize)); |
| 1310 // instantiator is provided (not kNoInstantiator, but may be null). | 1309 // T1: type arguments. |
| 1311 __ lw(T1, Address(SP, 1 * kWordSize)); | |
| 1312 __ lw(T0, Address(SP, 0 * kWordSize)); | |
| 1313 // R1: type arguments, instantiated or not. | |
| 1314 // R0: instantiator type arguments or kNoInstantiator. | |
| 1315 Label type_arguments_ready; | |
| 1316 __ BranchEqual(T0, Smi::RawValue(StubCode::kNoInstantiator), | |
| 1317 &type_arguments_ready); | |
| 1318 // Lookup instantiator EDI in instantiations array of type arguments EDX | |
| 1319 // and, if found, use cached instantiated type arguments. | |
| 1320 __ lw(T2, FieldAddress(T1, TypeArguments::instantiations_offset())); | |
| 1321 __ lw(T3, FieldAddress(T2, Array::length_offset())); | |
| 1322 __ AddImmediate(T2, Array::data_offset() - kHeapObjectTag); | |
| 1323 __ sll(TMP, T3, 1); // T3 is Smi. | |
| 1324 __ addu(T3, T2, TMP); | |
| 1325 Label loop, found; | |
| 1326 __ Bind(&loop); | |
| 1327 __ BranchUnsignedGreaterEqual(T2, T3, &slow_case_reload_type_arguments); | |
| 1328 __ lw(T1, Address(T2, 0 * kWordSize)); // Cached instantiator. | |
| 1329 __ beq(T1, T0, &found); | |
| 1330 __ BranchEqual(T1, Smi::RawValue(StubCode::kNoInstantiator), | |
| 1331 &slow_case_reload_type_arguments); | |
| 1332 __ b(&loop); | |
| 1333 __ delay_slot()->addiu(T2, T2, Immediate(2 * kWordSize)); | |
| 1334 __ Bind(&found); | |
| 1335 __ lw(T1, Address(T2, 1 * kWordSize)); // Cached instantiated args. | |
| 1336 __ LoadImmediate(T0, Smi::RawValue(StubCode::kNoInstantiator)); | |
| 1337 __ Bind(&type_arguments_ready); | |
| 1338 // T0: instantiated type arguments. | |
| 1339 // T1: kNoInstantiator. | |
| 1340 } | 1310 } |
| 1341 // Allocate the object and update top to point to | 1311 // Allocate the object and update top to point to |
| 1342 // next object start and initialize the allocated object. | 1312 // next object start and initialize the allocated object. |
| 1343 // T0: instantiated type arguments (if is_cls_parameterized). | 1313 // T1: instantiated type arguments (if is_cls_parameterized). |
| 1344 // T1: kNoInstantiator (if is_cls_parameterized). | |
| 1345 Heap* heap = Isolate::Current()->heap(); | 1314 Heap* heap = Isolate::Current()->heap(); |
| 1346 __ LoadImmediate(T5, heap->TopAddress()); | 1315 __ LoadImmediate(T5, heap->TopAddress()); |
| 1347 __ lw(T2, Address(T5)); | 1316 __ lw(T2, Address(T5)); |
| 1348 __ LoadImmediate(T4, instance_size); | 1317 __ LoadImmediate(T4, instance_size); |
| 1349 __ addu(T3, T2, T4); | 1318 __ addu(T3, T2, T4); |
| 1350 // Check if the allocation fits into the remaining space. | 1319 // Check if the allocation fits into the remaining space. |
| 1351 // T2: potential new object start. | 1320 // T2: potential new object start. |
| 1352 // T3: potential next object start. | 1321 // T3: potential next object start. |
| 1353 __ LoadImmediate(TMP, heap->EndAddress()); | 1322 __ LoadImmediate(TMP, heap->EndAddress()); |
| 1354 __ lw(CMPRES1, Address(TMP)); | 1323 __ lw(CMPRES1, Address(TMP)); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1398 // T1: new object type arguments (if is_cls_parameterized). | 1367 // T1: new object type arguments (if is_cls_parameterized). |
| 1399 Label loop, loop_exit; | 1368 Label loop, loop_exit; |
| 1400 __ BranchUnsignedGreaterEqual(T4, T3, &loop_exit); | 1369 __ BranchUnsignedGreaterEqual(T4, T3, &loop_exit); |
| 1401 __ Bind(&loop); | 1370 __ Bind(&loop); |
| 1402 __ addiu(T4, T4, Immediate(kWordSize)); | 1371 __ addiu(T4, T4, Immediate(kWordSize)); |
| 1403 __ bne(T4, T3, &loop); | 1372 __ bne(T4, T3, &loop); |
| 1404 __ delay_slot()->sw(T7, Address(T4, -kWordSize)); | 1373 __ delay_slot()->sw(T7, Address(T4, -kWordSize)); |
| 1405 __ Bind(&loop_exit); | 1374 __ Bind(&loop_exit); |
| 1406 } | 1375 } |
| 1407 if (is_cls_parameterized) { | 1376 if (is_cls_parameterized) { |
| 1408 // R1: new object type arguments. | 1377 // T1: new object type arguments. |
| 1409 // Set the type arguments in the new object. | 1378 // Set the type arguments in the new object. |
| 1410 __ sw(T1, Address(T2, cls.type_arguments_field_offset())); | 1379 __ sw(T1, Address(T2, cls.type_arguments_field_offset())); |
| 1411 } | 1380 } |
| 1412 // Done allocating and initializing the instance. | 1381 // Done allocating and initializing the instance. |
| 1413 // T2: new object still missing its heap tag. | 1382 // T2: new object still missing its heap tag. |
| 1414 __ Ret(); | 1383 __ Ret(); |
| 1415 __ delay_slot()->addiu(V0, T2, Immediate(kHeapObjectTag)); | 1384 __ delay_slot()->addiu(V0, T2, Immediate(kHeapObjectTag)); |
| 1416 | 1385 |
| 1417 __ Bind(&slow_case_reload_type_arguments); | 1386 __ Bind(&slow_case_reload_type_arguments); |
| 1418 } | 1387 } |
| 1419 if (is_cls_parameterized) { | 1388 if (is_cls_parameterized) { |
| 1420 __ lw(T1, Address(SP, 1 * kWordSize)); | 1389 __ lw(T1, Address(SP, 0 * kWordSize)); |
| 1421 __ lw(T0, Address(SP, 0 * kWordSize)); | |
| 1422 } | 1390 } |
| 1423 __ Bind(&slow_case_with_type_arguments); | 1391 __ Bind(&slow_case_with_type_arguments); |
| 1424 // If is_cls_parameterized: | 1392 // If is_cls_parameterized: |
| 1425 // T1: new object type arguments (instantiated or not). | 1393 // T1: new object type arguments (instantiated or not). |
| 1426 // T0: instantiator type arguments or kNoInstantiator. | |
| 1427 // Create a stub frame as we are pushing some objects on the stack before | 1394 // Create a stub frame as we are pushing some objects on the stack before |
| 1428 // calling into the runtime. | 1395 // calling into the runtime. |
| 1429 __ EnterStubFrame(true); // Uses pool pointer to pass cls to runtime. | 1396 __ EnterStubFrame(true); // Uses pool pointer to pass cls to runtime. |
| 1430 __ LoadObject(TMP, cls); | 1397 __ LoadObject(TMP, cls); |
| 1431 | 1398 |
| 1432 __ addiu(SP, SP, Immediate(-4 * kWordSize)); | 1399 __ addiu(SP, SP, Immediate(-4 * kWordSize)); |
| 1433 // Space on stack for return value. | 1400 // Space on stack for return value. |
| 1434 __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null())); | 1401 __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null())); |
| 1435 __ sw(T7, Address(SP, 3 * kWordSize)); | 1402 __ sw(T7, Address(SP, 2 * kWordSize)); |
| 1436 __ sw(TMP, Address(SP, 2 * kWordSize)); // Class of object to be allocated. | 1403 __ sw(TMP, Address(SP, 1 * kWordSize)); // Class of object to be allocated. |
| 1437 | 1404 |
| 1438 if (is_cls_parameterized) { | 1405 if (is_cls_parameterized) { |
| 1439 // Push type arguments of object to be allocated and of instantiator. | 1406 // Push type arguments of object to be allocated and of instantiator. |
| 1440 __ sw(T1, Address(SP, 1 * kWordSize)); | 1407 __ sw(T1, Address(SP, 0 * kWordSize)); |
| 1441 __ sw(T0, Address(SP, 0 * kWordSize)); | |
| 1442 } else { | 1408 } else { |
| 1443 // Push null type arguments and kNoInstantiator. | 1409 // Push null type arguments. |
| 1444 __ LoadImmediate(T1, Smi::RawValue(StubCode::kNoInstantiator)); | 1410 __ sw(T7, Address(SP, 0 * kWordSize)); |
| 1445 __ sw(T7, Address(SP, 1 * kWordSize)); | |
| 1446 __ sw(T1, Address(SP, 0 * kWordSize)); | |
| 1447 } | 1411 } |
| 1448 __ CallRuntime(kAllocateObjectRuntimeEntry, 3); // Allocate object. | 1412 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object. |
| 1449 __ TraceSimMsg("AllocationStubForClass return"); | 1413 __ TraceSimMsg("AllocationStubForClass return"); |
| 1450 // Pop result (newly allocated object). | 1414 // Pop result (newly allocated object). |
| 1451 __ lw(V0, Address(SP, 3 * kWordSize)); | 1415 __ lw(V0, Address(SP, 2 * kWordSize)); |
| 1452 __ addiu(SP, SP, Immediate(4 * kWordSize)); // Pop arguments. | 1416 __ addiu(SP, SP, Immediate(3 * kWordSize)); // Pop arguments. |
| 1453 // V0: new object | 1417 // V0: new object |
| 1454 // Restore the frame pointer and return. | 1418 // Restore the frame pointer and return. |
| 1455 __ LeaveStubFrameAndReturn(RA); | 1419 __ LeaveStubFrameAndReturn(RA); |
| 1456 } | 1420 } |
| 1457 | 1421 |
| 1458 | 1422 |
| 1459 // Called for inline allocation of closures. | 1423 // Called for inline allocation of closures. |
| 1460 // Input parameters: | 1424 // Input parameters: |
| 1461 // RA: return address. | 1425 // RA: return address. |
| 1462 // SP + 4 : receiver (null if not an implicit instance closure). | 1426 // SP + 4 : receiver (null if not an implicit instance closure). |
| (...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2424 const Register right = T0; | 2388 const Register right = T0; |
| 2425 __ lw(left, Address(SP, 1 * kWordSize)); | 2389 __ lw(left, Address(SP, 1 * kWordSize)); |
| 2426 __ lw(right, Address(SP, 0 * kWordSize)); | 2390 __ lw(right, Address(SP, 0 * kWordSize)); |
| 2427 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); | 2391 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); |
| 2428 __ Ret(); | 2392 __ Ret(); |
| 2429 } | 2393 } |
| 2430 | 2394 |
| 2431 } // namespace dart | 2395 } // namespace dart |
| 2432 | 2396 |
| 2433 #endif // defined TARGET_ARCH_MIPS | 2397 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |