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

Side by Side Diff: src/ppc/builtins-ppc.cc

Issue 999613004: PPC: [es6] implement Reflect.apply() & Reflect.construct() (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 9 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_PPC 7 #if V8_TARGET_ARCH_PPC
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/debug.h" 10 #include "src/debug.h"
(...skipping 1348 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 __ cmp(r5, r3); // Check formal and actual parameter counts. 1359 __ cmp(r5, r3); // Check formal and actual parameter counts.
1360 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 1360 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1361 RelocInfo::CODE_TARGET, ne); 1361 RelocInfo::CODE_TARGET, ne);
1362 1362
1363 __ LoadP(ip, FieldMemOperand(r4, JSFunction::kCodeEntryOffset)); 1363 __ LoadP(ip, FieldMemOperand(r4, JSFunction::kCodeEntryOffset));
1364 ParameterCount expected(0); 1364 ParameterCount expected(0);
1365 __ InvokeCode(ip, expected, expected, JUMP_FUNCTION, NullCallWrapper()); 1365 __ InvokeCode(ip, expected, expected, JUMP_FUNCTION, NullCallWrapper());
1366 } 1366 }
1367 1367
1368 1368
1369 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { 1369 static void Generate_CheckStackOverflow(MacroAssembler* masm,
1370 const int kIndexOffset = 1370 const int calleeOffset) {
1371 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); 1371 // Check the stack for overflow. We are not trying to catch
1372 const int kLimitOffset = 1372 // interruptions (e.g. debug break and preemption) here, so the "real stack
1373 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); 1373 // limit" is checked.
1374 const int kArgsOffset = 2 * kPointerSize; 1374 Label okay;
1375 const int kRecvOffset = 3 * kPointerSize; 1375 __ LoadRoot(r5, Heap::kRealStackLimitRootIndex);
1376 const int kFunctionOffset = 4 * kPointerSize; 1376 // Make r5 the space we have left. The stack might already be overflowed
1377 // here which will cause r5 to become negative.
1378 __ sub(r5, sp, r5);
1379 // Check if the arguments will overflow the stack.
1380 __ SmiToPtrArrayOffset(r0, r3);
1381 __ cmp(r5, r0);
1382 __ bgt(&okay); // Signed comparison.
1383
1384 // Out of stack space.
1385 __ LoadP(r4, MemOperand(fp, calleeOffset));
1386 __ Push(r4, r3);
1387 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
1388
1389 __ bind(&okay);
1390 }
1391
1392
1393 static void Generate_PushAppliedArguments(MacroAssembler* masm,
1394 const int argumentsOffset,
1395 const int indexOffset,
1396 const int limitOffset) {
1397 Label entry, loop;
1398 __ LoadP(r3, MemOperand(fp, indexOffset));
1399 __ b(&entry);
1400
1401 // Load the current argument from the arguments array and push it to the
1402 // stack.
1403 // r3: current argument index
1404 __ bind(&loop);
1405 __ LoadP(r4, MemOperand(fp, argumentsOffset));
1406 __ Push(r4, r3);
1407
1408 // Call the runtime to access the property in the arguments array.
1409 __ CallRuntime(Runtime::kGetProperty, 2);
1410 __ push(r3);
1411
1412 // Use inline caching to access the arguments.
1413 __ LoadP(r3, MemOperand(fp, indexOffset));
1414 __ AddSmiLiteral(r3, r3, Smi::FromInt(1), r0);
1415 __ StoreP(r3, MemOperand(fp, indexOffset));
1416
1417 // Test if the copy loop has finished copying all the elements from the
1418 // arguments object.
1419 __ bind(&entry);
1420 __ LoadP(r4, MemOperand(fp, limitOffset));
1421 __ cmp(r3, r4);
1422 __ bne(&loop);
1423
1424 // On exit, the pushed arguments count is in r0, untagged
1425 __ SmiUntag(r3);
1426 }
1427
1428
1429 // Used by FunctionApply and ReflectApply
1430 static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
1431 const int kFormalParameters = targetIsArgument ? 3 : 2;
1432 const int kStackSize = kFormalParameters + 1;
1377 1433
1378 { 1434 {
1379 FrameScope frame_scope(masm, StackFrame::INTERNAL); 1435 FrameScope frame_scope(masm, StackFrame::INTERNAL);
1436 const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize;
1437 const int kReceiverOffset = kArgumentsOffset + kPointerSize;
1438 const int kFunctionOffset = kReceiverOffset + kPointerSize;
1380 1439
1381 __ LoadP(r3, MemOperand(fp, kFunctionOffset)); // get the function 1440 __ LoadP(r3, MemOperand(fp, kFunctionOffset)); // get the function
1382 __ push(r3); 1441 __ push(r3);
1383 __ LoadP(r3, MemOperand(fp, kArgsOffset)); // get the args array 1442 __ LoadP(r3, MemOperand(fp, kArgumentsOffset)); // get the args array
1384 __ push(r3); 1443 __ push(r3);
1385 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); 1444 if (targetIsArgument) {
1445 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION);
1446 } else {
1447 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
1448 }
1386 1449
1387 // Check the stack for overflow. We are not trying to catch 1450 Generate_CheckStackOverflow(masm, kFunctionOffset);
1388 // interruptions (e.g. debug break and preemption) here, so the "real stack
1389 // limit" is checked.
1390 Label okay;
1391 __ LoadRoot(r5, Heap::kRealStackLimitRootIndex);
1392 // Make r5 the space we have left. The stack might already be overflowed
1393 // here which will cause r5 to become negative.
1394 __ sub(r5, sp, r5);
1395 // Check if the arguments will overflow the stack.
1396 __ SmiToPtrArrayOffset(r0, r3);
1397 __ cmp(r5, r0);
1398 __ bgt(&okay); // Signed comparison.
1399
1400 // Out of stack space.
1401 __ LoadP(r4, MemOperand(fp, kFunctionOffset));
1402 __ Push(r4, r3);
1403 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
1404 // End of stack check.
1405 1451
1406 // Push current limit and index. 1452 // Push current limit and index.
1407 __ bind(&okay); 1453 const int kIndexOffset =
1454 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize);
1455 const int kLimitOffset =
1456 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
1408 __ li(r4, Operand::Zero()); 1457 __ li(r4, Operand::Zero());
1409 __ Push(r3, r4); // limit and initial index. 1458 __ Push(r3, r4); // limit and initial index.
1410 1459
1411 // Get the receiver. 1460 // Get the receiver.
1412 __ LoadP(r3, MemOperand(fp, kRecvOffset)); 1461 __ LoadP(r3, MemOperand(fp, kReceiverOffset));
1413 1462
1414 // Check that the function is a JS function (otherwise it must be a proxy). 1463 // Check that the function is a JS function (otherwise it must be a proxy).
1415 Label push_receiver; 1464 Label push_receiver;
1416 __ LoadP(r4, MemOperand(fp, kFunctionOffset)); 1465 __ LoadP(r4, MemOperand(fp, kFunctionOffset));
1417 __ CompareObjectType(r4, r5, r5, JS_FUNCTION_TYPE); 1466 __ CompareObjectType(r4, r5, r5, JS_FUNCTION_TYPE);
1418 __ bne(&push_receiver); 1467 __ bne(&push_receiver);
1419 1468
1420 // Change context eagerly to get the right global object if necessary. 1469 // Change context eagerly to get the right global object if necessary.
1421 __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset)); 1470 __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
1422 // Load the shared function info while the function is still in r4. 1471 // Load the shared function info while the function is still in r4.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1470 __ bind(&use_global_proxy); 1519 __ bind(&use_global_proxy);
1471 __ LoadP(r3, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); 1520 __ LoadP(r3, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
1472 __ LoadP(r3, FieldMemOperand(r3, GlobalObject::kGlobalProxyOffset)); 1521 __ LoadP(r3, FieldMemOperand(r3, GlobalObject::kGlobalProxyOffset));
1473 1522
1474 // Push the receiver. 1523 // Push the receiver.
1475 // r3: receiver 1524 // r3: receiver
1476 __ bind(&push_receiver); 1525 __ bind(&push_receiver);
1477 __ push(r3); 1526 __ push(r3);
1478 1527
1479 // Copy all arguments from the array to the stack. 1528 // Copy all arguments from the array to the stack.
1480 Label entry, loop; 1529 Generate_PushAppliedArguments(masm, kArgumentsOffset, kIndexOffset,
1481 __ LoadP(r3, MemOperand(fp, kIndexOffset)); 1530 kLimitOffset);
1482 __ b(&entry);
1483
1484 // Load the current argument from the arguments array and push it to the
1485 // stack.
1486 // r3: current argument index
1487 __ bind(&loop);
1488 __ LoadP(r4, MemOperand(fp, kArgsOffset));
1489 __ Push(r4, r3);
1490
1491 // Call the runtime to access the property in the arguments array.
1492 __ CallRuntime(Runtime::kGetProperty, 2);
1493 __ push(r3);
1494
1495 // Use inline caching to access the arguments.
1496 __ LoadP(r3, MemOperand(fp, kIndexOffset));
1497 __ AddSmiLiteral(r3, r3, Smi::FromInt(1), r0);
1498 __ StoreP(r3, MemOperand(fp, kIndexOffset));
1499
1500 // Test if the copy loop has finished copying all the elements from the
1501 // arguments object.
1502 __ bind(&entry);
1503 __ LoadP(r4, MemOperand(fp, kLimitOffset));
1504 __ cmp(r3, r4);
1505 __ bne(&loop);
1506 1531
1507 // Call the function. 1532 // Call the function.
1508 Label call_proxy; 1533 Label call_proxy;
1509 ParameterCount actual(r3); 1534 ParameterCount actual(r3);
1510 __ SmiUntag(r3);
1511 __ LoadP(r4, MemOperand(fp, kFunctionOffset)); 1535 __ LoadP(r4, MemOperand(fp, kFunctionOffset));
1512 __ CompareObjectType(r4, r5, r5, JS_FUNCTION_TYPE); 1536 __ CompareObjectType(r4, r5, r5, JS_FUNCTION_TYPE);
1513 __ bne(&call_proxy); 1537 __ bne(&call_proxy);
1514 __ InvokeFunction(r4, actual, CALL_FUNCTION, NullCallWrapper()); 1538 __ InvokeFunction(r4, actual, CALL_FUNCTION, NullCallWrapper());
1515 1539
1516 __ LeaveFrame(StackFrame::INTERNAL, 3 * kPointerSize); 1540 __ LeaveFrame(StackFrame::INTERNAL, kStackSize * kPointerSize);
1517 __ blr(); 1541 __ blr();
1518 1542
1519 // Call the function proxy. 1543 // Call the function proxy.
1520 __ bind(&call_proxy); 1544 __ bind(&call_proxy);
1521 __ push(r4); // add function proxy as last argument 1545 __ push(r4); // add function proxy as last argument
1522 __ addi(r3, r3, Operand(1)); 1546 __ addi(r3, r3, Operand(1));
1523 __ li(r5, Operand::Zero()); 1547 __ li(r5, Operand::Zero());
1524 __ GetBuiltinFunction(r4, Builtins::CALL_FUNCTION_PROXY); 1548 __ GetBuiltinFunction(r4, Builtins::CALL_FUNCTION_PROXY);
1525 __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 1549 __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1526 RelocInfo::CODE_TARGET); 1550 RelocInfo::CODE_TARGET);
1527 1551
1528 // Tear down the internal frame and remove function, receiver and args. 1552 // Tear down the internal frame and remove function, receiver and args.
1529 } 1553 }
1530 __ addi(sp, sp, Operand(3 * kPointerSize)); 1554 __ addi(sp, sp, Operand(kStackSize * kPointerSize));
1531 __ blr(); 1555 __ blr();
1532 } 1556 }
1533 1557
1534 1558
1559 static void Generate_ConstructHelper(MacroAssembler* masm) {
1560 const int kFormalParameters = 3;
1561 const int kStackSize = kFormalParameters + 1;
1562
1563 {
1564 FrameScope frame_scope(masm, StackFrame::INTERNAL);
1565 const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize;
1566 const int kArgumentsOffset = kNewTargetOffset + kPointerSize;
1567 const int kFunctionOffset = kArgumentsOffset + kPointerSize;
1568
1569 // If newTarget is not supplied, set it to constructor
1570 Label validate_arguments;
1571 __ LoadP(r3, MemOperand(fp, kNewTargetOffset));
1572 __ CompareRoot(r3, Heap::kUndefinedValueRootIndex);
1573 __ bne(&validate_arguments);
1574 __ LoadP(r3, MemOperand(fp, kFunctionOffset));
1575 __ StoreP(r3, MemOperand(fp, kNewTargetOffset));
1576
1577 // Validate arguments
1578 __ bind(&validate_arguments);
1579 __ LoadP(r3, MemOperand(fp, kFunctionOffset)); // get the function
1580 __ push(r3);
1581 __ LoadP(r3, MemOperand(fp, kArgumentsOffset)); // get the args array
1582 __ push(r3);
1583 __ LoadP(r3, MemOperand(fp, kNewTargetOffset)); // get the new.target
1584 __ push(r3);
1585 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION);
1586
1587 Generate_CheckStackOverflow(masm, kFunctionOffset);
1588
1589 // Push current limit and index.
1590 const int kIndexOffset =
1591 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize);
1592 const int kLimitOffset =
1593 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
1594 __ li(r4, Operand::Zero());
1595 __ Push(r3, r4); // limit and initial index.
1596 // Push newTarget and callee functions
1597 __ LoadP(r3, MemOperand(fp, kNewTargetOffset));
1598 __ push(r3);
1599 __ LoadP(r3, MemOperand(fp, kFunctionOffset));
1600 __ push(r3);
1601
1602 // Copy all arguments from the array to the stack.
1603 Generate_PushAppliedArguments(masm, kArgumentsOffset, kIndexOffset,
1604 kLimitOffset);
1605
1606 // Use undefined feedback vector
1607 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
1608 __ LoadP(r4, MemOperand(fp, kFunctionOffset));
1609
1610 // Call the function.
1611 CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL);
1612 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
1613
1614 __ Drop(1);
1615
1616 // Leave internal frame.
1617 }
1618 __ addi(sp, sp, Operand(kStackSize * kPointerSize));
1619 __ blr();
1620 }
1621
1622
1623 void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
1624 Generate_ApplyHelper(masm, false);
1625 }
1626
1627
1628 void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
1629 Generate_ApplyHelper(masm, true);
1630 }
1631
1632
1633 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
1634 Generate_ConstructHelper(masm);
1635 }
1636
1637
1535 static void ArgumentAdaptorStackCheck(MacroAssembler* masm, 1638 static void ArgumentAdaptorStackCheck(MacroAssembler* masm,
1536 Label* stack_overflow) { 1639 Label* stack_overflow) {
1537 // ----------- S t a t e ------------- 1640 // ----------- S t a t e -------------
1538 // -- r3 : actual number of arguments 1641 // -- r3 : actual number of arguments
1539 // -- r4 : function (passed through to callee) 1642 // -- r4 : function (passed through to callee)
1540 // -- r5 : expected number of arguments 1643 // -- r5 : expected number of arguments
1541 // ----------------------------------- 1644 // -----------------------------------
1542 // Check the stack for overflow. We are not trying to catch 1645 // Check the stack for overflow. We are not trying to catch
1543 // interruptions (e.g. debug break and preemption) here, so the "real stack 1646 // interruptions (e.g. debug break and preemption) here, so the "real stack
1544 // limit" is checked. 1647 // limit" is checked.
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1700 __ bkpt(0); 1803 __ bkpt(0);
1701 } 1804 }
1702 } 1805 }
1703 1806
1704 1807
1705 #undef __ 1808 #undef __
1706 } 1809 }
1707 } // namespace v8::internal 1810 } // namespace v8::internal
1708 1811
1709 #endif // V8_TARGET_ARCH_PPC 1812 #endif // V8_TARGET_ARCH_PPC
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698