| 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 |