1453 { |
1453 { |
1454 static TUint8 there; |
1454 static TUint8 there; |
1455 TUint8 here; |
1455 TUint8 here; |
1456 return &here-&there; |
1456 return &here-&there; |
1457 } |
1457 } |
1458 LOCAL_C void sheLeavesMe(TBool sheLeavesMeNot) |
1458 LOCAL_C void sheLeavesMeL(TBool sheLeavesMeNot) |
1459 { |
1459 { |
1460 if (!sheLeavesMeNot) |
1460 if (!sheLeavesMeNot) |
1461 User::Leave(KErrBadName); // Montague |
1461 User::Leave(KErrBadName); // Montague |
1462 } |
1462 } |
1463 |
1463 |
|
1464 // Variables for stack balance test need to be global or clever compiler optimisations |
|
1465 // Can interfere with stack balance calculations. |
|
1466 TInt StackBalanceLoopCounter; |
|
1467 TInt StackBalanceResult=KErrNone; |
|
1468 TInt StackBalanceBefore; |
|
1469 TInt StackBalanceAfter; |
|
1470 |
|
1471 // Split into two functions because x86gcc makes a local stack optimisation for the second |
|
1472 // loop which unbalances the stack frame of the first loop. |
|
1473 LOCAL_C TInt StackBalanceNotLeaving() |
|
1474 { |
|
1475 StackBalanceBefore=getStackPointer(); |
|
1476 for (StackBalanceLoopCounter=0; StackBalanceLoopCounter<20;StackBalanceLoopCounter++) |
|
1477 { |
|
1478 TRAP(StackBalanceResult,sheLeavesMeL(ETrue)); |
|
1479 } |
|
1480 StackBalanceAfter=getStackPointer(); |
|
1481 return StackBalanceAfter-StackBalanceBefore; |
|
1482 } |
|
1483 LOCAL_C TInt StackBalanceLeaving() |
|
1484 { |
|
1485 StackBalanceBefore=getStackPointer(); |
|
1486 for (StackBalanceLoopCounter=0; StackBalanceLoopCounter<20;StackBalanceLoopCounter++) |
|
1487 { |
|
1488 TRAP(StackBalanceResult,sheLeavesMeL(EFalse)); |
|
1489 } |
|
1490 StackBalanceAfter=getStackPointer(); |
|
1491 return StackBalanceAfter-StackBalanceBefore; |
|
1492 } |
|
1493 |
1464 LOCAL_C void testStackBalance() |
1494 LOCAL_C void testStackBalance() |
1465 // |
1495 // |
1466 // Ensure that we get the stack properly balanced |
1496 // Ensure that we get the stack properly balanced |
1467 // |
1497 // |
1468 { |
1498 { |
1469 |
1499 // Not leaving case |
1470 TInt i; |
1500 test.Start(_L("Stack balance without Leaving")); |
1471 TInt r=KErrNone; |
1501 TInt balance = StackBalanceNotLeaving(); |
1472 test.Start(_L("Stack balance without leaving")); |
1502 test.Printf(_L("Stack balance: %d bytes\n"), balance); |
1473 TInt before=getStackPointer(); |
1503 test(balance == 0); |
1474 for (i=0; i<20;i++) |
1504 |
1475 TRAP(r,sheLeavesMe(ETrue)); |
1505 // Leaving case |
1476 TInt after=getStackPointer(); |
|
1477 test(r==KErrNone); |
|
1478 test(before==after); |
|
1479 // |
|
1480 test.Next(_L("Stack balance after Leave")); |
1506 test.Next(_L("Stack balance after Leave")); |
1481 before=getStackPointer(); |
1507 balance = StackBalanceLeaving(); |
1482 for (i=0; i<20;i++) |
1508 test.Printf(_L("Stack balance: %d bytes\n"), balance); |
1483 TRAP(r,sheLeavesMe(EFalse)); |
1509 test(balance == 0); |
1484 after=getStackPointer(); |
|
1485 test(r==KErrBadName); |
|
1486 test(before==after); |
|
1487 // |
|
1488 test.End(); |
1510 test.End(); |
1489 } |
1511 } |
1490 |
1512 |
1491 void Inc(TAny* aPtr) |
1513 void Inc(TAny* aPtr) |
1492 { |
1514 { |