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 |