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

Side by Side Diff: src/mips/stub-cache-mips.cc

Issue 148343005: A64: Synchronize with r18147. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
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 | « src/mips/macro-assembler-mips.cc ('k') | src/object-observe.js » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, 725 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
726 Label* label, 726 Label* label,
727 Handle<Name> name) { 727 Handle<Name> name) {
728 if (!label->is_unused()) { 728 if (!label->is_unused()) {
729 __ bind(label); 729 __ bind(label);
730 __ li(this->name(), Operand(name)); 730 __ li(this->name(), Operand(name));
731 } 731 }
732 } 732 }
733 733
734 734
735 static void GenerateCallFunction(MacroAssembler* masm,
736 Handle<Object> object,
737 const ParameterCount& arguments,
738 Label* miss,
739 Code::ExtraICState extra_ic_state) {
740 // ----------- S t a t e -------------
741 // -- a0: receiver
742 // -- a1: function to call
743 // -----------------------------------
744 // Check that the function really is a function.
745 __ JumpIfSmi(a1, miss);
746 __ GetObjectType(a1, a3, a3);
747 __ Branch(miss, ne, a3, Operand(JS_FUNCTION_TYPE));
748
749 // Patch the receiver on the stack with the global proxy if
750 // necessary.
751 if (object->IsGlobalObject()) {
752 __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset));
753 __ sw(a3, MemOperand(sp, arguments.immediate() * kPointerSize));
754 }
755
756 // Invoke the function.
757 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state)
758 ? CALL_AS_FUNCTION
759 : CALL_AS_METHOD;
760 __ InvokeFunction(a1, arguments, JUMP_FUNCTION, NullCallWrapper(), call_kind);
761 }
762
763
764 static void PushInterceptorArguments(MacroAssembler* masm, 735 static void PushInterceptorArguments(MacroAssembler* masm,
765 Register receiver, 736 Register receiver,
766 Register holder, 737 Register holder,
767 Register name, 738 Register name,
768 Handle<JSObject> holder_obj) { 739 Handle<JSObject> holder_obj) {
769 STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0); 740 STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0);
770 STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1); 741 STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1);
771 STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2); 742 STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2);
772 STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3); 743 STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3);
773 STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4); 744 STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4);
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 ASSERT(!scratch.is(values[i])); 906 ASSERT(!scratch.is(values[i]));
936 __ sw(receiver, MemOperand(sp, index-- * kPointerSize)); 907 __ sw(receiver, MemOperand(sp, index-- * kPointerSize));
937 } 908 }
938 909
939 GenerateFastApiDirectCall(masm, optimization, argc, true); 910 GenerateFastApiDirectCall(masm, optimization, argc, true);
940 } 911 }
941 912
942 913
943 class CallInterceptorCompiler BASE_EMBEDDED { 914 class CallInterceptorCompiler BASE_EMBEDDED {
944 public: 915 public:
945 CallInterceptorCompiler(StubCompiler* stub_compiler, 916 CallInterceptorCompiler(CallStubCompiler* stub_compiler,
946 const ParameterCount& arguments, 917 const ParameterCount& arguments,
947 Register name, 918 Register name,
948 Code::ExtraICState extra_ic_state) 919 ExtraICState extra_ic_state)
949 : stub_compiler_(stub_compiler), 920 : stub_compiler_(stub_compiler),
950 arguments_(arguments), 921 arguments_(arguments),
951 name_(name), 922 name_(name),
952 extra_ic_state_(extra_ic_state) {} 923 extra_ic_state_(extra_ic_state) {}
953 924
954 void Compile(MacroAssembler* masm, 925 void Compile(MacroAssembler* masm,
955 Handle<JSObject> object, 926 Handle<JSObject> object,
956 Handle<JSObject> holder, 927 Handle<JSObject> holder,
957 Handle<Name> name, 928 Handle<Name> name,
958 LookupResult* lookup, 929 LookupResult* lookup,
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1047 // safe to omit it here, as if present, it should be fetched 1018 // safe to omit it here, as if present, it should be fetched
1048 // by the previous CheckPrototypes. 1019 // by the previous CheckPrototypes.
1049 ASSERT(depth2 == kInvalidProtoDepth); 1020 ASSERT(depth2 == kInvalidProtoDepth);
1050 } 1021 }
1051 1022
1052 // Invoke function. 1023 // Invoke function.
1053 if (can_do_fast_api_call) { 1024 if (can_do_fast_api_call) {
1054 GenerateFastApiDirectCall( 1025 GenerateFastApiDirectCall(
1055 masm, optimization, arguments_.immediate(), false); 1026 masm, optimization, arguments_.immediate(), false);
1056 } else { 1027 } else {
1057 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
1058 ? CALL_AS_FUNCTION
1059 : CALL_AS_METHOD;
1060 Handle<JSFunction> function = optimization.constant_function(); 1028 Handle<JSFunction> function = optimization.constant_function();
1061 ParameterCount expected(function); 1029 stub_compiler_->GenerateJumpFunction(object, function);
1062 __ InvokeFunction(function, expected, arguments_,
1063 JUMP_FUNCTION, NullCallWrapper(), call_kind);
1064 } 1030 }
1065 1031
1066 // Deferred code for fast API call case---clean preallocated space. 1032 // Deferred code for fast API call case---clean preallocated space.
1067 if (can_do_fast_api_call) { 1033 if (can_do_fast_api_call) {
1068 __ bind(&miss_cleanup); 1034 __ bind(&miss_cleanup);
1069 FreeSpaceForFastApiCall(masm); 1035 FreeSpaceForFastApiCall(masm);
1070 __ Branch(miss_label); 1036 __ Branch(miss_label);
1071 } 1037 }
1072 1038
1073 // Invoke a regular function. 1039 // Invoke a regular function.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1119 masm, receiver, holder, name_, holder_obj, 1085 masm, receiver, holder, name_, holder_obj,
1120 IC::kLoadPropertyWithInterceptorOnly); 1086 IC::kLoadPropertyWithInterceptorOnly);
1121 __ pop(name_); // Restore the name. 1087 __ pop(name_); // Restore the name.
1122 __ pop(receiver); // Restore the holder. 1088 __ pop(receiver); // Restore the holder.
1123 } 1089 }
1124 // If interceptor returns no-result sentinel, call the constant function. 1090 // If interceptor returns no-result sentinel, call the constant function.
1125 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex); 1091 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex);
1126 __ Branch(interceptor_succeeded, ne, v0, Operand(scratch)); 1092 __ Branch(interceptor_succeeded, ne, v0, Operand(scratch));
1127 } 1093 }
1128 1094
1129 StubCompiler* stub_compiler_; 1095 CallStubCompiler* stub_compiler_;
1130 const ParameterCount& arguments_; 1096 const ParameterCount& arguments_;
1131 Register name_; 1097 Register name_;
1132 Code::ExtraICState extra_ic_state_; 1098 ExtraICState extra_ic_state_;
1133 }; 1099 };
1134 1100
1135 1101
1136 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { 1102 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
1137 __ Jump(code, RelocInfo::CODE_TARGET); 1103 __ Jump(code, RelocInfo::CODE_TARGET);
1138 } 1104 }
1139 1105
1140 1106
1141 #undef __ 1107 #undef __
1142 #define __ ACCESS_MASM(masm()) 1108 #define __ ACCESS_MASM(masm())
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
1520 } 1486 }
1521 1487
1522 1488
1523 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { 1489 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) {
1524 if (kind_ == Code::KEYED_CALL_IC) { 1490 if (kind_ == Code::KEYED_CALL_IC) {
1525 __ Branch(miss, ne, a2, Operand(name)); 1491 __ Branch(miss, ne, a2, Operand(name));
1526 } 1492 }
1527 } 1493 }
1528 1494
1529 1495
1530 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object, 1496 void CallStubCompiler::GenerateFunctionCheck(Register function,
1531 Handle<JSObject> holder, 1497 Register scratch,
1532 Handle<Name> name, 1498 Label* miss) {
1533 Label* miss) { 1499 __ JumpIfSmi(function, miss);
1534 ASSERT(holder->IsGlobalObject()); 1500 __ GetObjectType(function, scratch, scratch);
1535 1501 __ Branch(miss, ne, scratch, Operand(JS_FUNCTION_TYPE));
1536 // Get the number of arguments.
1537 const int argc = arguments().immediate();
1538
1539 // Get the receiver from the stack.
1540 __ lw(a0, MemOperand(sp, argc * kPointerSize));
1541
1542 // Check that the maps haven't changed.
1543 __ JumpIfSmi(a0, miss);
1544 CheckPrototypes(
1545 IC::CurrentTypeOf(object, isolate()), a0, holder, a3, a1, t0, name, miss);
1546 } 1502 }
1547 1503
1548 1504
1549 void CallStubCompiler::GenerateLoadFunctionFromCell( 1505 void CallStubCompiler::GenerateLoadFunctionFromCell(
1550 Handle<Cell> cell, 1506 Handle<Cell> cell,
1551 Handle<JSFunction> function, 1507 Handle<JSFunction> function,
1552 Label* miss) { 1508 Label* miss) {
1553 // Get the value from the cell. 1509 // Get the value from the cell.
1554 __ li(a3, Operand(cell)); 1510 __ li(a3, Operand(cell));
1555 __ lw(a1, FieldMemOperand(a3, Cell::kValueOffset)); 1511 __ lw(a1, FieldMemOperand(a3, Cell::kValueOffset));
1556 1512
1557 // Check that the cell contains the same function. 1513 // Check that the cell contains the same function.
1558 if (heap()->InNewSpace(*function)) { 1514 if (heap()->InNewSpace(*function)) {
1559 // We can't embed a pointer to a function in new space so we have 1515 // We can't embed a pointer to a function in new space so we have
1560 // to verify that the shared function info is unchanged. This has 1516 // to verify that the shared function info is unchanged. This has
1561 // the nice side effect that multiple closures based on the same 1517 // the nice side effect that multiple closures based on the same
1562 // function can all use this call IC. Before we load through the 1518 // function can all use this call IC. Before we load through the
1563 // function, we have to verify that it still is a function. 1519 // function, we have to verify that it still is a function.
1564 __ JumpIfSmi(a1, miss); 1520 GenerateFunctionCheck(a1, a3, miss);
1565 __ GetObjectType(a1, a3, a3);
1566 __ Branch(miss, ne, a3, Operand(JS_FUNCTION_TYPE));
1567 1521
1568 // Check the shared function info. Make sure it hasn't changed. 1522 // Check the shared function info. Make sure it hasn't changed.
1569 __ li(a3, Handle<SharedFunctionInfo>(function->shared())); 1523 __ li(a3, Handle<SharedFunctionInfo>(function->shared()));
1570 __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); 1524 __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
1571 __ Branch(miss, ne, t0, Operand(a3)); 1525 __ Branch(miss, ne, t0, Operand(a3));
1572 } else { 1526 } else {
1573 __ Branch(miss, ne, a1, Operand(function)); 1527 __ Branch(miss, ne, a1, Operand(function));
1574 } 1528 }
1575 } 1529 }
1576 1530
1577 1531
1578 void CallStubCompiler::GenerateMissBranch() { 1532 void CallStubCompiler::GenerateMissBranch() {
1579 Handle<Code> code = 1533 Handle<Code> code =
1580 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), 1534 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(),
1581 kind_, 1535 kind_,
1582 extra_state_); 1536 extra_state_);
1583 __ Jump(code, RelocInfo::CODE_TARGET); 1537 __ Jump(code, RelocInfo::CODE_TARGET);
1584 } 1538 }
1585 1539
1586 1540
1587 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, 1541 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
1588 Handle<JSObject> holder, 1542 Handle<JSObject> holder,
1589 PropertyIndex index, 1543 PropertyIndex index,
1590 Handle<Name> name) { 1544 Handle<Name> name) {
1591 // ----------- S t a t e -------------
1592 // -- a2 : name
1593 // -- ra : return address
1594 // -----------------------------------
1595 Label miss; 1545 Label miss;
1596 1546
1597 GenerateNameCheck(name, &miss); 1547 Register reg = HandlerFrontendHeader(
1598 1548 object, holder, name, RECEIVER_MAP_CHECK, &miss);
1599 const int argc = arguments().immediate();
1600
1601 // Get the receiver of the function from the stack into a0.
1602 __ lw(a0, MemOperand(sp, argc * kPointerSize));
1603 // Check that the receiver isn't a smi.
1604 __ JumpIfSmi(a0, &miss, t0);
1605
1606 // Do the right check and compute the holder register.
1607 Register reg = CheckPrototypes(
1608 IC::CurrentTypeOf(object, isolate()),
1609 a0, holder, a1, a3, t0, name, &miss);
1610 GenerateFastPropertyLoad(masm(), a1, reg, index.is_inobject(holder), 1549 GenerateFastPropertyLoad(masm(), a1, reg, index.is_inobject(holder),
1611 index.translate(holder), Representation::Tagged()); 1550 index.translate(holder), Representation::Tagged());
1551 GenerateJumpFunction(object, a1, &miss);
1612 1552
1613 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); 1553 HandlerFrontendFooter(&miss);
1614
1615 // Handle call cache miss.
1616 __ bind(&miss);
1617 GenerateMissBranch();
1618 1554
1619 // Return the generated code. 1555 // Return the generated code.
1620 return GetCode(Code::FAST, name); 1556 return GetCode(Code::FAST, name);
1621 } 1557 }
1622 1558
1623 1559
1624 Handle<Code> CallStubCompiler::CompileArrayCodeCall( 1560 Handle<Code> CallStubCompiler::CompileArrayCodeCall(
1625 Handle<Object> object, 1561 Handle<Object> object,
1626 Handle<JSObject> holder, 1562 Handle<JSObject> holder,
1627 Handle<Cell> cell, 1563 Handle<Cell> cell,
1628 Handle<JSFunction> function, 1564 Handle<JSFunction> function,
1629 Handle<String> name, 1565 Handle<String> name,
1630 Code::StubType type) { 1566 Code::StubType type) {
1631 Label miss; 1567 Label miss;
1632 1568
1633 // Check that function is still array. 1569 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1634 const int argc = arguments().immediate(); 1570 if (!cell.is_null()) {
1635 GenerateNameCheck(name, &miss);
1636 Register receiver = a1;
1637
1638 if (cell.is_null()) {
1639 __ lw(receiver, MemOperand(sp, argc * kPointerSize));
1640
1641 // Check that the receiver isn't a smi.
1642 __ JumpIfSmi(receiver, &miss);
1643
1644 // Check that the maps haven't changed.
1645 CheckPrototypes(
1646 IC::CurrentTypeOf(object, isolate()), receiver, holder,
1647 a3, a0, t0, name, &miss);
1648 } else {
1649 ASSERT(cell->value() == *function); 1571 ASSERT(cell->value() == *function);
1650 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
1651 &miss);
1652 GenerateLoadFunctionFromCell(cell, function, &miss); 1572 GenerateLoadFunctionFromCell(cell, function, &miss);
1653 } 1573 }
1654 1574
1655 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); 1575 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite();
1656 site->SetElementsKind(GetInitialFastElementsKind()); 1576 site->SetElementsKind(GetInitialFastElementsKind());
1657 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); 1577 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site);
1578 const int argc = arguments().immediate();
1658 __ li(a0, Operand(argc)); 1579 __ li(a0, Operand(argc));
1659 __ li(a2, Operand(site_feedback_cell)); 1580 __ li(a2, Operand(site_feedback_cell));
1660 __ li(a1, Operand(function)); 1581 __ li(a1, Operand(function));
1661 1582
1662 ArrayConstructorStub stub(isolate()); 1583 ArrayConstructorStub stub(isolate());
1663 __ TailCallStub(&stub); 1584 __ TailCallStub(&stub);
1664 1585
1665 __ bind(&miss); 1586 HandlerFrontendFooter(&miss);
1666 GenerateMissBranch();
1667 1587
1668 // Return the generated code. 1588 // Return the generated code.
1669 return GetCode(type, name); 1589 return GetCode(type, name);
1670 } 1590 }
1671 1591
1672 1592
1673 Handle<Code> CallStubCompiler::CompileArrayPushCall( 1593 Handle<Code> CallStubCompiler::CompileArrayPushCall(
1674 Handle<Object> object, 1594 Handle<Object> object,
1675 Handle<JSObject> holder, 1595 Handle<JSObject> holder,
1676 Handle<Cell> cell, 1596 Handle<Cell> cell,
1677 Handle<JSFunction> function, 1597 Handle<JSFunction> function,
1678 Handle<String> name, 1598 Handle<String> name,
1679 Code::StubType type) { 1599 Code::StubType type) {
1680 // ----------- S t a t e -------------
1681 // -- a2 : name
1682 // -- ra : return address
1683 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
1684 // -- ...
1685 // -- sp[argc * 4] : receiver
1686 // -----------------------------------
1687
1688 // If object is not an array or is observed, bail out to regular call. 1600 // If object is not an array or is observed, bail out to regular call.
1689 if (!object->IsJSArray() || 1601 if (!object->IsJSArray() ||
1690 !cell.is_null() || 1602 !cell.is_null() ||
1691 Handle<JSArray>::cast(object)->map()->is_observed()) { 1603 Handle<JSArray>::cast(object)->map()->is_observed()) {
1692 return Handle<Code>::null(); 1604 return Handle<Code>::null();
1693 } 1605 }
1694 1606
1695 Label miss; 1607 Label miss;
1608 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1609 Register receiver = a0;
1610 Register scratch = a1;
1696 1611
1697 GenerateNameCheck(name, &miss);
1698
1699 Register receiver = a1;
1700
1701 // Get the receiver from the stack.
1702 const int argc = arguments().immediate(); 1612 const int argc = arguments().immediate();
1703 __ lw(receiver, MemOperand(sp, argc * kPointerSize));
1704
1705 // Check that the receiver isn't a smi.
1706 __ JumpIfSmi(receiver, &miss);
1707
1708 // Check that the maps haven't changed.
1709 CheckPrototypes(
1710 IC::CurrentTypeOf(object, isolate()), receiver, holder,
1711 a3, v0, t0, name, &miss);
1712 1613
1713 if (argc == 0) { 1614 if (argc == 0) {
1714 // Nothing to do, just return the length. 1615 // Nothing to do, just return the length.
1715 __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1616 __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset));
1716 __ DropAndRet(argc + 1); 1617 __ DropAndRet(argc + 1);
1717 } else { 1618 } else {
1718 Label call_builtin; 1619 Label call_builtin;
1719 if (argc == 1) { // Otherwise fall through to call the builtin. 1620 if (argc == 1) { // Otherwise fall through to call the builtin.
1720 Label attempt_to_grow_elements, with_write_barrier, check_double; 1621 Label attempt_to_grow_elements, with_write_barrier, check_double;
1721 1622
1722 Register elements = t2; 1623 Register elements = t2;
1723 Register end_elements = t1; 1624 Register end_elements = t1;
1724 // Get the elements array of the object. 1625 // Get the elements array of the object.
1725 __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); 1626 __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset));
1726 1627
1727 // Check that the elements are in fast mode and writable. 1628 // Check that the elements are in fast mode and writable.
1728 __ CheckMap(elements, 1629 __ CheckMap(elements,
1729 v0, 1630 scratch,
1730 Heap::kFixedArrayMapRootIndex, 1631 Heap::kFixedArrayMapRootIndex,
1731 &check_double, 1632 &check_double,
1732 DONT_DO_SMI_CHECK); 1633 DONT_DO_SMI_CHECK);
1733 1634
1734 // Get the array's length into v0 and calculate new length. 1635 // Get the array's length into scratch and calculate new length.
1735 __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1636 __ lw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1736 STATIC_ASSERT(kSmiTagSize == 1); 1637 STATIC_ASSERT(kSmiTagSize == 1);
1737 STATIC_ASSERT(kSmiTag == 0); 1638 STATIC_ASSERT(kSmiTag == 0);
1738 __ Addu(v0, v0, Operand(Smi::FromInt(argc))); 1639 __ Addu(scratch, scratch, Operand(Smi::FromInt(argc)));
1739 1640
1740 // Get the elements' length. 1641 // Get the elements' length.
1741 __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1642 __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
1742 1643
1743 // Check if we could survive without allocation. 1644 // Check if we could survive without allocation.
1744 __ Branch(&attempt_to_grow_elements, gt, v0, Operand(t0)); 1645 __ Branch(&attempt_to_grow_elements, gt, scratch, Operand(t0));
1745 1646
1746 // Check if value is a smi. 1647 // Check if value is a smi.
1747 __ lw(t0, MemOperand(sp, (argc - 1) * kPointerSize)); 1648 __ lw(t0, MemOperand(sp, (argc - 1) * kPointerSize));
1748 __ JumpIfNotSmi(t0, &with_write_barrier); 1649 __ JumpIfNotSmi(t0, &with_write_barrier);
1749 1650
1750 // Save new length. 1651 // Save new length.
1751 __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1652 __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1752 1653
1753 // Store the value. 1654 // Store the value.
1754 // We may need a register containing the address end_elements below, 1655 // We may need a register containing the address end_elements below,
1755 // so write back the value in end_elements. 1656 // so write back the value in end_elements.
1756 __ sll(end_elements, v0, kPointerSizeLog2 - kSmiTagSize); 1657 __ sll(end_elements, scratch, kPointerSizeLog2 - kSmiTagSize);
1757 __ Addu(end_elements, elements, end_elements); 1658 __ Addu(end_elements, elements, end_elements);
1758 const int kEndElementsOffset = 1659 const int kEndElementsOffset =
1759 FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize; 1660 FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize;
1760 __ Addu(end_elements, end_elements, kEndElementsOffset); 1661 __ Addu(end_elements, end_elements, kEndElementsOffset);
1761 __ sw(t0, MemOperand(end_elements)); 1662 __ sw(t0, MemOperand(end_elements));
1762 1663
1763 // Check for a smi. 1664 // Check for a smi.
1665 __ mov(v0, scratch);
1764 __ DropAndRet(argc + 1); 1666 __ DropAndRet(argc + 1);
1765 1667
1766 __ bind(&check_double); 1668 __ bind(&check_double);
1767 1669
1768 // Check that the elements are in fast mode and writable. 1670 // Check that the elements are in fast mode and writable.
1769 __ CheckMap(elements, 1671 __ CheckMap(elements,
1770 a0, 1672 scratch,
1771 Heap::kFixedDoubleArrayMapRootIndex, 1673 Heap::kFixedDoubleArrayMapRootIndex,
1772 &call_builtin, 1674 &call_builtin,
1773 DONT_DO_SMI_CHECK); 1675 DONT_DO_SMI_CHECK);
1774 1676
1775 // Get the array's length into v0 and calculate new length. 1677 // Get the array's length into scratch and calculate new length.
1776 __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1678 __ lw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1777 STATIC_ASSERT(kSmiTagSize == 1); 1679 STATIC_ASSERT(kSmiTagSize == 1);
1778 STATIC_ASSERT(kSmiTag == 0); 1680 STATIC_ASSERT(kSmiTag == 0);
1779 __ Addu(v0, v0, Operand(Smi::FromInt(argc))); 1681 __ Addu(scratch, scratch, Operand(Smi::FromInt(argc)));
1780 1682
1781 // Get the elements' length. 1683 // Get the elements' length.
1782 __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1684 __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
1783 1685
1784 // Check if we could survive without allocation. 1686 // Check if we could survive without allocation.
1785 __ Branch(&call_builtin, gt, v0, Operand(t0)); 1687 __ Branch(&call_builtin, gt, scratch, Operand(t0));
1786 1688
1787 __ lw(t0, MemOperand(sp, (argc - 1) * kPointerSize)); 1689 __ lw(t0, MemOperand(sp, (argc - 1) * kPointerSize));
1788 __ StoreNumberToDoubleElements( 1690 __ StoreNumberToDoubleElements(
1789 t0, v0, elements, a3, t1, a2, 1691 t0, scratch, elements, a3, t1, a2,
1790 &call_builtin, argc * kDoubleSize); 1692 &call_builtin, argc * kDoubleSize);
1791 1693
1792 // Save new length. 1694 // Save new length.
1793 __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1695 __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1794 1696
1795 // Check for a smi. 1697 __ mov(v0, scratch);
1796 __ DropAndRet(argc + 1); 1698 __ DropAndRet(argc + 1);
1797 1699
1798 __ bind(&with_write_barrier); 1700 __ bind(&with_write_barrier);
1799 1701
1800 __ lw(a3, FieldMemOperand(receiver, HeapObject::kMapOffset)); 1702 __ lw(a3, FieldMemOperand(receiver, HeapObject::kMapOffset));
1801 1703
1802 if (FLAG_smi_only_arrays && !FLAG_trace_elements_transitions) { 1704 if (FLAG_smi_only_arrays && !FLAG_trace_elements_transitions) {
1803 Label fast_object, not_fast_object; 1705 Label fast_object, not_fast_object;
1804 __ CheckFastObjectElements(a3, t3, &not_fast_object); 1706 __ CheckFastObjectElements(a3, t3, &not_fast_object);
1805 __ jmp(&fast_object); 1707 __ jmp(&fast_object);
(...skipping 29 matching lines...) Expand all
1835 ElementsTransitionGenerator:: 1737 ElementsTransitionGenerator::
1836 GenerateMapChangeElementsTransition(masm(), 1738 GenerateMapChangeElementsTransition(masm(),
1837 DONT_TRACK_ALLOCATION_SITE, 1739 DONT_TRACK_ALLOCATION_SITE,
1838 NULL); 1740 NULL);
1839 __ bind(&fast_object); 1741 __ bind(&fast_object);
1840 } else { 1742 } else {
1841 __ CheckFastObjectElements(a3, a3, &call_builtin); 1743 __ CheckFastObjectElements(a3, a3, &call_builtin);
1842 } 1744 }
1843 1745
1844 // Save new length. 1746 // Save new length.
1845 __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1747 __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1846 1748
1847 // Store the value. 1749 // Store the value.
1848 // We may need a register containing the address end_elements below, 1750 // We may need a register containing the address end_elements below,
1849 // so write back the value in end_elements. 1751 // so write back the value in end_elements.
1850 __ sll(end_elements, v0, kPointerSizeLog2 - kSmiTagSize); 1752 __ sll(end_elements, scratch, kPointerSizeLog2 - kSmiTagSize);
1851 __ Addu(end_elements, elements, end_elements); 1753 __ Addu(end_elements, elements, end_elements);
1852 __ Addu(end_elements, end_elements, kEndElementsOffset); 1754 __ Addu(end_elements, end_elements, kEndElementsOffset);
1853 __ sw(t0, MemOperand(end_elements)); 1755 __ sw(t0, MemOperand(end_elements));
1854 1756
1855 __ RecordWrite(elements, 1757 __ RecordWrite(elements,
1856 end_elements, 1758 end_elements,
1857 t0, 1759 t0,
1858 kRAHasNotBeenSaved, 1760 kRAHasNotBeenSaved,
1859 kDontSaveFPRegs, 1761 kDontSaveFPRegs,
1860 EMIT_REMEMBERED_SET, 1762 EMIT_REMEMBERED_SET,
1861 OMIT_SMI_CHECK); 1763 OMIT_SMI_CHECK);
1764 __ mov(v0, scratch);
1862 __ DropAndRet(argc + 1); 1765 __ DropAndRet(argc + 1);
1863 1766
1864 __ bind(&attempt_to_grow_elements); 1767 __ bind(&attempt_to_grow_elements);
1865 // v0: array's length + 1. 1768 // scratch: array's length + 1.
1866 // t0: elements' length. 1769 // t0: elements' length.
1867 1770
1868 if (!FLAG_inline_new) { 1771 if (!FLAG_inline_new) {
1869 __ Branch(&call_builtin); 1772 __ Branch(&call_builtin);
1870 } 1773 }
1871 1774
1872 __ lw(a2, MemOperand(sp, (argc - 1) * kPointerSize)); 1775 __ lw(a2, MemOperand(sp, (argc - 1) * kPointerSize));
1873 // Growing elements that are SMI-only requires special handling in case 1776 // Growing elements that are SMI-only requires special handling in case
1874 // the new element is non-Smi. For now, delegate to the builtin. 1777 // the new element is non-Smi. For now, delegate to the builtin.
1875 Label no_fast_elements_check; 1778 Label no_fast_elements_check;
1876 __ JumpIfSmi(a2, &no_fast_elements_check); 1779 __ JumpIfSmi(a2, &no_fast_elements_check);
1877 __ lw(t3, FieldMemOperand(receiver, HeapObject::kMapOffset)); 1780 __ lw(t3, FieldMemOperand(receiver, HeapObject::kMapOffset));
1878 __ CheckFastObjectElements(t3, t3, &call_builtin); 1781 __ CheckFastObjectElements(t3, t3, &call_builtin);
1879 __ bind(&no_fast_elements_check); 1782 __ bind(&no_fast_elements_check);
1880 1783
1881 ExternalReference new_space_allocation_top = 1784 ExternalReference new_space_allocation_top =
1882 ExternalReference::new_space_allocation_top_address(isolate()); 1785 ExternalReference::new_space_allocation_top_address(isolate());
1883 ExternalReference new_space_allocation_limit = 1786 ExternalReference new_space_allocation_limit =
1884 ExternalReference::new_space_allocation_limit_address(isolate()); 1787 ExternalReference::new_space_allocation_limit_address(isolate());
1885 1788
1886 const int kAllocationDelta = 4; 1789 const int kAllocationDelta = 4;
1887 // Load top and check if it is the end of elements. 1790 // Load top and check if it is the end of elements.
1888 __ sll(end_elements, v0, kPointerSizeLog2 - kSmiTagSize); 1791 __ sll(end_elements, scratch, kPointerSizeLog2 - kSmiTagSize);
1889 __ Addu(end_elements, elements, end_elements); 1792 __ Addu(end_elements, elements, end_elements);
1890 __ Addu(end_elements, end_elements, Operand(kEndElementsOffset)); 1793 __ Addu(end_elements, end_elements, Operand(kEndElementsOffset));
1891 __ li(t3, Operand(new_space_allocation_top)); 1794 __ li(t3, Operand(new_space_allocation_top));
1892 __ lw(a3, MemOperand(t3)); 1795 __ lw(a3, MemOperand(t3));
1893 __ Branch(&call_builtin, ne, end_elements, Operand(a3)); 1796 __ Branch(&call_builtin, ne, end_elements, Operand(a3));
1894 1797
1895 __ li(t5, Operand(new_space_allocation_limit)); 1798 __ li(t5, Operand(new_space_allocation_limit));
1896 __ lw(t5, MemOperand(t5)); 1799 __ lw(t5, MemOperand(t5));
1897 __ Addu(a3, a3, Operand(kAllocationDelta * kPointerSize)); 1800 __ Addu(a3, a3, Operand(kAllocationDelta * kPointerSize));
1898 __ Branch(&call_builtin, hi, a3, Operand(t5)); 1801 __ Branch(&call_builtin, hi, a3, Operand(t5));
1899 1802
1900 // We fit and could grow elements. 1803 // We fit and could grow elements.
1901 // Update new_space_allocation_top. 1804 // Update new_space_allocation_top.
1902 __ sw(a3, MemOperand(t3)); 1805 __ sw(a3, MemOperand(t3));
1903 // Push the argument. 1806 // Push the argument.
1904 __ sw(a2, MemOperand(end_elements)); 1807 __ sw(a2, MemOperand(end_elements));
1905 // Fill the rest with holes. 1808 // Fill the rest with holes.
1906 __ LoadRoot(a3, Heap::kTheHoleValueRootIndex); 1809 __ LoadRoot(a3, Heap::kTheHoleValueRootIndex);
1907 for (int i = 1; i < kAllocationDelta; i++) { 1810 for (int i = 1; i < kAllocationDelta; i++) {
1908 __ sw(a3, MemOperand(end_elements, i * kPointerSize)); 1811 __ sw(a3, MemOperand(end_elements, i * kPointerSize));
1909 } 1812 }
1910 1813
1911 // Update elements' and array's sizes. 1814 // Update elements' and array's sizes.
1912 __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1815 __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
1913 __ Addu(t0, t0, Operand(Smi::FromInt(kAllocationDelta))); 1816 __ Addu(t0, t0, Operand(Smi::FromInt(kAllocationDelta)));
1914 __ sw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1817 __ sw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
1915 1818
1916 // Elements are in new space, so write barrier is not required. 1819 // Elements are in new space, so write barrier is not required.
1820 __ mov(v0, scratch);
1917 __ DropAndRet(argc + 1); 1821 __ DropAndRet(argc + 1);
1918 } 1822 }
1919 __ bind(&call_builtin); 1823 __ bind(&call_builtin);
1920 __ TailCallExternalReference( 1824 __ TailCallExternalReference(
1921 ExternalReference(Builtins::c_ArrayPush, isolate()), argc + 1, 1); 1825 ExternalReference(Builtins::c_ArrayPush, isolate()), argc + 1, 1);
1922 } 1826 }
1923 1827
1924 // Handle call cache miss. 1828 HandlerFrontendFooter(&miss);
1925 __ bind(&miss);
1926 GenerateMissBranch();
1927 1829
1928 // Return the generated code. 1830 // Return the generated code.
1929 return GetCode(type, name); 1831 return GetCode(type, name);
1930 } 1832 }
1931 1833
1932 1834
1933 Handle<Code> CallStubCompiler::CompileArrayPopCall( 1835 Handle<Code> CallStubCompiler::CompileArrayPopCall(
1934 Handle<Object> object, 1836 Handle<Object> object,
1935 Handle<JSObject> holder, 1837 Handle<JSObject> holder,
1936 Handle<Cell> cell, 1838 Handle<Cell> cell,
1937 Handle<JSFunction> function, 1839 Handle<JSFunction> function,
1938 Handle<String> name, 1840 Handle<String> name,
1939 Code::StubType type) { 1841 Code::StubType type) {
1940 // ----------- S t a t e -------------
1941 // -- a2 : name
1942 // -- ra : return address
1943 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
1944 // -- ...
1945 // -- sp[argc * 4] : receiver
1946 // -----------------------------------
1947
1948 // If object is not an array or is observed, bail out to regular call. 1842 // If object is not an array or is observed, bail out to regular call.
1949 if (!object->IsJSArray() || 1843 if (!object->IsJSArray() ||
1950 !cell.is_null() || 1844 !cell.is_null() ||
1951 Handle<JSArray>::cast(object)->map()->is_observed()) { 1845 Handle<JSArray>::cast(object)->map()->is_observed()) {
1952 return Handle<Code>::null(); 1846 return Handle<Code>::null();
1953 } 1847 }
1954 1848
1955 Label miss, return_undefined, call_builtin; 1849 Label miss, return_undefined, call_builtin;
1956 Register receiver = a1; 1850 Register receiver = a0;
1851 Register scratch = a1;
1957 Register elements = a3; 1852 Register elements = a3;
1958 GenerateNameCheck(name, &miss); 1853 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1959
1960 // Get the receiver from the stack.
1961 const int argc = arguments().immediate();
1962 __ lw(receiver, MemOperand(sp, argc * kPointerSize));
1963 // Check that the receiver isn't a smi.
1964 __ JumpIfSmi(receiver, &miss);
1965
1966 // Check that the maps haven't changed.
1967 CheckPrototypes(
1968 IC::CurrentTypeOf(object, isolate()), receiver, holder,
1969 elements, t0, v0, name, &miss);
1970 1854
1971 // Get the elements array of the object. 1855 // Get the elements array of the object.
1972 __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); 1856 __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset));
1973 1857
1974 // Check that the elements are in fast mode and writable. 1858 // Check that the elements are in fast mode and writable.
1975 __ CheckMap(elements, 1859 __ CheckMap(elements,
1976 v0, 1860 scratch,
1977 Heap::kFixedArrayMapRootIndex, 1861 Heap::kFixedArrayMapRootIndex,
1978 &call_builtin, 1862 &call_builtin,
1979 DONT_DO_SMI_CHECK); 1863 DONT_DO_SMI_CHECK);
1980 1864
1981 // Get the array's length into t0 and calculate new length. 1865 // Get the array's length into t0 and calculate new length.
1982 __ lw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1866 __ lw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset));
1983 __ Subu(t0, t0, Operand(Smi::FromInt(1))); 1867 __ Subu(t0, t0, Operand(Smi::FromInt(1)));
1984 __ Branch(&return_undefined, lt, t0, Operand(zero_reg)); 1868 __ Branch(&return_undefined, lt, t0, Operand(zero_reg));
1985 1869
1986 // Get the last element. 1870 // Get the last element.
1987 __ LoadRoot(t2, Heap::kTheHoleValueRootIndex); 1871 __ LoadRoot(t2, Heap::kTheHoleValueRootIndex);
1988 STATIC_ASSERT(kSmiTagSize == 1); 1872 STATIC_ASSERT(kSmiTagSize == 1);
1989 STATIC_ASSERT(kSmiTag == 0); 1873 STATIC_ASSERT(kSmiTag == 0);
1990 // We can't address the last element in one operation. Compute the more 1874 // We can't address the last element in one operation. Compute the more
1991 // expensive shift first, and use an offset later on. 1875 // expensive shift first, and use an offset later on.
1992 __ sll(t1, t0, kPointerSizeLog2 - kSmiTagSize); 1876 __ sll(t1, t0, kPointerSizeLog2 - kSmiTagSize);
1993 __ Addu(elements, elements, t1); 1877 __ Addu(elements, elements, t1);
1994 __ lw(v0, FieldMemOperand(elements, FixedArray::kHeaderSize)); 1878 __ lw(scratch, FieldMemOperand(elements, FixedArray::kHeaderSize));
1995 __ Branch(&call_builtin, eq, v0, Operand(t2)); 1879 __ Branch(&call_builtin, eq, scratch, Operand(t2));
1996 1880
1997 // Set the array's length. 1881 // Set the array's length.
1998 __ sw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1882 __ sw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset));
1999 1883
2000 // Fill with the hole. 1884 // Fill with the hole.
2001 __ sw(t2, FieldMemOperand(elements, FixedArray::kHeaderSize)); 1885 __ sw(t2, FieldMemOperand(elements, FixedArray::kHeaderSize));
1886 const int argc = arguments().immediate();
1887 __ mov(v0, scratch);
2002 __ DropAndRet(argc + 1); 1888 __ DropAndRet(argc + 1);
2003 1889
2004 __ bind(&return_undefined); 1890 __ bind(&return_undefined);
2005 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); 1891 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
2006 __ DropAndRet(argc + 1); 1892 __ DropAndRet(argc + 1);
2007 1893
2008 __ bind(&call_builtin); 1894 __ bind(&call_builtin);
2009 __ TailCallExternalReference( 1895 __ TailCallExternalReference(
2010 ExternalReference(Builtins::c_ArrayPop, isolate()), argc + 1, 1); 1896 ExternalReference(Builtins::c_ArrayPop, isolate()), argc + 1, 1);
2011 1897
2012 // Handle call cache miss. 1898 HandlerFrontendFooter(&miss);
2013 __ bind(&miss);
2014 GenerateMissBranch();
2015 1899
2016 // Return the generated code. 1900 // Return the generated code.
2017 return GetCode(type, name); 1901 return GetCode(type, name);
2018 } 1902 }
2019 1903
2020 1904
2021 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall( 1905 Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
2022 Handle<Object> object, 1906 Handle<Object> object,
2023 Handle<JSObject> holder, 1907 Handle<JSObject> holder,
2024 Handle<Cell> cell, 1908 Handle<Cell> cell,
2025 Handle<JSFunction> function, 1909 Handle<JSFunction> function,
2026 Handle<String> name, 1910 Handle<String> name,
2027 Code::StubType type) { 1911 Code::StubType type) {
2028 // ----------- S t a t e -------------
2029 // -- a2 : function name
2030 // -- ra : return address
2031 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2032 // -- ...
2033 // -- sp[argc * 4] : receiver
2034 // -----------------------------------
2035
2036 // If object is not a string, bail out to regular call. 1912 // If object is not a string, bail out to regular call.
2037 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); 1913 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
2038 1914
2039 const int argc = arguments().immediate();
2040 Label miss; 1915 Label miss;
2041 Label name_miss; 1916 Label name_miss;
2042 Label index_out_of_range; 1917 Label index_out_of_range;
2043 1918
2044 Label* index_out_of_range_label = &index_out_of_range; 1919 Label* index_out_of_range_label = &index_out_of_range;
2045 1920
2046 if (kind_ == Code::CALL_IC && 1921 if (kind_ == Code::CALL_IC &&
2047 (CallICBase::StringStubState::decode(extra_state_) == 1922 (CallICBase::StringStubState::decode(extra_state_) ==
2048 DEFAULT_STRING_STUB)) { 1923 DEFAULT_STRING_STUB)) {
2049 index_out_of_range_label = &miss; 1924 index_out_of_range_label = &miss;
2050 } 1925 }
2051 1926
2052 GenerateNameCheck(name, &name_miss); 1927 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
2053 1928
2054 // Check that the maps starting from the prototype haven't changed. 1929 Register receiver = a0;
2055 GenerateDirectLoadGlobalFunctionPrototype(masm(),
2056 Context::STRING_FUNCTION_INDEX,
2057 v0,
2058 &miss);
2059 ASSERT(!object.is_identical_to(holder));
2060 Handle<JSObject> prototype(JSObject::cast(object->GetPrototype(isolate())));
2061 CheckPrototypes(
2062 IC::CurrentTypeOf(prototype, isolate()),
2063 v0, holder, a1, a3, t0, name, &miss);
2064
2065 Register receiver = a1;
2066 Register index = t1; 1930 Register index = t1;
2067 Register result = v0; 1931 Register result = a1;
1932 const int argc = arguments().immediate();
2068 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); 1933 __ lw(receiver, MemOperand(sp, argc * kPointerSize));
2069 if (argc > 0) { 1934 if (argc > 0) {
2070 __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize)); 1935 __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize));
2071 } else { 1936 } else {
2072 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); 1937 __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
2073 } 1938 }
2074 1939
2075 StringCharCodeAtGenerator generator(receiver, 1940 StringCharCodeAtGenerator generator(receiver,
2076 index, 1941 index,
2077 result, 1942 result,
2078 &miss, // When not a string. 1943 &miss, // When not a string.
2079 &miss, // When not a number. 1944 &miss, // When not a number.
2080 index_out_of_range_label, 1945 index_out_of_range_label,
2081 STRING_INDEX_IS_NUMBER); 1946 STRING_INDEX_IS_NUMBER);
2082 generator.GenerateFast(masm()); 1947 generator.GenerateFast(masm());
1948 __ mov(v0, result);
2083 __ DropAndRet(argc + 1); 1949 __ DropAndRet(argc + 1);
2084 1950
2085 StubRuntimeCallHelper call_helper; 1951 StubRuntimeCallHelper call_helper;
2086 generator.GenerateSlow(masm(), call_helper); 1952 generator.GenerateSlow(masm(), call_helper);
2087 1953
2088 if (index_out_of_range.is_linked()) { 1954 if (index_out_of_range.is_linked()) {
2089 __ bind(&index_out_of_range); 1955 __ bind(&index_out_of_range);
2090 __ LoadRoot(v0, Heap::kNanValueRootIndex); 1956 __ LoadRoot(v0, Heap::kNanValueRootIndex);
2091 __ DropAndRet(argc + 1); 1957 __ DropAndRet(argc + 1);
2092 } 1958 }
2093 1959
2094 __ bind(&miss); 1960 __ bind(&miss);
2095 // Restore function name in a2. 1961 // Restore function name in a2.
2096 __ li(a2, name); 1962 __ li(a2, name);
2097 __ bind(&name_miss); 1963 HandlerFrontendFooter(&name_miss);
2098 GenerateMissBranch();
2099 1964
2100 // Return the generated code. 1965 // Return the generated code.
2101 return GetCode(type, name); 1966 return GetCode(type, name);
2102 } 1967 }
2103 1968
2104 1969
2105 Handle<Code> CallStubCompiler::CompileStringCharAtCall( 1970 Handle<Code> CallStubCompiler::CompileStringCharAtCall(
2106 Handle<Object> object, 1971 Handle<Object> object,
2107 Handle<JSObject> holder, 1972 Handle<JSObject> holder,
2108 Handle<Cell> cell, 1973 Handle<Cell> cell,
2109 Handle<JSFunction> function, 1974 Handle<JSFunction> function,
2110 Handle<String> name, 1975 Handle<String> name,
2111 Code::StubType type) { 1976 Code::StubType type) {
2112 // ----------- S t a t e -------------
2113 // -- a2 : function name
2114 // -- ra : return address
2115 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2116 // -- ...
2117 // -- sp[argc * 4] : receiver
2118 // -----------------------------------
2119
2120 // If object is not a string, bail out to regular call. 1977 // If object is not a string, bail out to regular call.
2121 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); 1978 if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
2122 1979
2123 const int argc = arguments().immediate(); 1980 const int argc = arguments().immediate();
2124 Label miss; 1981 Label miss;
2125 Label name_miss; 1982 Label name_miss;
2126 Label index_out_of_range; 1983 Label index_out_of_range;
2127 Label* index_out_of_range_label = &index_out_of_range; 1984 Label* index_out_of_range_label = &index_out_of_range;
2128 if (kind_ == Code::CALL_IC && 1985 if (kind_ == Code::CALL_IC &&
2129 (CallICBase::StringStubState::decode(extra_state_) == 1986 (CallICBase::StringStubState::decode(extra_state_) ==
2130 DEFAULT_STRING_STUB)) { 1987 DEFAULT_STRING_STUB)) {
2131 index_out_of_range_label = &miss; 1988 index_out_of_range_label = &miss;
2132 } 1989 }
2133 GenerateNameCheck(name, &name_miss);
2134 1990
2135 // Check that the maps starting from the prototype haven't changed. 1991 HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss);
2136 GenerateDirectLoadGlobalFunctionPrototype(masm(),
2137 Context::STRING_FUNCTION_INDEX,
2138 v0,
2139 &miss);
2140 ASSERT(!object.is_identical_to(holder));
2141 Handle<JSObject> prototype(JSObject::cast(object->GetPrototype(isolate())));
2142 CheckPrototypes(
2143 IC::CurrentTypeOf(prototype, isolate()),
2144 v0, holder, a1, a3, t0, name, &miss);
2145 1992
2146 Register receiver = v0; 1993 Register receiver = a0;
2147 Register index = t1; 1994 Register index = t1;
2148 Register scratch = a3; 1995 Register scratch = a3;
2149 Register result = v0; 1996 Register result = a1;
2150 __ lw(receiver, MemOperand(sp, argc * kPointerSize));
2151 if (argc > 0) { 1997 if (argc > 0) {
2152 __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize)); 1998 __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize));
2153 } else { 1999 } else {
2154 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); 2000 __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
2155 } 2001 }
2156 2002
2157 StringCharAtGenerator generator(receiver, 2003 StringCharAtGenerator generator(receiver,
2158 index, 2004 index,
2159 scratch, 2005 scratch,
2160 result, 2006 result,
2161 &miss, // When not a string. 2007 &miss, // When not a string.
2162 &miss, // When not a number. 2008 &miss, // When not a number.
2163 index_out_of_range_label, 2009 index_out_of_range_label,
2164 STRING_INDEX_IS_NUMBER); 2010 STRING_INDEX_IS_NUMBER);
2165 generator.GenerateFast(masm()); 2011 generator.GenerateFast(masm());
2012 __ mov(v0, result);
2166 __ DropAndRet(argc + 1); 2013 __ DropAndRet(argc + 1);
2167 2014
2168 StubRuntimeCallHelper call_helper; 2015 StubRuntimeCallHelper call_helper;
2169 generator.GenerateSlow(masm(), call_helper); 2016 generator.GenerateSlow(masm(), call_helper);
2170 2017
2171 if (index_out_of_range.is_linked()) { 2018 if (index_out_of_range.is_linked()) {
2172 __ bind(&index_out_of_range); 2019 __ bind(&index_out_of_range);
2173 __ LoadRoot(v0, Heap::kempty_stringRootIndex); 2020 __ LoadRoot(v0, Heap::kempty_stringRootIndex);
2174 __ DropAndRet(argc + 1); 2021 __ DropAndRet(argc + 1);
2175 } 2022 }
2176 2023
2177 __ bind(&miss); 2024 __ bind(&miss);
2178 // Restore function name in a2. 2025 // Restore function name in a2.
2179 __ li(a2, name); 2026 __ li(a2, name);
2180 __ bind(&name_miss); 2027 HandlerFrontendFooter(&name_miss);
2181 GenerateMissBranch();
2182 2028
2183 // Return the generated code. 2029 // Return the generated code.
2184 return GetCode(type, name); 2030 return GetCode(type, name);
2185 } 2031 }
2186 2032
2187 2033
2188 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( 2034 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
2189 Handle<Object> object, 2035 Handle<Object> object,
2190 Handle<JSObject> holder, 2036 Handle<JSObject> holder,
2191 Handle<Cell> cell, 2037 Handle<Cell> cell,
2192 Handle<JSFunction> function, 2038 Handle<JSFunction> function,
2193 Handle<String> name, 2039 Handle<String> name,
2194 Code::StubType type) { 2040 Code::StubType type) {
2195 // ----------- S t a t e -------------
2196 // -- a2 : function name
2197 // -- ra : return address
2198 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2199 // -- ...
2200 // -- sp[argc * 4] : receiver
2201 // -----------------------------------
2202
2203 const int argc = arguments().immediate(); 2041 const int argc = arguments().immediate();
2204 2042
2205 // If the object is not a JSObject or we got an unexpected number of 2043 // If the object is not a JSObject or we got an unexpected number of
2206 // arguments, bail out to the regular call. 2044 // arguments, bail out to the regular call.
2207 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2045 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2208 2046
2209 Label miss; 2047 Label miss;
2210 GenerateNameCheck(name, &miss); 2048 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2211 2049 if (!cell.is_null()) {
2212 if (cell.is_null()) {
2213 __ lw(a1, MemOperand(sp, 1 * kPointerSize));
2214
2215 STATIC_ASSERT(kSmiTag == 0);
2216 __ JumpIfSmi(a1, &miss);
2217
2218 CheckPrototypes(
2219 IC::CurrentTypeOf(object, isolate()),
2220 a1, holder, v0, a3, t0, name, &miss);
2221 } else {
2222 ASSERT(cell->value() == *function); 2050 ASSERT(cell->value() == *function);
2223 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2224 &miss);
2225 GenerateLoadFunctionFromCell(cell, function, &miss); 2051 GenerateLoadFunctionFromCell(cell, function, &miss);
2226 } 2052 }
2227 2053
2228 // Load the char code argument. 2054 // Load the char code argument.
2229 Register code = a1; 2055 Register code = a1;
2230 __ lw(code, MemOperand(sp, 0 * kPointerSize)); 2056 __ lw(code, MemOperand(sp, 0 * kPointerSize));
2231 2057
2232 // Check the code is a smi. 2058 // Check the code is a smi.
2233 Label slow; 2059 Label slow;
2234 STATIC_ASSERT(kSmiTag == 0); 2060 STATIC_ASSERT(kSmiTag == 0);
2235 __ JumpIfNotSmi(code, &slow); 2061 __ JumpIfNotSmi(code, &slow);
2236 2062
2237 // Convert the smi code to uint16. 2063 // Convert the smi code to uint16.
2238 __ And(code, code, Operand(Smi::FromInt(0xffff))); 2064 __ And(code, code, Operand(Smi::FromInt(0xffff)));
2239 2065
2240 StringCharFromCodeGenerator generator(code, v0); 2066 StringCharFromCodeGenerator generator(code, v0);
2241 generator.GenerateFast(masm()); 2067 generator.GenerateFast(masm());
2242 __ DropAndRet(argc + 1); 2068 __ DropAndRet(argc + 1);
2243 2069
2244 StubRuntimeCallHelper call_helper; 2070 StubRuntimeCallHelper call_helper;
2245 generator.GenerateSlow(masm(), call_helper); 2071 generator.GenerateSlow(masm(), call_helper);
2246 2072
2247 // Tail call the full function. We do not have to patch the receiver
2248 // because the function makes no use of it.
2249 __ bind(&slow); 2073 __ bind(&slow);
2250 ParameterCount expected(function); 2074 // We do not have to patch the receiver because the function makes no use of
2251 __ InvokeFunction(function, expected, arguments(), 2075 // it.
2252 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2076 GenerateJumpFunctionIgnoreReceiver(function);
2253 2077
2254 __ bind(&miss); 2078 HandlerFrontendFooter(&miss);
2255 // a2: function name.
2256 GenerateMissBranch();
2257 2079
2258 // Return the generated code. 2080 // Return the generated code.
2259 return GetCode(type, name); 2081 return GetCode(type, name);
2260 } 2082 }
2261 2083
2262 2084
2263 Handle<Code> CallStubCompiler::CompileMathFloorCall( 2085 Handle<Code> CallStubCompiler::CompileMathFloorCall(
2264 Handle<Object> object, 2086 Handle<Object> object,
2265 Handle<JSObject> holder, 2087 Handle<JSObject> holder,
2266 Handle<Cell> cell, 2088 Handle<Cell> cell,
2267 Handle<JSFunction> function, 2089 Handle<JSFunction> function,
2268 Handle<String> name, 2090 Handle<String> name,
2269 Code::StubType type) { 2091 Code::StubType type) {
2270 // ----------- S t a t e -------------
2271 // -- a2 : function name
2272 // -- ra : return address
2273 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2274 // -- ...
2275 // -- sp[argc * 4] : receiver
2276 // -----------------------------------
2277
2278
2279 const int argc = arguments().immediate(); 2092 const int argc = arguments().immediate();
2280 // If the object is not a JSObject or we got an unexpected number of 2093 // If the object is not a JSObject or we got an unexpected number of
2281 // arguments, bail out to the regular call. 2094 // arguments, bail out to the regular call.
2282 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2095 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2283 2096
2284 Label miss, slow; 2097 Label miss, slow;
2285 GenerateNameCheck(name, &miss); 2098 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2286 2099 if (!cell.is_null()) {
2287 if (cell.is_null()) {
2288 __ lw(a1, MemOperand(sp, 1 * kPointerSize));
2289 STATIC_ASSERT(kSmiTag == 0);
2290 __ JumpIfSmi(a1, &miss);
2291 CheckPrototypes(
2292 IC::CurrentTypeOf(object, isolate()),
2293 a1, holder, a0, a3, t0, name, &miss);
2294 } else {
2295 ASSERT(cell->value() == *function); 2100 ASSERT(cell->value() == *function);
2296 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2297 &miss);
2298 GenerateLoadFunctionFromCell(cell, function, &miss); 2101 GenerateLoadFunctionFromCell(cell, function, &miss);
2299 } 2102 }
2300 2103
2301 // Load the (only) argument into v0. 2104 // Load the (only) argument into v0.
2302 __ lw(v0, MemOperand(sp, 0 * kPointerSize)); 2105 __ lw(v0, MemOperand(sp, 0 * kPointerSize));
2303 2106
2304 // If the argument is a smi, just return. 2107 // If the argument is a smi, just return.
2305 STATIC_ASSERT(kSmiTag == 0); 2108 STATIC_ASSERT(kSmiTag == 0);
2306 __ SmiTst(v0, t0); 2109 __ SmiTst(v0, t0);
2307 __ DropAndRet(argc + 1, eq, t0, Operand(zero_reg)); 2110 __ DropAndRet(argc + 1, eq, t0, Operand(zero_reg));
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2369 // Restore FCSR and return. 2172 // Restore FCSR and return.
2370 __ ctc1(a3, FCSR); 2173 __ ctc1(a3, FCSR);
2371 2174
2372 __ DropAndRet(argc + 1); 2175 __ DropAndRet(argc + 1);
2373 2176
2374 __ bind(&wont_fit_smi); 2177 __ bind(&wont_fit_smi);
2375 // Restore FCSR and fall to slow case. 2178 // Restore FCSR and fall to slow case.
2376 __ ctc1(a3, FCSR); 2179 __ ctc1(a3, FCSR);
2377 2180
2378 __ bind(&slow); 2181 __ bind(&slow);
2379 // Tail call the full function. We do not have to patch the receiver 2182 // We do not have to patch the receiver because the function makes no use of
2380 // because the function makes no use of it. 2183 // it.
2381 ParameterCount expected(function); 2184 GenerateJumpFunctionIgnoreReceiver(function);
2382 __ InvokeFunction(function, expected, arguments(),
2383 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
2384 2185
2385 __ bind(&miss); 2186 HandlerFrontendFooter(&miss);
2386 // a2: function name.
2387 GenerateMissBranch();
2388 2187
2389 // Return the generated code. 2188 // Return the generated code.
2390 return GetCode(type, name); 2189 return GetCode(type, name);
2391 } 2190 }
2392 2191
2393 2192
2394 Handle<Code> CallStubCompiler::CompileMathAbsCall( 2193 Handle<Code> CallStubCompiler::CompileMathAbsCall(
2395 Handle<Object> object, 2194 Handle<Object> object,
2396 Handle<JSObject> holder, 2195 Handle<JSObject> holder,
2397 Handle<Cell> cell, 2196 Handle<Cell> cell,
2398 Handle<JSFunction> function, 2197 Handle<JSFunction> function,
2399 Handle<String> name, 2198 Handle<String> name,
2400 Code::StubType type) { 2199 Code::StubType type) {
2401 // ----------- S t a t e -------------
2402 // -- a2 : function name
2403 // -- ra : return address
2404 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2405 // -- ...
2406 // -- sp[argc * 4] : receiver
2407 // -----------------------------------
2408
2409 const int argc = arguments().immediate(); 2200 const int argc = arguments().immediate();
2410 // If the object is not a JSObject or we got an unexpected number of 2201 // If the object is not a JSObject or we got an unexpected number of
2411 // arguments, bail out to the regular call. 2202 // arguments, bail out to the regular call.
2412 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2203 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2413 2204
2414 Label miss; 2205 Label miss;
2415 2206
2416 GenerateNameCheck(name, &miss); 2207 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2417 if (cell.is_null()) { 2208 if (!cell.is_null()) {
2418 __ lw(a1, MemOperand(sp, 1 * kPointerSize));
2419 STATIC_ASSERT(kSmiTag == 0);
2420 __ JumpIfSmi(a1, &miss);
2421 CheckPrototypes(
2422 IC::CurrentTypeOf(object, isolate()),
2423 a1, holder, v0, a3, t0, name, &miss);
2424 } else {
2425 ASSERT(cell->value() == *function); 2209 ASSERT(cell->value() == *function);
2426 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2427 &miss);
2428 GenerateLoadFunctionFromCell(cell, function, &miss); 2210 GenerateLoadFunctionFromCell(cell, function, &miss);
2429 } 2211 }
2430 2212
2431 // Load the (only) argument into v0. 2213 // Load the (only) argument into v0.
2432 __ lw(v0, MemOperand(sp, 0 * kPointerSize)); 2214 __ lw(v0, MemOperand(sp, 0 * kPointerSize));
2433 2215
2434 // Check if the argument is a smi. 2216 // Check if the argument is a smi.
2435 Label not_smi; 2217 Label not_smi;
2436 STATIC_ASSERT(kSmiTag == 0); 2218 STATIC_ASSERT(kSmiTag == 0);
2437 __ JumpIfNotSmi(v0, &not_smi); 2219 __ JumpIfNotSmi(v0, &not_smi);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2469 // number. 2251 // number.
2470 __ bind(&negative_sign); 2252 __ bind(&negative_sign);
2471 __ Xor(a1, a1, Operand(HeapNumber::kSignMask)); 2253 __ Xor(a1, a1, Operand(HeapNumber::kSignMask));
2472 __ lw(a3, FieldMemOperand(v0, HeapNumber::kMantissaOffset)); 2254 __ lw(a3, FieldMemOperand(v0, HeapNumber::kMantissaOffset));
2473 __ LoadRoot(t2, Heap::kHeapNumberMapRootIndex); 2255 __ LoadRoot(t2, Heap::kHeapNumberMapRootIndex);
2474 __ AllocateHeapNumber(v0, t0, t1, t2, &slow); 2256 __ AllocateHeapNumber(v0, t0, t1, t2, &slow);
2475 __ sw(a1, FieldMemOperand(v0, HeapNumber::kExponentOffset)); 2257 __ sw(a1, FieldMemOperand(v0, HeapNumber::kExponentOffset));
2476 __ sw(a3, FieldMemOperand(v0, HeapNumber::kMantissaOffset)); 2258 __ sw(a3, FieldMemOperand(v0, HeapNumber::kMantissaOffset));
2477 __ DropAndRet(argc + 1); 2259 __ DropAndRet(argc + 1);
2478 2260
2479 // Tail call the full function. We do not have to patch the receiver
2480 // because the function makes no use of it.
2481 __ bind(&slow); 2261 __ bind(&slow);
2482 ParameterCount expected(function); 2262 // We do not have to patch the receiver because the function makes no use of
2483 __ InvokeFunction(function, expected, arguments(), 2263 // it.
2484 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2264 GenerateJumpFunctionIgnoreReceiver(function);
2485 2265
2486 __ bind(&miss); 2266 HandlerFrontendFooter(&miss);
2487 // a2: function name.
2488 GenerateMissBranch();
2489 2267
2490 // Return the generated code. 2268 // Return the generated code.
2491 return GetCode(type, name); 2269 return GetCode(type, name);
2492 } 2270 }
2493 2271
2494 2272
2495 Handle<Code> CallStubCompiler::CompileFastApiCall( 2273 Handle<Code> CallStubCompiler::CompileFastApiCall(
2496 const CallOptimization& optimization, 2274 const CallOptimization& optimization,
2497 Handle<Object> object, 2275 Handle<Object> object,
2498 Handle<JSObject> holder, 2276 Handle<JSObject> holder,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2531 // Check that the maps haven't changed and find a Holder as a side effect. 2309 // Check that the maps haven't changed and find a Holder as a side effect.
2532 CheckPrototypes( 2310 CheckPrototypes(
2533 IC::CurrentTypeOf(object, isolate()), 2311 IC::CurrentTypeOf(object, isolate()),
2534 a1, holder, a0, a3, t0, name, depth, &miss); 2312 a1, holder, a0, a3, t0, name, depth, &miss);
2535 2313
2536 GenerateFastApiDirectCall(masm(), optimization, argc, false); 2314 GenerateFastApiDirectCall(masm(), optimization, argc, false);
2537 2315
2538 __ bind(&miss); 2316 __ bind(&miss);
2539 FreeSpaceForFastApiCall(masm()); 2317 FreeSpaceForFastApiCall(masm());
2540 2318
2541 __ bind(&miss_before_stack_reserved); 2319 HandlerFrontendFooter(&miss_before_stack_reserved);
2542 GenerateMissBranch();
2543 2320
2544 // Return the generated code. 2321 // Return the generated code.
2545 return GetCode(function); 2322 return GetCode(function);
2546 } 2323 }
2547 2324
2548 2325
2549 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { 2326 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
2550 Label success; 2327 Label success;
2551 // Check that the object is a boolean. 2328 // Check that the object is a boolean.
2552 __ LoadRoot(at, Heap::kTrueValueRootIndex); 2329 __ LoadRoot(at, Heap::kTrueValueRootIndex);
2553 __ Branch(&success, eq, object, Operand(at)); 2330 __ Branch(&success, eq, object, Operand(at));
2554 __ LoadRoot(at, Heap::kFalseValueRootIndex); 2331 __ LoadRoot(at, Heap::kFalseValueRootIndex);
2555 __ Branch(miss, ne, object, Operand(at)); 2332 __ Branch(miss, ne, object, Operand(at));
2556 __ bind(&success); 2333 __ bind(&success);
2557 } 2334 }
2558 2335
2559 2336
2560 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object, 2337 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) {
2561 Handle<JSObject> holder, 2338 if (!object.is_null() && object->IsGlobalObject()) {
2562 Handle<Name> name, 2339 const int argc = arguments().immediate();
2563 CheckType check) { 2340 const int receiver_offset = argc * kPointerSize;
2341 __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset));
2342 __ sw(a3, MemOperand(sp, receiver_offset));
2343 }
2344 }
2345
2346
2347 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object,
2348 Handle<JSObject> holder,
2349 Handle<Name> name,
2350 CheckType check,
2351 Label* miss) {
2564 // ----------- S t a t e ------------- 2352 // ----------- S t a t e -------------
2565 // -- a2 : name 2353 // -- a2 : name
2566 // -- ra : return address 2354 // -- ra : return address
2567 // ----------------------------------- 2355 // -----------------------------------
2568 Label miss; 2356 GenerateNameCheck(name, miss);
2569 GenerateNameCheck(name, &miss); 2357
2358 Register reg = a0;
2570 2359
2571 // Get the receiver from the stack. 2360 // Get the receiver from the stack.
2572 const int argc = arguments().immediate(); 2361 const int argc = arguments().immediate();
2573 __ lw(a1, MemOperand(sp, argc * kPointerSize)); 2362 const int receiver_offset = argc * kPointerSize;
2363 __ lw(a0, MemOperand(sp, receiver_offset));
2574 2364
2575 // Check that the receiver isn't a smi. 2365 // Check that the receiver isn't a smi.
2576 if (check != NUMBER_CHECK) { 2366 if (check != NUMBER_CHECK) {
2577 __ JumpIfSmi(a1, &miss); 2367 __ JumpIfSmi(a0, miss);
2578 } 2368 }
2579 2369
2580 // Make sure that it's okay not to patch the on stack receiver 2370 // Make sure that it's okay not to patch the on stack receiver
2581 // unless we're doing a receiver map check. 2371 // unless we're doing a receiver map check.
2582 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 2372 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
2583 switch (check) { 2373 switch (check) {
2584 case RECEIVER_MAP_CHECK: 2374 case RECEIVER_MAP_CHECK:
2585 __ IncrementCounter(isolate()->counters()->call_const(), 1, a0, a3); 2375 __ IncrementCounter(isolate()->counters()->call_const(), 1, a1, a3);
2586 2376
2587 // Check that the maps haven't changed. 2377 // Check that the maps haven't changed.
2588 CheckPrototypes( 2378 reg = CheckPrototypes(
2589 IC::CurrentTypeOf(object, isolate()), 2379 IC::CurrentTypeOf(object, isolate()),
2590 a1, holder, a0, a3, t0, name, &miss); 2380 reg, holder, a1, a3, t0, name, miss);
2591
2592 // Patch the receiver on the stack with the global proxy if
2593 // necessary.
2594 if (object->IsGlobalObject()) {
2595 __ lw(a3, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset));
2596 __ sw(a3, MemOperand(sp, argc * kPointerSize));
2597 }
2598 break; 2381 break;
2599 2382
2600 case STRING_CHECK: { 2383 case STRING_CHECK: {
2601 // Check that the object is a string. 2384 // Check that the object is a string.
2602 __ GetObjectType(a1, a3, a3); 2385 __ GetObjectType(reg, a3, a3);
2603 __ Branch(&miss, Ugreater_equal, a3, Operand(FIRST_NONSTRING_TYPE)); 2386 __ Branch(miss, Ugreater_equal, a3, Operand(FIRST_NONSTRING_TYPE));
2604 // Check that the maps starting from the prototype haven't changed. 2387 // Check that the maps starting from the prototype haven't changed.
2605 GenerateDirectLoadGlobalFunctionPrototype( 2388 GenerateDirectLoadGlobalFunctionPrototype(
2606 masm(), Context::STRING_FUNCTION_INDEX, a0, &miss); 2389 masm(), Context::STRING_FUNCTION_INDEX, a1, miss);
2607 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2608 CheckPrototypes(
2609 IC::CurrentTypeOf(prototype, isolate()),
2610 a0, holder, a3, a1, t0, name, &miss);
2611 break; 2390 break;
2612 } 2391 }
2613 case SYMBOL_CHECK: { 2392 case SYMBOL_CHECK: {
2614 // Check that the object is a symbol. 2393 // Check that the object is a symbol.
2615 __ GetObjectType(a1, a1, a3); 2394 __ GetObjectType(reg, a1, a3);
2616 __ Branch(&miss, ne, a3, Operand(SYMBOL_TYPE)); 2395 __ Branch(miss, ne, a3, Operand(SYMBOL_TYPE));
2617 // Check that the maps starting from the prototype haven't changed. 2396 // Check that the maps starting from the prototype haven't changed.
2618 GenerateDirectLoadGlobalFunctionPrototype( 2397 GenerateDirectLoadGlobalFunctionPrototype(
2619 masm(), Context::SYMBOL_FUNCTION_INDEX, a0, &miss); 2398 masm(), Context::SYMBOL_FUNCTION_INDEX, a1, miss);
2620 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2621 CheckPrototypes(
2622 IC::CurrentTypeOf(prototype, isolate()),
2623 a0, holder, a3, a1, t0, name, &miss);
2624 break; 2399 break;
2625 } 2400 }
2626 case NUMBER_CHECK: { 2401 case NUMBER_CHECK: {
2627 Label fast; 2402 Label fast;
2628 // Check that the object is a smi or a heap number. 2403 // Check that the object is a smi or a heap number.
2629 __ JumpIfSmi(a1, &fast); 2404 __ JumpIfSmi(reg, &fast);
2630 __ GetObjectType(a1, a0, a0); 2405 __ GetObjectType(reg, a3, a3);
2631 __ Branch(&miss, ne, a0, Operand(HEAP_NUMBER_TYPE)); 2406 __ Branch(miss, ne, a3, Operand(HEAP_NUMBER_TYPE));
2632 __ bind(&fast); 2407 __ bind(&fast);
2633 // Check that the maps starting from the prototype haven't changed. 2408 // Check that the maps starting from the prototype haven't changed.
2634 GenerateDirectLoadGlobalFunctionPrototype( 2409 GenerateDirectLoadGlobalFunctionPrototype(
2635 masm(), Context::NUMBER_FUNCTION_INDEX, a0, &miss); 2410 masm(), Context::NUMBER_FUNCTION_INDEX, a1, miss);
2636 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2637 CheckPrototypes(
2638 IC::CurrentTypeOf(prototype, isolate()),
2639 a0, holder, a3, a1, t0, name, &miss);
2640 break; 2411 break;
2641 } 2412 }
2642 case BOOLEAN_CHECK: { 2413 case BOOLEAN_CHECK: {
2643 GenerateBooleanCheck(a1, &miss); 2414 GenerateBooleanCheck(reg, miss);
2644 2415
2645 // Check that the maps starting from the prototype haven't changed. 2416 // Check that the maps starting from the prototype haven't changed.
2646 GenerateDirectLoadGlobalFunctionPrototype( 2417 GenerateDirectLoadGlobalFunctionPrototype(
2647 masm(), Context::BOOLEAN_FUNCTION_INDEX, a0, &miss); 2418 masm(), Context::BOOLEAN_FUNCTION_INDEX, a1, miss);
2648 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2649 CheckPrototypes(
2650 IC::CurrentTypeOf(prototype, isolate()),
2651 a0, holder, a3, a1, t0, name, &miss);
2652 break; 2419 break;
2653 } 2420 }
2654 } 2421 }
2655 2422
2656 Label success; 2423 if (check != RECEIVER_MAP_CHECK) {
2657 __ Branch(&success); 2424 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2425 reg = CheckPrototypes(
2426 IC::CurrentTypeOf(prototype, isolate()),
2427 a1, holder, a1, a3, t0, name, miss);
2428 }
2658 2429
2659 // Handle call cache miss. 2430 return reg;
2660 __ bind(&miss);
2661
2662 GenerateMissBranch();
2663
2664 __ bind(&success);
2665 } 2431 }
2666 2432
2667 2433
2668 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { 2434 void CallStubCompiler::GenerateJumpFunction(Handle<Object> object,
2669 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2435 Register function,
2670 ? CALL_AS_FUNCTION 2436 Label* miss) {
2671 : CALL_AS_METHOD; 2437 ASSERT(function.is(a1));
2672 ParameterCount expected(function); 2438 // Check that the function really is a function.
2673 __ InvokeFunction(function, expected, arguments(), 2439 GenerateFunctionCheck(function, a3, miss);
2674 JUMP_FUNCTION, NullCallWrapper(), call_kind); 2440 if (!function.is(a1)) __ mov(a1, function);
2675 } 2441 PatchGlobalProxy(object);
2676 2442 // Invoke the function.
2677 2443 __ InvokeFunction(a1, arguments(), JUMP_FUNCTION,
2678 Handle<Code> CallStubCompiler::CompileCallConstant( 2444 NullCallWrapper(), call_kind());
2679 Handle<Object> object,
2680 Handle<JSObject> holder,
2681 Handle<Name> name,
2682 CheckType check,
2683 Handle<JSFunction> function) {
2684 if (HasCustomCallGenerator(function)) {
2685 Handle<Code> code = CompileCustomCall(object, holder,
2686 Handle<Cell>::null(),
2687 function, Handle<String>::cast(name),
2688 Code::FAST);
2689 // A null handle means bail out to the regular compiler code below.
2690 if (!code.is_null()) return code;
2691 }
2692
2693 CompileHandlerFrontend(object, holder, name, check);
2694 CompileHandlerBackend(function);
2695
2696 // Return the generated code.
2697 return GetCode(function);
2698 } 2445 }
2699 2446
2700 2447
2701 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2448 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
2702 Handle<JSObject> holder, 2449 Handle<JSObject> holder,
2703 Handle<Name> name) { 2450 Handle<Name> name) {
2704 // ----------- S t a t e -------------
2705 // -- a2 : name
2706 // -- ra : return address
2707 // -----------------------------------
2708
2709 Label miss; 2451 Label miss;
2710 2452
2711 GenerateNameCheck(name, &miss); 2453 GenerateNameCheck(name, &miss);
2712 2454
2713 // Get the number of arguments. 2455 // Get the number of arguments.
2714 const int argc = arguments().immediate(); 2456 const int argc = arguments().immediate();
2715 LookupResult lookup(isolate()); 2457 LookupResult lookup(isolate());
2716 LookupPostInterceptor(holder, name, &lookup); 2458 LookupPostInterceptor(holder, name, &lookup);
2717 2459
2718 // Get the receiver from the stack. 2460 // Get the receiver from the stack.
2719 __ lw(a1, MemOperand(sp, argc * kPointerSize)); 2461 __ lw(a1, MemOperand(sp, argc * kPointerSize));
2720 2462
2721 CallInterceptorCompiler compiler(this, arguments(), a2, extra_state_); 2463 CallInterceptorCompiler compiler(this, arguments(), a2, extra_state_);
2722 compiler.Compile(masm(), object, holder, name, &lookup, a1, a3, t0, a0, 2464 compiler.Compile(masm(), object, holder, name, &lookup, a1, a3, t0, a0,
2723 &miss); 2465 &miss);
2724 2466
2725 // Move returned value, the function to call, to a1. 2467 // Move returned value, the function to call, to a1.
2726 __ mov(a1, v0); 2468 __ mov(a1, v0);
2727 // Restore receiver. 2469 // Restore receiver.
2728 __ lw(a0, MemOperand(sp, argc * kPointerSize)); 2470 __ lw(a0, MemOperand(sp, argc * kPointerSize));
2729 2471
2730 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); 2472 GenerateJumpFunction(object, a1, &miss);
2731 2473
2732 // Handle call cache miss. 2474 HandlerFrontendFooter(&miss);
2733 __ bind(&miss);
2734 GenerateMissBranch();
2735 2475
2736 // Return the generated code. 2476 // Return the generated code.
2737 return GetCode(Code::FAST, name); 2477 return GetCode(Code::FAST, name);
2738 } 2478 }
2739 2479
2740 2480
2741 Handle<Code> CallStubCompiler::CompileCallGlobal( 2481 Handle<Code> CallStubCompiler::CompileCallGlobal(
2742 Handle<JSObject> object, 2482 Handle<JSObject> object,
2743 Handle<GlobalObject> holder, 2483 Handle<GlobalObject> holder,
2744 Handle<PropertyCell> cell, 2484 Handle<PropertyCell> cell,
2745 Handle<JSFunction> function, 2485 Handle<JSFunction> function,
2746 Handle<Name> name) { 2486 Handle<Name> name) {
2747 // ----------- S t a t e -------------
2748 // -- a2 : name
2749 // -- ra : return address
2750 // -----------------------------------
2751
2752 if (HasCustomCallGenerator(function)) { 2487 if (HasCustomCallGenerator(function)) {
2753 Handle<Code> code = CompileCustomCall( 2488 Handle<Code> code = CompileCustomCall(
2754 object, holder, cell, function, Handle<String>::cast(name), 2489 object, holder, cell, function, Handle<String>::cast(name),
2755 Code::NORMAL); 2490 Code::NORMAL);
2756 // A null handle means bail out to the regular compiler code below. 2491 // A null handle means bail out to the regular compiler code below.
2757 if (!code.is_null()) return code; 2492 if (!code.is_null()) return code;
2758 } 2493 }
2759 2494
2760 Label miss; 2495 Label miss;
2761 GenerateNameCheck(name, &miss); 2496 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2762 2497 // Potentially loads a closure that matches the shared function info of the
2763 // Get the number of arguments. 2498 // function, rather than function.
2764 const int argc = arguments().immediate();
2765 GenerateGlobalReceiverCheck(object, holder, name, &miss);
2766 GenerateLoadFunctionFromCell(cell, function, &miss); 2499 GenerateLoadFunctionFromCell(cell, function, &miss);
2767
2768 // Patch the receiver on the stack with the global proxy if
2769 // necessary.
2770 if (object->IsGlobalObject()) {
2771 __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset));
2772 __ sw(a3, MemOperand(sp, argc * kPointerSize));
2773 }
2774
2775 // Set up the context (function already in r1).
2776 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
2777
2778 // Jump to the cached code (tail call).
2779 Counters* counters = isolate()->counters(); 2500 Counters* counters = isolate()->counters();
2780 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); 2501 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0);
2781 ParameterCount expected(function->shared()->formal_parameter_count()); 2502 GenerateJumpFunction(object, a1, function);
2782 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2503 HandlerFrontendFooter(&miss);
2783 ? CALL_AS_FUNCTION
2784 : CALL_AS_METHOD;
2785 // We call indirectly through the code field in the function to
2786 // allow recompilation to take effect without changing any of the
2787 // call sites.
2788 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
2789 __ InvokeCode(a3, expected, arguments(), JUMP_FUNCTION,
2790 NullCallWrapper(), call_kind);
2791
2792 // Handle call cache miss.
2793 __ bind(&miss);
2794 __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3);
2795 GenerateMissBranch();
2796 2504
2797 // Return the generated code. 2505 // Return the generated code.
2798 return GetCode(Code::NORMAL, name); 2506 return GetCode(Code::NORMAL, name);
2799 } 2507 }
2800 2508
2801 2509
2802 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2510 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2803 Handle<JSObject> object, 2511 Handle<JSObject> object,
2804 Handle<JSObject> holder, 2512 Handle<JSObject> holder,
2805 Handle<Name> name, 2513 Handle<Name> name,
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
2904 if (object->IsJSGlobalProxy()) { 2612 if (object->IsJSGlobalProxy()) {
2905 __ CheckAccessGlobalProxy(receiver(), scratch1(), &miss); 2613 __ CheckAccessGlobalProxy(receiver(), scratch1(), &miss);
2906 } 2614 }
2907 2615
2908 // Stub is never generated for non-global objects that require access 2616 // Stub is never generated for non-global objects that require access
2909 // checks. 2617 // checks.
2910 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 2618 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
2911 2619
2912 __ Push(receiver(), this->name(), value()); 2620 __ Push(receiver(), this->name(), value());
2913 2621
2914 __ li(scratch1(), Operand(Smi::FromInt(strict_mode())));
2915 __ push(scratch1()); // strict mode
2916
2917 // Do tail-call to the runtime system. 2622 // Do tail-call to the runtime system.
2918 ExternalReference store_ic_property = 2623 ExternalReference store_ic_property =
2919 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); 2624 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate());
2920 __ TailCallExternalReference(store_ic_property, 4, 1); 2625 __ TailCallExternalReference(store_ic_property, 3, 1);
2921 2626
2922 // Handle store cache miss. 2627 // Handle store cache miss.
2923 __ bind(&miss); 2628 __ bind(&miss);
2924 TailCallBuiltin(masm(), MissBuiltin(kind())); 2629 TailCallBuiltin(masm(), MissBuiltin(kind()));
2925 2630
2926 // Return the generated code. 2631 // Return the generated code.
2927 return GetCode(kind(), Code::FAST, name); 2632 return GetCode(kind(), Code::FAST, name);
2928 } 2633 }
2929 2634
2930 2635
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
3177 // ----------------------------------- 2882 // -----------------------------------
3178 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 2883 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
3179 } 2884 }
3180 2885
3181 2886
3182 #undef __ 2887 #undef __
3183 2888
3184 } } // namespace v8::internal 2889 } } // namespace v8::internal
3185 2890
3186 #endif // V8_TARGET_ARCH_MIPS 2891 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/macro-assembler-mips.cc ('k') | src/object-observe.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698