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 1396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1407 __ TraceSimMsg("AllocationStubForClass return"); | 1407 __ TraceSimMsg("AllocationStubForClass return"); |
1408 // Pop result (newly allocated object). | 1408 // Pop result (newly allocated object). |
1409 __ lw(V0, Address(SP, 2 * kWordSize)); | 1409 __ lw(V0, Address(SP, 2 * kWordSize)); |
1410 __ addiu(SP, SP, Immediate(3 * kWordSize)); // Pop arguments. | 1410 __ addiu(SP, SP, Immediate(3 * kWordSize)); // Pop arguments. |
1411 // V0: new object | 1411 // V0: new object |
1412 // Restore the frame pointer and return. | 1412 // Restore the frame pointer and return. |
1413 __ LeaveStubFrameAndReturn(RA); | 1413 __ LeaveStubFrameAndReturn(RA); |
1414 } | 1414 } |
1415 | 1415 |
1416 | 1416 |
1417 // Called for inline allocation of closures. | |
1418 // Input parameters: | |
1419 // RA: return address. | |
1420 // SP + 4 : receiver (null if not an implicit instance closure). | |
1421 // SP + 0 : type arguments object (null if class is no parameterized). | |
1422 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, | |
1423 const Function& func) { | |
1424 ASSERT(func.IsClosureFunction()); | |
1425 ASSERT(!func.IsImplicitStaticClosureFunction()); | |
1426 const bool is_implicit_instance_closure = | |
1427 func.IsImplicitInstanceClosureFunction(); | |
1428 const Class& cls = Class::ZoneHandle(func.signature_class()); | |
1429 const bool has_type_arguments = cls.NumTypeArguments() > 0; | |
1430 | |
1431 __ TraceSimMsg("AllocationStubForClosure"); | |
1432 __ EnterStubFrame(true); // Uses pool pointer to refer to function. | |
1433 const intptr_t kTypeArgumentsFPOffset = 3 * kWordSize; | |
1434 const intptr_t kReceiverFPOffset = 4 * kWordSize; | |
1435 const intptr_t closure_size = Closure::InstanceSize(); | |
1436 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver. | |
1437 if (FLAG_inline_alloc && | |
1438 Heap::IsAllocatableInNewSpace(closure_size + context_size)) { | |
1439 Label slow_case; | |
1440 Heap* heap = Isolate::Current()->heap(); | |
1441 __ LoadImmediate(T5, heap->TopAddress()); | |
1442 __ lw(T2, Address(T5)); | |
1443 __ AddImmediate(T3, T2, closure_size); | |
1444 if (is_implicit_instance_closure) { | |
1445 __ mov(T4, T3); // T4: new context address. | |
1446 __ AddImmediate(T3, context_size); | |
1447 } | |
1448 // Check if the allocation fits into the remaining space. | |
1449 // T2: potential new closure object. | |
1450 // T3: address of top of heap. | |
1451 // T4: potential new context object (only if is_implicit_closure). | |
1452 __ LoadImmediate(TMP, heap->EndAddress()); | |
1453 __ lw(CMPRES1, Address(TMP)); | |
1454 if (FLAG_use_slow_path) { | |
1455 __ b(&slow_case); | |
1456 } else { | |
1457 __ BranchUnsignedGreaterEqual(T3, CMPRES1, &slow_case); | |
1458 } | |
1459 | |
1460 // Successfully allocated the object, now update top to point to | |
1461 // next object start and initialize the object. | |
1462 __ sw(T3, Address(T5)); | |
1463 if (is_implicit_instance_closure) { | |
1464 // This closure allocates a context, update allocation stats. | |
1465 // T3: context size. | |
1466 __ LoadImmediate(T3, context_size); | |
1467 // T5: Clobbered. | |
1468 __ UpdateAllocationStatsWithSize(kContextCid, T3, T5); | |
1469 } | |
1470 // The closure allocation is attributed to the signature class. | |
1471 // T5: Will be clobbered. | |
1472 __ UpdateAllocationStats(cls.id(), T5); | |
1473 | |
1474 // T2: new closure object. | |
1475 // T4: new context object (only if is_implicit_closure). | |
1476 // Set the tags. | |
1477 uword tags = 0; | |
1478 tags = RawObject::SizeTag::update(closure_size, tags); | |
1479 tags = RawObject::ClassIdTag::update(cls.id(), tags); | |
1480 __ LoadImmediate(T0, tags); | |
1481 __ sw(T0, Address(T2, Instance::tags_offset())); | |
1482 | |
1483 // Initialize the function field in the object. | |
1484 // T2: new closure object. | |
1485 // T4: new context object (only if is_implicit_closure). | |
1486 __ LoadObject(T0, func); // Load function of closure to be allocated. | |
1487 __ sw(T0, Address(T2, Closure::function_offset())); | |
1488 | |
1489 // Setup the context for this closure. | |
1490 if (is_implicit_instance_closure) { | |
1491 // Initialize the new context capturing the receiver. | |
1492 const Class& context_class = Class::ZoneHandle(Object::context_class()); | |
1493 // Set the tags. | |
1494 uword tags = 0; | |
1495 tags = RawObject::SizeTag::update(context_size, tags); | |
1496 tags = RawObject::ClassIdTag::update(context_class.id(), tags); | |
1497 __ LoadImmediate(T0, tags); | |
1498 __ sw(T0, Address(T4, Context::tags_offset())); | |
1499 | |
1500 // Set number of variables field to 1 (for captured receiver). | |
1501 __ LoadImmediate(T0, 1); | |
1502 __ sw(T0, Address(T4, Context::num_variables_offset())); | |
1503 | |
1504 // Set isolate field to isolate of current context. | |
1505 __ lw(T0, FieldAddress(CTX, Context::isolate_offset())); | |
1506 __ sw(T0, Address(T4, Context::isolate_offset())); | |
1507 | |
1508 // Set the parent to null. | |
1509 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | |
1510 __ sw(TMP, Address(T4, Context::parent_offset())); | |
1511 | |
1512 // Initialize the context variable to the receiver. | |
1513 __ lw(T0, Address(FP, kReceiverFPOffset)); | |
1514 __ sw(T0, Address(T4, Context::variable_offset(0))); | |
1515 | |
1516 // Set the newly allocated context in the newly allocated closure. | |
1517 __ AddImmediate(T1, T4, kHeapObjectTag); | |
1518 __ sw(T1, Address(T2, Closure::context_offset())); | |
1519 } else { | |
1520 __ sw(CTX, Address(T2, Closure::context_offset())); | |
1521 } | |
1522 | |
1523 // Set the type arguments field in the newly allocated closure. | |
1524 __ lw(T0, Address(FP, kTypeArgumentsFPOffset)); | |
1525 __ sw(T0, Address(T2, Closure::type_arguments_offset())); | |
1526 | |
1527 // Done allocating and initializing the instance. | |
1528 // V0: new object. | |
1529 __ addiu(V0, T2, Immediate(kHeapObjectTag)); | |
1530 | |
1531 __ LeaveStubFrameAndReturn(RA); | |
1532 | |
1533 __ Bind(&slow_case); | |
1534 } | |
1535 | |
1536 // If it's an implicit instance closure we need 4 stack slots, o/w only 3. | |
1537 intptr_t num_slots = is_implicit_instance_closure ? 4 : 3; | |
1538 __ addiu(SP, SP, Immediate(-num_slots * kWordSize)); | |
1539 // Setup space on stack for return value. | |
1540 __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null())); | |
1541 __ sw(T7, Address(SP, (num_slots - 1) * kWordSize)); | |
1542 __ LoadObject(TMP, func); | |
1543 __ sw(TMP, Address(SP, (num_slots - 2) * kWordSize)); | |
1544 __ mov(T2, T7); | |
1545 if (is_implicit_instance_closure) { | |
1546 __ lw(T1, Address(FP, kReceiverFPOffset)); | |
1547 __ sw(T1, Address(SP, (num_slots - 3) * kWordSize)); // Receiver. | |
1548 } | |
1549 if (has_type_arguments) { | |
1550 __ lw(T2, Address(FP, kTypeArgumentsFPOffset)); | |
1551 } | |
1552 __ sw(T2, Address(SP, 0 * kWordSize)); | |
1553 | |
1554 if (is_implicit_instance_closure) { | |
1555 __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry, 3); | |
1556 __ TraceSimMsg("AllocationStubForClosure return"); | |
1557 } else { | |
1558 ASSERT(func.IsNonImplicitClosureFunction()); | |
1559 __ CallRuntime(kAllocateClosureRuntimeEntry, 2); | |
1560 __ TraceSimMsg("AllocationStubForClosure return"); | |
1561 } | |
1562 __ lw(V0, Address(SP, (num_slots - 1) * kWordSize)); // Pop function object. | |
1563 __ addiu(SP, SP, Immediate(num_slots * kWordSize)); | |
1564 | |
1565 // V0: new object | |
1566 // Restore the frame pointer. | |
1567 __ LeaveStubFrameAndReturn(RA); | |
1568 } | |
1569 | |
1570 | |
1571 // Called for invoking "dynamic noSuchMethod(Invocation invocation)" function | 1417 // Called for invoking "dynamic noSuchMethod(Invocation invocation)" function |
1572 // from the entry code of a dart function after an error in passed argument | 1418 // from the entry code of a dart function after an error in passed argument |
1573 // name or number is detected. | 1419 // name or number is detected. |
1574 // Input parameters: | 1420 // Input parameters: |
1575 // RA : return address. | 1421 // RA : return address. |
1576 // SP : address of last argument. | 1422 // SP : address of last argument. |
1577 // S5: inline cache data object. | 1423 // S5: inline cache data object. |
1578 // S4: arguments descriptor array. | 1424 // S4: arguments descriptor array. |
1579 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { | 1425 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { |
1580 __ EnterStubFrame(); | 1426 __ EnterStubFrame(); |
(...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2382 const Register right = T0; | 2228 const Register right = T0; |
2383 __ lw(left, Address(SP, 1 * kWordSize)); | 2229 __ lw(left, Address(SP, 1 * kWordSize)); |
2384 __ lw(right, Address(SP, 0 * kWordSize)); | 2230 __ lw(right, Address(SP, 0 * kWordSize)); |
2385 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); | 2231 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); |
2386 __ Ret(); | 2232 __ Ret(); |
2387 } | 2233 } |
2388 | 2234 |
2389 } // namespace dart | 2235 } // namespace dart |
2390 | 2236 |
2391 #endif // defined TARGET_ARCH_MIPS | 2237 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |