OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
8 #include "src/interpreter/bytecode-array-iterator.h" | 8 #include "src/interpreter/bytecode-array-iterator.h" |
9 #include "src/interpreter/bytecode-generator.h" | 9 #include "src/interpreter/bytecode-generator.h" |
10 #include "src/interpreter/interpreter.h" | 10 #include "src/interpreter/interpreter.h" |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 | 124 |
125 static void CheckConstant(InstanceType expected, Object* actual) { | 125 static void CheckConstant(InstanceType expected, Object* actual) { |
126 CHECK_EQ(expected, HeapObject::cast(actual)->map()->instance_type()); | 126 CHECK_EQ(expected, HeapObject::cast(actual)->map()->instance_type()); |
127 } | 127 } |
128 | 128 |
129 | 129 |
130 template <typename T> | 130 template <typename T> |
131 static void CheckBytecodeArrayEqual(struct ExpectedSnippet<T> expected, | 131 static void CheckBytecodeArrayEqual(struct ExpectedSnippet<T> expected, |
132 Handle<BytecodeArray> actual, | 132 Handle<BytecodeArray> actual, |
133 bool has_unknown = false) { | 133 bool has_unknown = false) { |
134 CHECK_EQ(actual->frame_size(), expected.frame_size); | 134 CHECK_EQ(expected.frame_size, actual->frame_size()); |
135 CHECK_EQ(actual->parameter_count(), expected.parameter_count); | 135 CHECK_EQ(expected.parameter_count, actual->parameter_count()); |
136 CHECK_EQ(actual->length(), expected.bytecode_length); | 136 CHECK_EQ(expected.bytecode_length, actual->length()); |
137 if (expected.constant_count == 0) { | 137 if (expected.constant_count == 0) { |
138 CHECK_EQ(actual->constant_pool(), CcTest::heap()->empty_fixed_array()); | 138 CHECK_EQ(CcTest::heap()->empty_fixed_array(), actual->constant_pool()); |
139 } else { | 139 } else { |
140 CHECK_EQ(actual->constant_pool()->length(), expected.constant_count); | 140 CHECK_EQ(expected.constant_count, actual->constant_pool()->length()); |
141 for (int i = 0; i < expected.constant_count; i++) { | 141 for (int i = 0; i < expected.constant_count; i++) { |
142 CheckConstant(expected.constants[i], actual->constant_pool()->get(i)); | 142 CheckConstant(expected.constants[i], actual->constant_pool()->get(i)); |
143 } | 143 } |
144 } | 144 } |
145 | 145 |
146 BytecodeArrayIterator iterator(actual); | 146 BytecodeArrayIterator iterator(actual); |
147 int i = 0; | 147 int i = 0; |
148 while (!iterator.done()) { | 148 while (!iterator.done()) { |
149 int bytecode_index = i++; | 149 int bytecode_index = i++; |
150 Bytecode bytecode = iterator.current_bytecode(); | 150 Bytecode bytecode = iterator.current_bytecode(); |
(...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1029 helper.MakeBytecode(snippets[i].code_snippet, helper.kFunctionName); | 1029 helper.MakeBytecode(snippets[i].code_snippet, helper.kFunctionName); |
1030 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | 1030 CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
1031 } | 1031 } |
1032 } | 1032 } |
1033 | 1033 |
1034 | 1034 |
1035 TEST(LoadGlobal) { | 1035 TEST(LoadGlobal) { |
1036 InitializedHandleScope handle_scope; | 1036 InitializedHandleScope handle_scope; |
1037 BytecodeGeneratorHelper helper; | 1037 BytecodeGeneratorHelper helper; |
1038 | 1038 |
| 1039 if (!FLAG_global_var_shortcuts) return; |
| 1040 |
1039 ExpectedSnippet<int> snippets[] = { | 1041 ExpectedSnippet<int> snippets[] = { |
1040 { | 1042 { |
1041 "var a = 1;\nfunction f() { return a; }\nf()", | 1043 "var a = 1;\nfunction f() { return a; }\nf()", |
1042 0, | 1044 0, |
1043 1, | 1045 1, |
1044 3, | 1046 3, |
1045 { | 1047 { |
1046 B(LdaGlobal), _, // | 1048 B(LdaGlobal), _, // |
1047 B(Return) // | 1049 B(Return) // |
1048 }, | 1050 }, |
(...skipping 15 matching lines...) Expand all Loading... |
1064 helper.MakeBytecode(snippets[i].code_snippet, "f"); | 1066 helper.MakeBytecode(snippets[i].code_snippet, "f"); |
1065 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true); | 1067 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true); |
1066 } | 1068 } |
1067 } | 1069 } |
1068 | 1070 |
1069 | 1071 |
1070 TEST(StoreGlobal) { | 1072 TEST(StoreGlobal) { |
1071 InitializedHandleScope handle_scope; | 1073 InitializedHandleScope handle_scope; |
1072 BytecodeGeneratorHelper helper; | 1074 BytecodeGeneratorHelper helper; |
1073 | 1075 |
| 1076 if (!FLAG_global_var_shortcuts) return; |
| 1077 |
1074 ExpectedSnippet<InstanceType> snippets[] = { | 1078 ExpectedSnippet<InstanceType> snippets[] = { |
1075 { | 1079 { |
1076 "var a = 1;\nfunction f() { a = 2; }\nf()", | 1080 "var a = 1;\nfunction f() { a = 2; }\nf()", |
1077 0, | 1081 0, |
1078 1, | 1082 1, |
1079 6, | 1083 6, |
1080 { | 1084 { |
1081 B(LdaSmi8), U8(2), // | 1085 B(LdaSmi8), U8(2), // |
1082 B(StaGlobalSloppy), _, // | 1086 B(StaGlobalSloppy), _, // |
1083 B(LdaUndefined), // | 1087 B(LdaUndefined), // |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1115 helper.MakeBytecode(snippets[i].code_snippet, "f"); | 1119 helper.MakeBytecode(snippets[i].code_snippet, "f"); |
1116 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true); | 1120 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true); |
1117 } | 1121 } |
1118 } | 1122 } |
1119 | 1123 |
1120 | 1124 |
1121 TEST(CallGlobal) { | 1125 TEST(CallGlobal) { |
1122 InitializedHandleScope handle_scope; | 1126 InitializedHandleScope handle_scope; |
1123 BytecodeGeneratorHelper helper; | 1127 BytecodeGeneratorHelper helper; |
1124 | 1128 |
| 1129 if (!FLAG_global_var_shortcuts) return; |
| 1130 |
1125 ExpectedSnippet<int> snippets[] = { | 1131 ExpectedSnippet<int> snippets[] = { |
1126 { | 1132 { |
1127 "function t() { }\nfunction f() { return t(); }\nf()", | 1133 "function t() { }\nfunction f() { return t(); }\nf()", |
1128 2 * kPointerSize, | 1134 2 * kPointerSize, |
1129 1, | 1135 1, |
1130 12, | 1136 12, |
1131 { | 1137 { |
1132 B(LdaUndefined), // | 1138 B(LdaUndefined), // |
1133 B(Star), R(1), // | 1139 B(Star), R(1), // |
1134 B(LdaGlobal), _, // | 1140 B(LdaGlobal), _, // |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1170 | 1176 |
1171 TEST(LoadUnallocated) { | 1177 TEST(LoadUnallocated) { |
1172 InitializedHandleScope handle_scope; | 1178 InitializedHandleScope handle_scope; |
1173 BytecodeGeneratorHelper helper; | 1179 BytecodeGeneratorHelper helper; |
1174 Zone zone; | 1180 Zone zone; |
1175 | 1181 |
1176 int context_reg = Register::function_context().index(); | 1182 int context_reg = Register::function_context().index(); |
1177 int global_index = Context::GLOBAL_OBJECT_INDEX; | 1183 int global_index = Context::GLOBAL_OBJECT_INDEX; |
1178 | 1184 |
1179 FeedbackVectorSpec feedback_spec(&zone); | 1185 FeedbackVectorSpec feedback_spec(&zone); |
1180 FeedbackVectorSlot slot1 = feedback_spec.AddStoreICSlot(); | 1186 FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot(); |
1181 | 1187 |
1182 Handle<i::TypeFeedbackVector> vector = | 1188 Handle<i::TypeFeedbackVector> vector = |
1183 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); | 1189 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); |
1184 | 1190 |
1185 ExpectedSnippet<const char*> snippets[] = { | 1191 ExpectedSnippet<const char*> snippets[] = { |
1186 {"a = 1;\nfunction f() { return a; }\nf()", | 1192 {"a = 1;\nfunction f() { return a; }\nf()", |
1187 1 * kPointerSize, | 1193 1 * kPointerSize, |
1188 1, | 1194 1, |
1189 11, | 1195 11, |
1190 {B(LdaContextSlot), R(context_reg), U8(global_index), // | 1196 {B(LdaContextSlot), R(context_reg), U8(global_index), // |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1491 }; | 1497 }; |
1492 | 1498 |
1493 for (size_t i = 0; i < arraysize(snippets); i++) { | 1499 for (size_t i = 0; i < arraysize(snippets); i++) { |
1494 Handle<BytecodeArray> bytecode_array = | 1500 Handle<BytecodeArray> bytecode_array = |
1495 helper.MakeBytecode(snippets[i].code_snippet, helper.kFunctionName); | 1501 helper.MakeBytecode(snippets[i].code_snippet, helper.kFunctionName); |
1496 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | 1502 CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
1497 } | 1503 } |
1498 } | 1504 } |
1499 | 1505 |
1500 | 1506 |
| 1507 // Tests !FLAG_global_var_shortcuts mode. |
1501 TEST(DeclareGlobals) { | 1508 TEST(DeclareGlobals) { |
1502 InitializedHandleScope handle_scope; | 1509 InitializedHandleScope handle_scope; |
1503 BytecodeGeneratorHelper helper; | 1510 BytecodeGeneratorHelper helper; |
| 1511 Zone zone; |
| 1512 |
| 1513 if (FLAG_global_var_shortcuts) return; |
| 1514 |
| 1515 int context_reg = Register::function_context().index(); |
| 1516 int global_index = Context::GLOBAL_OBJECT_INDEX; |
| 1517 |
| 1518 // Create different feedback vector specs to be precise on slot numbering. |
| 1519 FeedbackVectorSpec feedback_spec_ss(&zone); |
| 1520 FeedbackVectorSlot slot_ss_1 = feedback_spec_ss.AddStoreICSlot(); |
| 1521 FeedbackVectorSlot slot_ss_2 = feedback_spec_ss.AddStoreICSlot(); |
| 1522 USE(slot_ss_1); |
| 1523 |
| 1524 Handle<i::TypeFeedbackVector> vector_ss = |
| 1525 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec_ss); |
| 1526 |
| 1527 FeedbackVectorSpec feedback_spec_l(&zone); |
| 1528 FeedbackVectorSlot slot_l_1 = feedback_spec_l.AddLoadICSlot(); |
| 1529 |
| 1530 Handle<i::TypeFeedbackVector> vector_l = |
| 1531 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec_l); |
| 1532 |
1504 | 1533 |
1505 ExpectedSnippet<InstanceType> snippets[] = { | 1534 ExpectedSnippet<InstanceType> snippets[] = { |
1506 {"var a = 1;", | 1535 {"var a = 1;", |
| 1536 4 * kPointerSize, |
| 1537 1, |
| 1538 30, |
| 1539 { |
| 1540 B(LdaConstant), U8(0), // |
| 1541 B(Star), R(1), // |
| 1542 B(LdaZero), // |
| 1543 B(Star), R(2), // |
| 1544 B(CallRuntime), U16(Runtime::kDeclareGlobals), R(1), U8(2), // |
| 1545 B(LdaConstant), U8(1), // |
| 1546 B(Star), R(1), // |
| 1547 B(LdaZero), // |
| 1548 B(Star), R(2), // |
| 1549 B(LdaSmi8), U8(1), // |
| 1550 B(Star), R(3), // |
| 1551 B(CallRuntime), U16(Runtime::kInitializeVarGlobal), R(1), // |
| 1552 U8(3), // |
| 1553 B(LdaUndefined), // |
| 1554 B(Return) // |
| 1555 }, |
| 1556 2, |
| 1557 {InstanceType::FIXED_ARRAY_TYPE, |
| 1558 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, |
| 1559 {"function f() {}", |
| 1560 2 * kPointerSize, |
| 1561 1, |
| 1562 14, |
| 1563 { |
| 1564 B(LdaConstant), U8(0), // |
| 1565 B(Star), R(0), // |
| 1566 B(LdaZero), // |
| 1567 B(Star), R(1), // |
| 1568 B(CallRuntime), U16(Runtime::kDeclareGlobals), R(0), U8(2), // |
| 1569 B(LdaUndefined), // |
| 1570 B(Return) // |
| 1571 }, |
| 1572 1, |
| 1573 {InstanceType::FIXED_ARRAY_TYPE}}, |
| 1574 {"var a = 1;\na=2;", |
| 1575 4 * kPointerSize, |
| 1576 1, |
| 1577 52, |
| 1578 { |
| 1579 B(LdaConstant), U8(0), // |
| 1580 B(Star), R(1), // |
| 1581 B(LdaZero), // |
| 1582 B(Star), R(2), // |
| 1583 B(CallRuntime), U16(Runtime::kDeclareGlobals), R(1), U8(2), // |
| 1584 B(LdaConstant), U8(1), // |
| 1585 B(Star), R(1), // |
| 1586 B(LdaZero), // |
| 1587 B(Star), R(2), // |
| 1588 B(LdaSmi8), U8(1), // |
| 1589 B(Star), R(3), // |
| 1590 B(CallRuntime), U16(Runtime::kInitializeVarGlobal), R(1), // |
| 1591 U8(3), // |
| 1592 B(LdaSmi8), U8(2), // |
| 1593 B(Star), R(1), // |
| 1594 B(LdaContextSlot), R(context_reg), U8(global_index), // |
| 1595 B(Star), R(2), // |
| 1596 B(LdaConstant), U8(1), // |
| 1597 B(Star), R(3), // |
| 1598 B(Ldar), R(1), // |
| 1599 B(StoreICSloppy), R(2), R(3), U8(vector_ss->GetIndex(slot_ss_2)), // |
| 1600 B(Star), R(0), // |
| 1601 B(Ldar), R(0), // |
| 1602 B(Return) // |
| 1603 }, |
| 1604 2, |
| 1605 {InstanceType::FIXED_ARRAY_TYPE, |
| 1606 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, |
| 1607 {"function f() {}\nf();", |
| 1608 4 * kPointerSize, |
| 1609 1, |
| 1610 36, |
| 1611 { |
| 1612 B(LdaConstant), U8(0), // |
| 1613 B(Star), R(1), // |
| 1614 B(LdaZero), // |
| 1615 B(Star), R(2), // |
| 1616 B(CallRuntime), U16(Runtime::kDeclareGlobals), R(1), U8(2), // |
| 1617 B(LdaUndefined), // |
| 1618 B(Star), R(2), // |
| 1619 B(LdaContextSlot), R(context_reg), U8(global_index), // |
| 1620 B(Star), R(3), // |
| 1621 B(LdaConstant), U8(1), // |
| 1622 B(LoadICSloppy), R(3), U8(vector_l->GetIndex(slot_l_1)), // |
| 1623 B(Star), R(1), // |
| 1624 B(Call), R(1), R(2), U8(0), // |
| 1625 B(Star), R(0), // |
| 1626 B(Ldar), R(0), // |
| 1627 B(Return) // |
| 1628 }, |
| 1629 2, |
| 1630 {InstanceType::FIXED_ARRAY_TYPE, |
| 1631 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, |
| 1632 }; |
| 1633 |
| 1634 for (size_t i = 0; i < arraysize(snippets); i++) { |
| 1635 Handle<BytecodeArray> bytecode_array = |
| 1636 helper.MakeTopLevelBytecode(snippets[i].code_snippet); |
| 1637 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true); |
| 1638 } |
| 1639 } |
| 1640 |
| 1641 |
| 1642 // Tests FLAG_global_var_shortcuts mode. |
| 1643 // TODO(ishell): remove when FLAG_global_var_shortcuts is removed. |
| 1644 TEST(DeclareGlobals2) { |
| 1645 InitializedHandleScope handle_scope; |
| 1646 BytecodeGeneratorHelper helper; |
| 1647 |
| 1648 if (!FLAG_global_var_shortcuts) return; |
| 1649 |
| 1650 ExpectedSnippet<InstanceType> snippets[] = { |
| 1651 {"var a = 1;", |
1507 5 * kPointerSize, | 1652 5 * kPointerSize, |
1508 1, | 1653 1, |
1509 45, | 1654 45, |
1510 { | 1655 { |
1511 B(Ldar), R(Register::function_closure().index()), // | 1656 B(Ldar), R(Register::function_closure().index()), // |
1512 B(Star), R(2), // | 1657 B(Star), R(2), // |
1513 B(LdaConstant), U8(0), // | 1658 B(LdaConstant), U8(0), // |
1514 B(Star), R(3), // | 1659 B(Star), R(3), // |
1515 B(CallRuntime), U16(Runtime::kNewScriptContext), R(2), U8(2), // | 1660 B(CallRuntime), U16(Runtime::kNewScriptContext), R(2), U8(2), // |
1516 B(PushContext), R(1), // | 1661 B(PushContext), R(1), // |
(...skipping 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2617 }; | 2762 }; |
2618 | 2763 |
2619 for (size_t i = 0; i < arraysize(snippets); i++) { | 2764 for (size_t i = 0; i < arraysize(snippets); i++) { |
2620 Handle<BytecodeArray> bytecode_array = | 2765 Handle<BytecodeArray> bytecode_array = |
2621 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | 2766 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); |
2622 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | 2767 CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
2623 } | 2768 } |
2624 } | 2769 } |
2625 | 2770 |
2626 | 2771 |
| 2772 // Tests !FLAG_global_var_shortcuts mode. |
2627 TEST(TopLevelObjectLiterals) { | 2773 TEST(TopLevelObjectLiterals) { |
2628 InitializedHandleScope handle_scope; | 2774 InitializedHandleScope handle_scope; |
2629 BytecodeGeneratorHelper helper; | 2775 BytecodeGeneratorHelper helper; |
2630 | 2776 |
| 2777 if (FLAG_global_var_shortcuts) return; |
| 2778 |
2631 int has_function_flags = ObjectLiteral::kFastElements | | 2779 int has_function_flags = ObjectLiteral::kFastElements | |
2632 ObjectLiteral::kHasFunction | | 2780 ObjectLiteral::kHasFunction | |
2633 ObjectLiteral::kDisableMementos; | 2781 ObjectLiteral::kDisableMementos; |
| 2782 ExpectedSnippet<InstanceType> snippets[] = { |
| 2783 {"var a = { func: function() { } };", |
| 2784 6 * kPointerSize, |
| 2785 1, |
| 2786 54, |
| 2787 { |
| 2788 B(LdaConstant), U8(0), // |
| 2789 B(Star), R(1), // |
| 2790 B(LdaZero), // |
| 2791 B(Star), R(2), // |
| 2792 B(CallRuntime), U16(Runtime::kDeclareGlobals), R(1), U8(2), // |
| 2793 B(LdaConstant), U8(1), // |
| 2794 B(Star), R(1), // |
| 2795 B(LdaZero), // |
| 2796 B(Star), R(2), // |
| 2797 B(LdaConstant), U8(2), // |
| 2798 B(CreateObjectLiteral), U8(0), U8(has_function_flags), // |
| 2799 B(Star), R(4), // |
| 2800 B(LdaConstant), U8(3), // |
| 2801 B(Star), R(5), // |
| 2802 B(LdaConstant), U8(4), // |
| 2803 B(CreateClosure), U8(1), // |
| 2804 B(StoreICSloppy), R(4), R(5), U8(5), // |
| 2805 B(CallRuntime), U16(Runtime::kToFastProperties), R(4), U8(1), // |
| 2806 B(Ldar), R(4), // |
| 2807 B(Star), R(3), // |
| 2808 B(CallRuntime), U16(Runtime::kInitializeVarGlobal), R(1), U8(3), // |
| 2809 B(LdaUndefined), // |
| 2810 B(Return), // |
| 2811 }, |
| 2812 5, |
| 2813 {InstanceType::FIXED_ARRAY_TYPE, |
| 2814 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, |
| 2815 InstanceType::FIXED_ARRAY_TYPE, |
| 2816 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, |
| 2817 InstanceType::SHARED_FUNCTION_INFO_TYPE}}, |
| 2818 }; |
| 2819 |
| 2820 for (size_t i = 0; i < arraysize(snippets); i++) { |
| 2821 Handle<BytecodeArray> bytecode_array = |
| 2822 helper.MakeTopLevelBytecode(snippets[i].code_snippet); |
| 2823 CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
| 2824 } |
| 2825 } |
| 2826 |
| 2827 |
| 2828 // Tests FLAG_global_var_shortcuts mode. |
| 2829 // TODO(ishell): remove when FLAG_global_var_shortcuts is removed. |
| 2830 TEST(TopLevelObjectLiterals2) { |
| 2831 InitializedHandleScope handle_scope; |
| 2832 BytecodeGeneratorHelper helper; |
| 2833 |
| 2834 if (!FLAG_global_var_shortcuts) return; |
| 2835 |
| 2836 int has_function_flags = ObjectLiteral::kFastElements | |
| 2837 ObjectLiteral::kHasFunction | |
| 2838 ObjectLiteral::kDisableMementos; |
2634 ExpectedSnippet<InstanceType> snippets[] = { | 2839 ExpectedSnippet<InstanceType> snippets[] = { |
2635 {"var a = { func: function() { } };", | 2840 {"var a = { func: function() { } };", |
2636 7 * kPointerSize, | 2841 7 * kPointerSize, |
2637 1, | 2842 1, |
2638 69, | 2843 69, |
2639 { | 2844 { |
2640 B(Ldar), R(Register::function_closure().index()), // | 2845 B(Ldar), R(Register::function_closure().index()), // |
2641 B(Star), R(2), // | 2846 B(Star), R(2), // |
2642 B(LdaConstant), U8(0), // | 2847 B(LdaConstant), U8(0), // |
2643 B(Star), R(3), // | 2848 B(Star), R(3), // |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2800 }; | 3005 }; |
2801 | 3006 |
2802 for (size_t i = 0; i < arraysize(snippets); i++) { | 3007 for (size_t i = 0; i < arraysize(snippets); i++) { |
2803 Handle<BytecodeArray> bytecode_array = | 3008 Handle<BytecodeArray> bytecode_array = |
2804 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | 3009 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); |
2805 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | 3010 CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
2806 } | 3011 } |
2807 } | 3012 } |
2808 | 3013 |
2809 | 3014 |
| 3015 // Tests !FLAG_global_var_shortcuts mode. |
2810 TEST(CallNew) { | 3016 TEST(CallNew) { |
2811 InitializedHandleScope handle_scope; | 3017 InitializedHandleScope handle_scope; |
2812 BytecodeGeneratorHelper helper; | 3018 BytecodeGeneratorHelper helper; |
| 3019 Zone zone; |
| 3020 |
| 3021 if (FLAG_global_var_shortcuts) return; |
| 3022 |
| 3023 int context_reg = Register::function_context().index(); |
| 3024 int global_index = Context::GLOBAL_OBJECT_INDEX; |
| 3025 |
| 3026 FeedbackVectorSpec feedback_spec(&zone); |
| 3027 FeedbackVectorSlot slot1 = feedback_spec.AddGeneralSlot(); |
| 3028 FeedbackVectorSlot slot2 = feedback_spec.AddLoadICSlot(); |
| 3029 USE(slot1); |
| 3030 |
| 3031 Handle<i::TypeFeedbackVector> vector = |
| 3032 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); |
2813 | 3033 |
2814 ExpectedSnippet<InstanceType> snippets[] = { | 3034 ExpectedSnippet<InstanceType> snippets[] = { |
2815 {"function bar() { this.value = 0; }\n" | 3035 {"function bar() { this.value = 0; }\n" |
| 3036 "function f() { return new bar(); }\n" |
| 3037 "f()", |
| 3038 2 * kPointerSize, |
| 3039 1, |
| 3040 17, |
| 3041 { |
| 3042 B(LdaContextSlot), R(context_reg), U8(global_index), // |
| 3043 B(Star), R(1), // |
| 3044 B(LdaConstant), U8(0), // |
| 3045 B(LoadICSloppy), R(1), U8(vector->GetIndex(slot2)), // |
| 3046 B(Star), R(0), // |
| 3047 B(New), R(0), R(0), U8(0), // |
| 3048 B(Return), // |
| 3049 }, |
| 3050 1, |
| 3051 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, |
| 3052 {"function bar(x) { this.value = 18; this.x = x;}\n" |
| 3053 "function f() { return new bar(3); }\n" |
| 3054 "f()", |
| 3055 2 * kPointerSize, |
| 3056 1, |
| 3057 21, |
| 3058 { |
| 3059 B(LdaContextSlot), R(context_reg), U8(global_index), // |
| 3060 B(Star), R(1), // |
| 3061 B(LdaConstant), U8(0), // |
| 3062 B(LoadICSloppy), R(1), U8(vector->GetIndex(slot2)), // |
| 3063 B(Star), R(0), // |
| 3064 B(LdaSmi8), U8(3), // |
| 3065 B(Star), R(1), // |
| 3066 B(New), R(0), R(1), U8(1), // |
| 3067 B(Return), // |
| 3068 }, |
| 3069 1, |
| 3070 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, |
| 3071 {"function bar(w, x, y, z) {\n" |
| 3072 " this.value = 18;\n" |
| 3073 " this.x = x;\n" |
| 3074 " this.y = y;\n" |
| 3075 " this.z = z;\n" |
| 3076 "}\n" |
| 3077 "function f() { return new bar(3, 4, 5); }\n" |
| 3078 "f()", |
| 3079 4 * kPointerSize, |
| 3080 1, |
| 3081 29, |
| 3082 { |
| 3083 B(LdaContextSlot), R(context_reg), U8(global_index), // |
| 3084 B(Star), R(1), // |
| 3085 B(LdaConstant), U8(0), // |
| 3086 B(LoadICSloppy), R(1), U8(vector->GetIndex(slot2)), // |
| 3087 B(Star), R(0), // |
| 3088 B(LdaSmi8), U8(3), // |
| 3089 B(Star), R(1), // |
| 3090 B(LdaSmi8), U8(4), // |
| 3091 B(Star), R(2), // |
| 3092 B(LdaSmi8), U8(5), // |
| 3093 B(Star), R(3), // |
| 3094 B(New), R(0), R(1), U8(3), // |
| 3095 B(Return), // |
| 3096 }, |
| 3097 1, |
| 3098 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, |
| 3099 }; |
| 3100 |
| 3101 for (size_t i = 0; i < arraysize(snippets); i++) { |
| 3102 Handle<BytecodeArray> bytecode_array = |
| 3103 helper.MakeBytecode(snippets[i].code_snippet, "f"); |
| 3104 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true); |
| 3105 } |
| 3106 } |
| 3107 |
| 3108 |
| 3109 // Tests FLAG_global_var_shortcuts mode. |
| 3110 // TODO(ishell): remove when FLAG_global_var_shortcuts is removed. |
| 3111 TEST(CallNew2) { |
| 3112 InitializedHandleScope handle_scope; |
| 3113 BytecodeGeneratorHelper helper; |
| 3114 |
| 3115 if (!FLAG_global_var_shortcuts) return; |
| 3116 |
| 3117 ExpectedSnippet<InstanceType> snippets[] = { |
| 3118 {"function bar() { this.value = 0; }\n" |
2816 "function f() { return new bar(); }\n" | 3119 "function f() { return new bar(); }\n" |
2817 "f()", | 3120 "f()", |
2818 kPointerSize, | 3121 kPointerSize, |
2819 1, | 3122 1, |
2820 9, | 3123 9, |
2821 { | 3124 { |
2822 B(LdaGlobal), _, // | 3125 B(LdaGlobal), _, // |
2823 B(Star), R(0), // | 3126 B(Star), R(0), // |
2824 B(New), R(0), R(0), U8(0), // | 3127 B(New), R(0), R(0), U8(0), // |
2825 B(Return), // | 3128 B(Return), // |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3073 for (size_t i = 0; i < arraysize(snippets); i++) { | 3376 for (size_t i = 0; i < arraysize(snippets); i++) { |
3074 Handle<BytecodeArray> bytecode_array = | 3377 Handle<BytecodeArray> bytecode_array = |
3075 helper.MakeBytecodeForFunction(snippets[i].code_snippet); | 3378 helper.MakeBytecodeForFunction(snippets[i].code_snippet); |
3076 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | 3379 CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
3077 } | 3380 } |
3078 } | 3381 } |
3079 | 3382 |
3080 } // namespace interpreter | 3383 } // namespace interpreter |
3081 } // namespace internal | 3384 } // namespace internal |
3082 } // namespace v8 | 3385 } // namespace v8 |
OLD | NEW |