Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
| 6 | 6 |
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
| 9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
| 10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
| (...skipping 1425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1436 __ movp(rdx, rdi); | 1436 __ movp(rdx, rdi); |
| 1437 // Run the native code for the Array function called as a normal function. | 1437 // Run the native code for the Array function called as a normal function. |
| 1438 // tail call a stub | 1438 // tail call a stub |
| 1439 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); | 1439 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); |
| 1440 ArrayConstructorStub stub(masm->isolate()); | 1440 ArrayConstructorStub stub(masm->isolate()); |
| 1441 __ TailCallStub(&stub); | 1441 __ TailCallStub(&stub); |
| 1442 } | 1442 } |
| 1443 | 1443 |
| 1444 | 1444 |
| 1445 // static | 1445 // static |
| 1446 void Builtins::Generate_NumberConstructor(MacroAssembler* masm) { | |
| 1447 // ----------- S t a t e ------------- | |
| 1448 // -- rax : number of arguments | |
| 1449 // -- rdi : constructor function | |
| 1450 // -- rsp[0] : return address | |
| 1451 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | |
| 1452 // -- rsp[(argc + 1) * 8] : receiver | |
| 1453 // ----------------------------------- | |
| 1454 | |
| 1455 // 1. Load the first argument into rax and get rid of the rest (including the | |
| 1456 // receiver). | |
| 1457 Label no_arguments; | |
| 1458 { | |
| 1459 StackArgumentsAccessor args(rsp, rax); | |
| 1460 __ testp(rax, rax); | |
| 1461 __ j(zero, &no_arguments, Label::kNear); | |
| 1462 __ movp(rbx, args.GetArgumentOperand(1)); | |
| 1463 __ PopReturnAddressTo(rcx); | |
| 1464 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize)); | |
| 1465 __ PushReturnAddressFrom(rcx); | |
| 1466 __ movp(rax, rbx); | |
| 1467 } | |
| 1468 | |
| 1469 // 2a. Convert the first argument to a number. | |
| 1470 ToNumberStub stub(masm->isolate()); | |
| 1471 __ TailCallStub(&stub); | |
| 1472 | |
| 1473 // 2b. No arguments, return +0 (already in rax). | |
|
Jarin
2016/01/13 12:05:19
Hmm, I see it's already micro-optimized...
| |
| 1474 __ bind(&no_arguments); | |
| 1475 __ ret(1 * kPointerSize); | |
| 1476 } | |
| 1477 | |
| 1478 | |
| 1479 // static | |
| 1480 void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) { | |
| 1481 // ----------- S t a t e ------------- | |
| 1482 // -- rax : number of arguments | |
| 1483 // -- rdi : constructor function | |
| 1484 // -- rdx : new target | |
| 1485 // -- rsp[0] : return address | |
| 1486 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | |
| 1487 // -- rsp[(argc + 1) * 8] : receiver | |
| 1488 // ----------------------------------- | |
| 1489 | |
| 1490 // 1. Make sure we operate in the context of the called function. | |
| 1491 __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | |
| 1492 | |
| 1493 // 2. Load the first argument into rbx and get rid of the rest (including the | |
| 1494 // receiver). | |
| 1495 { | |
| 1496 StackArgumentsAccessor args(rsp, rax); | |
| 1497 Label no_arguments, done; | |
| 1498 __ testp(rax, rax); | |
| 1499 __ j(zero, &no_arguments, Label::kNear); | |
| 1500 __ movp(rbx, args.GetArgumentOperand(1)); | |
| 1501 __ jmp(&done, Label::kNear); | |
| 1502 __ bind(&no_arguments); | |
| 1503 __ Move(rbx, Smi::FromInt(0)); | |
| 1504 __ bind(&done); | |
| 1505 __ PopReturnAddressTo(rcx); | |
| 1506 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize)); | |
| 1507 __ PushReturnAddressFrom(rcx); | |
| 1508 } | |
| 1509 | |
| 1510 // 3. Make sure rbx is a number. | |
| 1511 { | |
| 1512 Label done_convert; | |
| 1513 __ JumpIfSmi(rbx, &done_convert); | |
| 1514 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), | |
| 1515 Heap::kHeapNumberMapRootIndex); | |
| 1516 __ j(equal, &done_convert); | |
| 1517 { | |
| 1518 FrameScope scope(masm, StackFrame::INTERNAL); | |
| 1519 __ Push(rdx); | |
| 1520 __ Push(rdi); | |
| 1521 __ Move(rax, rbx); | |
| 1522 ToNumberStub stub(masm->isolate()); | |
| 1523 __ CallStub(&stub); | |
| 1524 __ Move(rbx, rax); | |
| 1525 __ Pop(rdi); | |
| 1526 __ Pop(rdx); | |
| 1527 } | |
| 1528 __ bind(&done_convert); | |
| 1529 } | |
| 1530 | |
| 1531 // 4. Check if new target and constructor differ. | |
| 1532 Label new_object; | |
| 1533 __ cmpp(rdx, rdi); | |
| 1534 __ j(not_equal, &new_object); | |
| 1535 | |
| 1536 // 5. Allocate a JSValue wrapper for the number. | |
| 1537 __ AllocateJSValue(rax, rdi, rbx, rcx, &new_object); | |
| 1538 __ Ret(); | |
| 1539 | |
| 1540 // 6. Fallback to the runtime to create new object. | |
| 1541 __ bind(&new_object); | |
| 1542 { | |
| 1543 FrameScope scope(masm, StackFrame::INTERNAL); | |
| 1544 __ Push(rbx); // the first argument | |
| 1545 __ Push(rdi); // constructor function | |
| 1546 __ Push(rdx); // new target | |
| 1547 __ CallRuntime(Runtime::kNewObject); | |
| 1548 __ Pop(FieldOperand(rax, JSValue::kValueOffset)); | |
| 1549 } | |
| 1550 __ Ret(); | |
| 1551 } | |
| 1552 | |
| 1553 | |
| 1554 // static | |
| 1446 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { | 1555 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { |
| 1447 // ----------- S t a t e ------------- | 1556 // ----------- S t a t e ------------- |
| 1448 // -- rax : number of arguments | 1557 // -- rax : number of arguments |
| 1449 // -- rdi : constructor function | 1558 // -- rdi : constructor function |
| 1450 // -- rsp[0] : return address | 1559 // -- rsp[0] : return address |
| 1451 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1560 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
| 1452 // -- rsp[(argc + 1) * 8] : receiver | 1561 // -- rsp[(argc + 1) * 8] : receiver |
| 1453 // ----------------------------------- | 1562 // ----------------------------------- |
| 1454 | 1563 |
| 1455 // 1. Load the first argument into rax and get rid of the rest (including the | 1564 // 1. Load the first argument into rax and get rid of the rest (including the |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1507 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { | 1616 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { |
| 1508 // ----------- S t a t e ------------- | 1617 // ----------- S t a t e ------------- |
| 1509 // -- rax : number of arguments | 1618 // -- rax : number of arguments |
| 1510 // -- rdi : constructor function | 1619 // -- rdi : constructor function |
| 1511 // -- rdx : new target | 1620 // -- rdx : new target |
| 1512 // -- rsp[0] : return address | 1621 // -- rsp[0] : return address |
| 1513 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1622 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
| 1514 // -- rsp[(argc + 1) * 8] : receiver | 1623 // -- rsp[(argc + 1) * 8] : receiver |
| 1515 // ----------------------------------- | 1624 // ----------------------------------- |
| 1516 | 1625 |
| 1517 // 1. Load the first argument into rbx and get rid of the rest (including the | 1626 // 1. Make sure we operate in the context of the called function. |
| 1627 __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | |
| 1628 | |
| 1629 // 2. Load the first argument into rbx and get rid of the rest (including the | |
| 1518 // receiver). | 1630 // receiver). |
| 1519 { | 1631 { |
| 1520 StackArgumentsAccessor args(rsp, rax); | 1632 StackArgumentsAccessor args(rsp, rax); |
| 1521 Label no_arguments, done; | 1633 Label no_arguments, done; |
| 1522 __ testp(rax, rax); | 1634 __ testp(rax, rax); |
| 1523 __ j(zero, &no_arguments, Label::kNear); | 1635 __ j(zero, &no_arguments, Label::kNear); |
| 1524 __ movp(rbx, args.GetArgumentOperand(1)); | 1636 __ movp(rbx, args.GetArgumentOperand(1)); |
| 1525 __ jmp(&done, Label::kNear); | 1637 __ jmp(&done, Label::kNear); |
| 1526 __ bind(&no_arguments); | 1638 __ bind(&no_arguments); |
| 1527 __ LoadRoot(rbx, Heap::kempty_stringRootIndex); | 1639 __ LoadRoot(rbx, Heap::kempty_stringRootIndex); |
| 1528 __ bind(&done); | 1640 __ bind(&done); |
| 1529 __ PopReturnAddressTo(rcx); | 1641 __ PopReturnAddressTo(rcx); |
| 1530 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize)); | 1642 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize)); |
| 1531 __ PushReturnAddressFrom(rcx); | 1643 __ PushReturnAddressFrom(rcx); |
| 1532 } | 1644 } |
| 1533 | 1645 |
| 1534 // 2. Make sure rbx is a string. | 1646 // 3. Make sure rbx is a string. |
| 1535 { | 1647 { |
| 1536 Label convert, done_convert; | 1648 Label convert, done_convert; |
| 1537 __ JumpIfSmi(rbx, &convert, Label::kNear); | 1649 __ JumpIfSmi(rbx, &convert, Label::kNear); |
| 1538 __ CmpObjectType(rbx, FIRST_NONSTRING_TYPE, rcx); | 1650 __ CmpObjectType(rbx, FIRST_NONSTRING_TYPE, rcx); |
| 1539 __ j(below, &done_convert); | 1651 __ j(below, &done_convert); |
| 1540 __ bind(&convert); | 1652 __ bind(&convert); |
| 1541 { | 1653 { |
| 1542 FrameScope scope(masm, StackFrame::INTERNAL); | 1654 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1543 ToStringStub stub(masm->isolate()); | 1655 ToStringStub stub(masm->isolate()); |
| 1544 __ Push(rdx); | 1656 __ Push(rdx); |
| 1545 __ Push(rdi); | 1657 __ Push(rdi); |
| 1546 __ Move(rax, rbx); | 1658 __ Move(rax, rbx); |
| 1547 __ CallStub(&stub); | 1659 __ CallStub(&stub); |
| 1548 __ Move(rbx, rax); | 1660 __ Move(rbx, rax); |
| 1549 __ Pop(rdi); | 1661 __ Pop(rdi); |
| 1550 __ Pop(rdx); | 1662 __ Pop(rdx); |
| 1551 } | 1663 } |
| 1552 __ bind(&done_convert); | 1664 __ bind(&done_convert); |
| 1553 } | 1665 } |
| 1554 | 1666 |
| 1555 // 3. Check if new target and constructor differ. | 1667 // 4. Check if new target and constructor differ. |
| 1556 Label new_object; | 1668 Label new_object; |
| 1557 __ cmpp(rdx, rdi); | 1669 __ cmpp(rdx, rdi); |
| 1558 __ j(not_equal, &new_object); | 1670 __ j(not_equal, &new_object); |
| 1559 | 1671 |
| 1560 // 4. Allocate a JSValue wrapper for the string. | 1672 // 5. Allocate a JSValue wrapper for the string. |
| 1561 { | 1673 __ AllocateJSValue(rax, rdi, rbx, rcx, &new_object); |
| 1562 // ----------- S t a t e ------------- | 1674 __ Ret(); |
| 1563 // -- rbx : the first argument | |
| 1564 // -- rdi : constructor function | |
| 1565 // -- rdx : new target | |
| 1566 // ----------------------------------- | |
| 1567 __ Allocate(JSValue::kSize, rax, rcx, no_reg, &new_object, TAG_OBJECT); | |
| 1568 | 1675 |
| 1569 // Initialize the JSValue in rax. | 1676 // 6. Fallback to the runtime to create new object. |
| 1570 __ LoadGlobalFunctionInitialMap(rdi, rcx); | |
| 1571 __ movp(FieldOperand(rax, HeapObject::kMapOffset), rcx); | |
| 1572 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex); | |
| 1573 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rcx); | |
| 1574 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rcx); | |
| 1575 __ movp(FieldOperand(rax, JSValue::kValueOffset), rbx); | |
| 1576 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); | |
| 1577 __ Ret(); | |
| 1578 } | |
| 1579 | |
| 1580 // 5. Fallback to the runtime to create new object. | |
| 1581 __ bind(&new_object); | 1677 __ bind(&new_object); |
| 1582 { | 1678 { |
| 1583 FrameScope scope(masm, StackFrame::INTERNAL); | 1679 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1584 __ Push(rbx); // the first argument | 1680 __ Push(rbx); // the first argument |
| 1585 __ Push(rdi); // constructor function | 1681 __ Push(rdi); // constructor function |
| 1586 __ Push(rdx); // new target | 1682 __ Push(rdx); // new target |
| 1587 __ CallRuntime(Runtime::kNewObject); | 1683 __ CallRuntime(Runtime::kNewObject); |
| 1588 __ Pop(FieldOperand(rax, JSValue::kValueOffset)); | 1684 __ Pop(FieldOperand(rax, JSValue::kValueOffset)); |
| 1589 } | 1685 } |
| 1590 __ Ret(); | 1686 __ Ret(); |
| (...skipping 896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2487 __ ret(0); | 2583 __ ret(0); |
| 2488 } | 2584 } |
| 2489 | 2585 |
| 2490 | 2586 |
| 2491 #undef __ | 2587 #undef __ |
| 2492 | 2588 |
| 2493 } // namespace internal | 2589 } // namespace internal |
| 2494 } // namespace v8 | 2590 } // namespace v8 |
| 2495 | 2591 |
| 2496 #endif // V8_TARGET_ARCH_X64 | 2592 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |