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/execution.h" | 7 #include "src/execution.h" |
8 #include "src/handles.h" | 8 #include "src/handles.h" |
9 #include "src/interpreter/bytecode-array-builder.h" | 9 #include "src/interpreter/bytecode-array-builder.h" |
| 10 #include "src/interpreter/bytecode-array-iterator.h" |
10 #include "src/interpreter/interpreter.h" | 11 #include "src/interpreter/interpreter.h" |
11 #include "test/cctest/cctest.h" | 12 #include "test/cctest/cctest.h" |
12 #include "test/cctest/interpreter/interpreter-tester.h" | 13 #include "test/cctest/interpreter/interpreter-tester.h" |
13 #include "test/cctest/test-feedback-vector.h" | 14 #include "test/cctest/test-feedback-vector.h" |
14 | 15 |
15 namespace v8 { | 16 namespace v8 { |
16 namespace internal { | 17 namespace internal { |
17 namespace interpreter { | 18 namespace interpreter { |
18 | 19 |
19 | 20 |
(...skipping 965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
985 .Bind(&done1) | 986 .Bind(&done1) |
986 .Return(); | 987 .Return(); |
987 | 988 |
988 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 989 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
989 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 990 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
990 auto callable = tester.GetCallable<>(); | 991 auto callable = tester.GetCallable<>(); |
991 Handle<Object> return_value = callable().ToHandleChecked(); | 992 Handle<Object> return_value = callable().ToHandleChecked(); |
992 CHECK_EQ(Smi::cast(*return_value)->value(), 7); | 993 CHECK_EQ(Smi::cast(*return_value)->value(), 7); |
993 } | 994 } |
994 | 995 |
995 | |
996 TEST(InterpreterConditionalJumps2) { | 996 TEST(InterpreterConditionalJumps2) { |
997 // TODO(oth): Add tests for all conditional jumps near and far. | 997 // TODO(oth): Add tests for all conditional jumps near and far. |
998 HandleAndZoneScope handles; | 998 HandleAndZoneScope handles; |
999 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 0, | 999 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 0, |
1000 0, 2); | 1000 0, 2); |
1001 Register reg(0), scratch(1); | 1001 Register reg(0), scratch(1); |
1002 BytecodeLabel label[2]; | 1002 BytecodeLabel label[2]; |
1003 BytecodeLabel done, done1; | 1003 BytecodeLabel done, done1; |
1004 | 1004 |
1005 builder.LoadLiteral(Smi::FromInt(0)) | 1005 builder.LoadLiteral(Smi::FromInt(0)) |
(...skipping 13 matching lines...) Expand all Loading... |
1019 .Bind(&done1) | 1019 .Bind(&done1) |
1020 .Return(); | 1020 .Return(); |
1021 | 1021 |
1022 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 1022 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
1023 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 1023 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
1024 auto callable = tester.GetCallable<>(); | 1024 auto callable = tester.GetCallable<>(); |
1025 Handle<Object> return_value = callable().ToHandleChecked(); | 1025 Handle<Object> return_value = callable().ToHandleChecked(); |
1026 CHECK_EQ(Smi::cast(*return_value)->value(), 7); | 1026 CHECK_EQ(Smi::cast(*return_value)->value(), 7); |
1027 } | 1027 } |
1028 | 1028 |
| 1029 TEST(InterpreterJumpConstantWith16BitOperand) { |
| 1030 HandleAndZoneScope handles; |
| 1031 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1, |
| 1032 0, 257); |
| 1033 Register reg(0), scratch(256); |
| 1034 BytecodeLabel done; |
| 1035 |
| 1036 builder.LoadLiteral(Smi::FromInt(0)); |
| 1037 builder.StoreAccumulatorInRegister(reg); |
| 1038 // Consume all 8-bit operands |
| 1039 for (int i = 1; i <= 256; i++) { |
| 1040 builder.LoadLiteral(handles.main_isolate()->factory()->NewNumber(i)); |
| 1041 builder.BinaryOperation(Token::Value::ADD, reg); |
| 1042 builder.StoreAccumulatorInRegister(reg); |
| 1043 } |
| 1044 builder.Jump(&done); |
| 1045 |
| 1046 // Emit more than 16-bit immediate operands worth of code to jump over. |
| 1047 for (int i = 0; i < 6600; i++) { |
| 1048 builder.LoadLiteral(Smi::FromInt(0)); // 1-byte |
| 1049 builder.BinaryOperation(Token::Value::ADD, scratch); // 4-bytes |
| 1050 builder.StoreAccumulatorInRegister(scratch); // 4-bytes |
| 1051 builder.MoveRegister(scratch, reg); // 6-bytes |
| 1052 } |
| 1053 builder.Bind(&done); |
| 1054 builder.LoadAccumulatorWithRegister(reg); |
| 1055 builder.Return(); |
| 1056 |
| 1057 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 1058 BytecodeArrayIterator iterator(bytecode_array); |
| 1059 |
| 1060 bool found_16bit_constant_jump = false; |
| 1061 while (!iterator.done()) { |
| 1062 if (iterator.current_bytecode() == Bytecode::kJumpConstant && |
| 1063 iterator.current_operand_scale() == OperandScale::kDouble) { |
| 1064 found_16bit_constant_jump = true; |
| 1065 break; |
| 1066 } |
| 1067 iterator.Advance(); |
| 1068 } |
| 1069 CHECK(found_16bit_constant_jump); |
| 1070 |
| 1071 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 1072 auto callable = tester.GetCallable<>(); |
| 1073 Handle<Object> return_value = callable().ToHandleChecked(); |
| 1074 CHECK_EQ(Smi::cast(*return_value)->value(), 256.0 / 2 * (1 + 256)); |
| 1075 } |
| 1076 |
| 1077 TEST(InterpreterJumpWith32BitOperand) { |
| 1078 HandleAndZoneScope handles; |
| 1079 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1, |
| 1080 0, 1); |
| 1081 Register reg(0); |
| 1082 BytecodeLabel done; |
| 1083 |
| 1084 builder.LoadLiteral(Smi::FromInt(0)); |
| 1085 builder.StoreAccumulatorInRegister(reg); |
| 1086 // Consume all 16-bit constant pool entries |
| 1087 for (int i = 1; i <= 65536; i++) { |
| 1088 builder.LoadLiteral(handles.main_isolate()->factory()->NewNumber(i)); |
| 1089 } |
| 1090 builder.Jump(&done); |
| 1091 builder.LoadLiteral(Smi::FromInt(0)); |
| 1092 builder.Bind(&done); |
| 1093 builder.Return(); |
| 1094 |
| 1095 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 1096 BytecodeArrayIterator iterator(bytecode_array); |
| 1097 |
| 1098 bool found_32bit_jump = false; |
| 1099 while (!iterator.done()) { |
| 1100 if (iterator.current_bytecode() == Bytecode::kJump && |
| 1101 iterator.current_operand_scale() == OperandScale::kQuadruple) { |
| 1102 found_32bit_jump = true; |
| 1103 break; |
| 1104 } |
| 1105 iterator.Advance(); |
| 1106 } |
| 1107 CHECK(found_32bit_jump); |
| 1108 |
| 1109 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 1110 auto callable = tester.GetCallable<>(); |
| 1111 Handle<Object> return_value = callable().ToHandleChecked(); |
| 1112 CHECK_EQ(Smi::cast(*return_value)->value(), 65536.0); |
| 1113 } |
| 1114 |
1029 static const Token::Value kComparisonTypes[] = { | 1115 static const Token::Value kComparisonTypes[] = { |
1030 Token::Value::EQ, Token::Value::NE, Token::Value::EQ_STRICT, | 1116 Token::Value::EQ, Token::Value::NE, Token::Value::EQ_STRICT, |
1031 Token::Value::LT, Token::Value::LTE, Token::Value::GT, | 1117 Token::Value::LT, Token::Value::LTE, Token::Value::GT, |
1032 Token::Value::GTE}; | 1118 Token::Value::GTE}; |
1033 | 1119 |
1034 template <typename T> | 1120 template <typename T> |
1035 bool CompareC(Token::Value op, T lhs, T rhs, bool types_differed = false) { | 1121 bool CompareC(Token::Value op, T lhs, T rhs, bool types_differed = false) { |
1036 switch (op) { | 1122 switch (op) { |
1037 case Token::Value::EQ: | 1123 case Token::Value::EQ: |
1038 return lhs == rhs; | 1124 return lhs == rhs; |
(...skipping 3010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4049 v8::Local<v8::String> expected_string = v8_str(const_decl[i].second); | 4135 v8::Local<v8::String> expected_string = v8_str(const_decl[i].second); |
4050 CHECK( | 4136 CHECK( |
4051 message->Equals(CcTest::isolate()->GetCurrentContext(), expected_string) | 4137 message->Equals(CcTest::isolate()->GetCurrentContext(), expected_string) |
4052 .FromJust()); | 4138 .FromJust()); |
4053 } | 4139 } |
4054 } | 4140 } |
4055 | 4141 |
4056 } // namespace interpreter | 4142 } // namespace interpreter |
4057 } // namespace internal | 4143 } // namespace internal |
4058 } // namespace v8 | 4144 } // namespace v8 |
OLD | NEW |