Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: runtime/vm/stub_code_mips.cc

Issue 178233003: Allocate instance closures similarly to regular closures, i.e. without a (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/stub_code_ia32.cc ('k') | runtime/vm/stub_code_x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/stub_code_ia32.cc ('k') | runtime/vm/stub_code_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698