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

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

Issue 1021863002: MIPS: [es6] implement Reflect.apply() & Reflect.construct() (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix comment. 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 | « src/mips/builtins-mips.cc ('k') | 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 5
6 6
7 #include "src/v8.h" 7 #include "src/v8.h"
8 8
9 #if V8_TARGET_ARCH_MIPS64 9 #if V8_TARGET_ARCH_MIPS64
10 10
(...skipping 1341 matching lines...) Expand 10 before | Expand all | Expand 10 after
1352 // Check formal and actual parameter counts. 1352 // Check formal and actual parameter counts.
1353 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 1353 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1354 RelocInfo::CODE_TARGET, ne, a2, Operand(a0)); 1354 RelocInfo::CODE_TARGET, ne, a2, Operand(a0));
1355 1355
1356 __ ld(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); 1356 __ ld(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
1357 ParameterCount expected(0); 1357 ParameterCount expected(0);
1358 __ InvokeCode(a3, expected, expected, JUMP_FUNCTION, NullCallWrapper()); 1358 __ InvokeCode(a3, expected, expected, JUMP_FUNCTION, NullCallWrapper());
1359 } 1359 }
1360 1360
1361 1361
1362 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { 1362 static void Generate_CheckStackOverflow(MacroAssembler* masm,
1363 const int kIndexOffset = 1363 const int calleeOffset) {
1364 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); 1364 // Check the stack for overflow. We are not trying to catch
1365 const int kLimitOffset = 1365 // interruptions (e.g. debug break and preemption) here, so the "real stack
1366 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); 1366 // limit" is checked.
1367 const int kArgsOffset = 2 * kPointerSize; 1367 Label okay;
1368 const int kRecvOffset = 3 * kPointerSize; 1368 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
1369 const int kFunctionOffset = 4 * kPointerSize; 1369 // Make a2 the space we have left. The stack might already be overflowed
1370 // here which will cause a2 to become negative.
1371 __ dsubu(a2, sp, a2);
1372 // Check if the arguments will overflow the stack.
1373 __ SmiScale(a7, v0, kPointerSizeLog2);
1374 __ Branch(&okay, gt, a2, Operand(a7)); // Signed comparison.
1375
1376 // Out of stack space.
1377 __ ld(a1, MemOperand(fp, calleeOffset));
1378 __ Push(a1, v0);
1379 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
1380
1381 __ bind(&okay);
1382 }
1383
1384
1385 static void Generate_PushAppliedArguments(MacroAssembler* masm,
1386 const int argumentsOffset,
1387 const int indexOffset,
1388 const int limitOffset) {
1389 Label entry, loop;
1390 __ ld(a0, MemOperand(fp, indexOffset));
1391 __ Branch(&entry);
1392
1393 // Load the current argument from the arguments array and push it to the
1394 // stack.
1395 // a0: current argument index
1396 __ bind(&loop);
1397 __ ld(a1, MemOperand(fp, argumentsOffset));
1398 __ Push(a1, a0);
1399
1400 // Call the runtime to access the property in the arguments array.
1401 __ CallRuntime(Runtime::kGetProperty, 2);
1402 __ push(v0);
1403
1404 // Use inline caching to access the arguments.
1405 __ ld(a0, MemOperand(fp, indexOffset));
1406 __ Daddu(a0, a0, Operand(Smi::FromInt(1)));
1407 __ sd(a0, MemOperand(fp, indexOffset));
1408
1409 // Test if the copy loop has finished copying all the elements from the
1410 // arguments object.
1411 __ bind(&entry);
1412 __ ld(a1, MemOperand(fp, limitOffset));
1413 __ Branch(&loop, ne, a0, Operand(a1));
1414
1415 // On exit, the pushed arguments count is in a0, untagged
1416 __ SmiUntag(a0);
1417 }
1418
1419
1420 // Used by FunctionApply and ReflectApply
1421 static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
1422 const int kFormalParameters = targetIsArgument ? 3 : 2;
1423 const int kStackSize = kFormalParameters + 1;
1370 1424
1371 { 1425 {
1372 FrameScope frame_scope(masm, StackFrame::INTERNAL); 1426 FrameScope frame_scope(masm, StackFrame::INTERNAL);
1427 const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize;
1428 const int kReceiverOffset = kArgumentsOffset + kPointerSize;
1429 const int kFunctionOffset = kReceiverOffset + kPointerSize;
1430
1373 __ ld(a0, MemOperand(fp, kFunctionOffset)); // Get the function. 1431 __ ld(a0, MemOperand(fp, kFunctionOffset)); // Get the function.
1374 __ push(a0); 1432 __ push(a0);
1375 __ ld(a0, MemOperand(fp, kArgsOffset)); // Get the args array. 1433 __ ld(a0, MemOperand(fp, kArgumentsOffset)); // Get the args array.
1376 __ push(a0); 1434 __ push(a0);
1435
1377 // Returns (in v0) number of arguments to copy to stack as Smi. 1436 // Returns (in v0) number of arguments to copy to stack as Smi.
1378 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); 1437 if (targetIsArgument) {
1438 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION);
1439 } else {
1440 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
1441 }
1379 1442
1380 // Check the stack for overflow. We are not trying to catch 1443 Generate_CheckStackOverflow(masm, kFunctionOffset);
1381 // interruptions (e.g. debug break and preemption) here, so the "real stack
1382 // limit" is checked.
1383 Label okay;
1384 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
1385 // Make a2 the space we have left. The stack might already be overflowed
1386 // here which will cause a2 to become negative.
1387 __ dsubu(a2, sp, a2);
1388 // Check if the arguments will overflow the stack.
1389 __ SmiScale(a7, v0, kPointerSizeLog2);
1390 __ Branch(&okay, gt, a2, Operand(a7)); // Signed comparison.
1391
1392 // Out of stack space.
1393 __ ld(a1, MemOperand(fp, kFunctionOffset));
1394 __ Push(a1, v0);
1395 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
1396 // End of stack check.
1397 1444
1398 // Push current limit and index. 1445 // Push current limit and index.
1399 __ bind(&okay); 1446 const int kIndexOffset =
1447 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize);
1448 const int kLimitOffset =
1449 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
1400 __ mov(a1, zero_reg); 1450 __ mov(a1, zero_reg);
1401 __ Push(v0, a1); // Limit and initial index. 1451 __ Push(v0, a1); // Limit and initial index.
1402 1452
1403 // Get the receiver. 1453 // Get the receiver.
1404 __ ld(a0, MemOperand(fp, kRecvOffset)); 1454 __ ld(a0, MemOperand(fp, kReceiverOffset));
1405 1455
1406 // Check that the function is a JS function (otherwise it must be a proxy). 1456 // Check that the function is a JS function (otherwise it must be a proxy).
1407 Label push_receiver; 1457 Label push_receiver;
1408 __ ld(a1, MemOperand(fp, kFunctionOffset)); 1458 __ ld(a1, MemOperand(fp, kFunctionOffset));
1409 __ GetObjectType(a1, a2, a2); 1459 __ GetObjectType(a1, a2, a2);
1410 __ Branch(&push_receiver, ne, a2, Operand(JS_FUNCTION_TYPE)); 1460 __ Branch(&push_receiver, ne, a2, Operand(JS_FUNCTION_TYPE));
1411 1461
1412 // Change context eagerly to get the right global object if necessary. 1462 // Change context eagerly to get the right global object if necessary.
1413 __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); 1463 __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
1414 // Load the shared function info while the function is still in a1. 1464 // Load the shared function info while the function is still in a1.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1450 __ bind(&use_global_proxy); 1500 __ bind(&use_global_proxy);
1451 __ ld(a0, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); 1501 __ ld(a0, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
1452 __ ld(a0, FieldMemOperand(a0, GlobalObject::kGlobalProxyOffset)); 1502 __ ld(a0, FieldMemOperand(a0, GlobalObject::kGlobalProxyOffset));
1453 1503
1454 // Push the receiver. 1504 // Push the receiver.
1455 // a0: receiver 1505 // a0: receiver
1456 __ bind(&push_receiver); 1506 __ bind(&push_receiver);
1457 __ push(a0); 1507 __ push(a0);
1458 1508
1459 // Copy all arguments from the array to the stack. 1509 // Copy all arguments from the array to the stack.
1460 Label entry, loop; 1510 Generate_PushAppliedArguments(
1461 __ ld(a0, MemOperand(fp, kIndexOffset)); 1511 masm, kArgumentsOffset, kIndexOffset, kLimitOffset);
1462 __ Branch(&entry);
1463
1464 // Load the current argument from the arguments array and push it to the
1465 // stack.
1466 // a0: current argument index
1467 __ bind(&loop);
1468 __ ld(a1, MemOperand(fp, kArgsOffset));
1469 __ Push(a1, a0);
1470
1471 // Call the runtime to access the property in the arguments array.
1472 __ CallRuntime(Runtime::kGetProperty, 2);
1473 __ push(v0);
1474
1475 // Use inline caching to access the arguments.
1476 __ ld(a0, MemOperand(fp, kIndexOffset));
1477 __ Daddu(a0, a0, Operand(Smi::FromInt(1)));
1478 __ sd(a0, MemOperand(fp, kIndexOffset));
1479
1480 // Test if the copy loop has finished copying all the elements from the
1481 // arguments object.
1482 __ bind(&entry);
1483 __ ld(a1, MemOperand(fp, kLimitOffset));
1484 __ Branch(&loop, ne, a0, Operand(a1));
1485 1512
1486 // Call the function. 1513 // Call the function.
1487 Label call_proxy; 1514 Label call_proxy;
1488 ParameterCount actual(a0); 1515 ParameterCount actual(a0);
1489 __ SmiUntag(a0);
1490 __ ld(a1, MemOperand(fp, kFunctionOffset)); 1516 __ ld(a1, MemOperand(fp, kFunctionOffset));
1491 __ GetObjectType(a1, a2, a2); 1517 __ GetObjectType(a1, a2, a2);
1492 __ Branch(&call_proxy, ne, a2, Operand(JS_FUNCTION_TYPE)); 1518 __ Branch(&call_proxy, ne, a2, Operand(JS_FUNCTION_TYPE));
1493 1519
1494 __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper()); 1520 __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper());
1495 1521
1496 frame_scope.GenerateLeaveFrame(); 1522 frame_scope.GenerateLeaveFrame();
1497 __ Ret(USE_DELAY_SLOT); 1523 __ Ret(USE_DELAY_SLOT);
1498 __ Daddu(sp, sp, Operand(3 * kPointerSize)); // In delay slot. 1524 __ Daddu(sp, sp, Operand(kStackSize * kPointerSize)); // In delay slot.
1499 1525
1500 // Call the function proxy. 1526 // Call the function proxy.
1501 __ bind(&call_proxy); 1527 __ bind(&call_proxy);
1502 __ push(a1); // Add function proxy as last argument. 1528 __ push(a1); // Add function proxy as last argument.
1503 __ Daddu(a0, a0, Operand(1)); 1529 __ Daddu(a0, a0, Operand(1));
1504 __ li(a2, Operand(0, RelocInfo::NONE32)); 1530 __ li(a2, Operand(0, RelocInfo::NONE32));
1505 __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY); 1531 __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY);
1506 __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 1532 __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1507 RelocInfo::CODE_TARGET); 1533 RelocInfo::CODE_TARGET);
1508 // Tear down the internal frame and remove function, receiver and args. 1534 // Tear down the internal frame and remove function, receiver and args.
1509 } 1535 }
1510 1536
1511 __ Ret(USE_DELAY_SLOT); 1537 __ Ret(USE_DELAY_SLOT);
1512 __ Daddu(sp, sp, Operand(3 * kPointerSize)); // In delay slot. 1538 __ Daddu(sp, sp, Operand(kStackSize * kPointerSize)); // In delay slot.
1513 } 1539 }
1514 1540
1515 1541
1542 static void Generate_ConstructHelper(MacroAssembler* masm) {
1543 const int kFormalParameters = 3;
1544 const int kStackSize = kFormalParameters + 1;
1545
1546 {
1547 FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL);
1548 const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize;
1549 const int kArgumentsOffset = kNewTargetOffset + kPointerSize;
1550 const int kFunctionOffset = kArgumentsOffset + kPointerSize;
1551
1552 // If newTarget is not supplied, set it to constructor
1553 Label validate_arguments;
1554 __ ld(a0, MemOperand(fp, kNewTargetOffset));
1555 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
1556 __ Branch(&validate_arguments, ne, a0, Operand(at));
1557 __ ld(a0, MemOperand(fp, kFunctionOffset));
1558 __ sd(a0, MemOperand(fp, kNewTargetOffset));
1559
1560 // Validate arguments
1561 __ bind(&validate_arguments);
1562 __ ld(a0, MemOperand(fp, kFunctionOffset)); // get the function
1563 __ push(a0);
1564 __ ld(a0, MemOperand(fp, kArgumentsOffset)); // get the args array
1565 __ push(a0);
1566 __ ld(a0, MemOperand(fp, kNewTargetOffset)); // get the new.target
1567 __ push(a0);
1568 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION);
1569
1570 Generate_CheckStackOverflow(masm, kFunctionOffset);
1571
1572 // Push current limit and index.
1573 const int kIndexOffset =
1574 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize);
1575 const int kLimitOffset =
1576 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
1577 __ push(v0); // limit
1578 __ mov(a1, zero_reg); // initial index
1579 __ push(a1);
1580 // Push newTarget and callee functions
1581 __ ld(a0, MemOperand(fp, kNewTargetOffset));
1582 __ push(a0);
1583 __ ld(a0, MemOperand(fp, kFunctionOffset));
1584 __ push(a0);
1585
1586 // Copy all arguments from the array to the stack.
1587 Generate_PushAppliedArguments(
1588 masm, kArgumentsOffset, kIndexOffset, kLimitOffset);
1589
1590 // Use undefined feedback vector
1591 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
1592 __ ld(a1, MemOperand(fp, kFunctionOffset));
1593
1594 // Call the function.
1595 CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL);
1596 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
1597
1598 __ Drop(1);
1599
1600 // Leave internal frame.
1601 }
1602 __ Daddu(sp, sp, Operand(kStackSize * kPointerSize));
1603 __ Jump(ra);
1604 }
1605
1606
1607 void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
1608 Generate_ApplyHelper(masm, false);
1609 }
1610
1611
1612 void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
1613 Generate_ApplyHelper(masm, true);
1614 }
1615
1616
1617 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
1618 Generate_ConstructHelper(masm);
1619 }
1620
1621
1516 static void ArgumentAdaptorStackCheck(MacroAssembler* masm, 1622 static void ArgumentAdaptorStackCheck(MacroAssembler* masm,
1517 Label* stack_overflow) { 1623 Label* stack_overflow) {
1518 // ----------- S t a t e ------------- 1624 // ----------- S t a t e -------------
1519 // -- a0 : actual number of arguments 1625 // -- a0 : actual number of arguments
1520 // -- a1 : function (passed through to callee) 1626 // -- a1 : function (passed through to callee)
1521 // -- a2 : expected number of arguments 1627 // -- a2 : expected number of arguments
1522 // ----------------------------------- 1628 // -----------------------------------
1523 // Check the stack for overflow. We are not trying to catch 1629 // Check the stack for overflow. We are not trying to catch
1524 // interruptions (e.g. debug break and preemption) here, so the "real stack 1630 // interruptions (e.g. debug break and preemption) here, so the "real stack
1525 // limit" is checked. 1631 // limit" is checked.
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
1688 __ break_(0xCC); 1794 __ break_(0xCC);
1689 } 1795 }
1690 } 1796 }
1691 1797
1692 1798
1693 #undef __ 1799 #undef __
1694 1800
1695 } } // namespace v8::internal 1801 } } // namespace v8::internal
1696 1802
1697 #endif // V8_TARGET_ARCH_MIPS64 1803 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/mips/builtins-mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698