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

Side by Side Diff: test/cctest/interpreter/test-bytecode-generator.cc

Issue 1420503002: [Interpreter] Add support for compound expressions. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebased Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/interpreter/bytecode-generator.cc ('k') | test/cctest/interpreter/test-interpreter.cc » ('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 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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 } 70 }
71 }; 71 };
72 72
73 73
74 // Helper macros for handcrafting bytecode sequences. 74 // Helper macros for handcrafting bytecode sequences.
75 #define B(x) static_cast<uint8_t>(Bytecode::k##x) 75 #define B(x) static_cast<uint8_t>(Bytecode::k##x)
76 #define U8(x) static_cast<uint8_t>((x) & 0xff) 76 #define U8(x) static_cast<uint8_t>((x) & 0xff)
77 #define R(x) static_cast<uint8_t>(-(x) & 0xff) 77 #define R(x) static_cast<uint8_t>(-(x) & 0xff)
78 #define A(x, n) R(helper.kLastParamIndex - (n) + 1 + (x)) 78 #define A(x, n) R(helper.kLastParamIndex - (n) + 1 + (x))
79 #define THIS(n) A(0, n) 79 #define THIS(n) A(0, n)
80 #define _ static_cast<uint8_t>(0x5a)
81 #if defined(V8_TARGET_LITTLE_ENDIAN) 80 #if defined(V8_TARGET_LITTLE_ENDIAN)
82 #define U16(x) static_cast<uint8_t>((x) & 0xff), \ 81 #define U16(x) static_cast<uint8_t>((x) & 0xff), \
83 static_cast<uint8_t>(((x) >> kBitsPerByte) & 0xff) 82 static_cast<uint8_t>(((x) >> kBitsPerByte) & 0xff)
84 #elif defined(V8_TARGET_BIG_ENDIAN) 83 #elif defined(V8_TARGET_BIG_ENDIAN)
85 #define U16(x) static_cast<uint8_t>(((x) >> kBitsPerByte) & 0xff), \ 84 #define U16(x) static_cast<uint8_t>(((x) >> kBitsPerByte) & 0xff), \
86 static_cast<uint8_t>((x) & 0xff) 85 static_cast<uint8_t>((x) & 0xff)
87 #else 86 #else
88 #error Unknown byte ordering 87 #error Unknown byte ordering
89 #endif 88 #endif
90 89
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 } 123 }
125 124
126 125
127 static void CheckConstant(InstanceType expected, Object* actual) { 126 static void CheckConstant(InstanceType expected, Object* actual) {
128 CHECK_EQ(expected, HeapObject::cast(actual)->map()->instance_type()); 127 CHECK_EQ(expected, HeapObject::cast(actual)->map()->instance_type());
129 } 128 }
130 129
131 130
132 template <typename T> 131 template <typename T>
133 static void CheckBytecodeArrayEqual(const ExpectedSnippet<T>& expected, 132 static void CheckBytecodeArrayEqual(const ExpectedSnippet<T>& expected,
134 Handle<BytecodeArray> actual, 133 Handle<BytecodeArray> actual) {
135 bool has_unknown = false) {
136 CHECK_EQ(expected.frame_size, actual->frame_size()); 134 CHECK_EQ(expected.frame_size, actual->frame_size());
137 CHECK_EQ(expected.parameter_count, actual->parameter_count()); 135 CHECK_EQ(expected.parameter_count, actual->parameter_count());
138 CHECK_EQ(expected.bytecode_length, actual->length()); 136 CHECK_EQ(expected.bytecode_length, actual->length());
139 if (expected.constant_count == 0) { 137 if (expected.constant_count == 0) {
140 CHECK_EQ(CcTest::heap()->empty_fixed_array(), actual->constant_pool()); 138 CHECK_EQ(CcTest::heap()->empty_fixed_array(), actual->constant_pool());
141 } else { 139 } else {
142 CHECK_EQ(expected.constant_count, actual->constant_pool()->length()); 140 CHECK_EQ(expected.constant_count, actual->constant_pool()->length());
143 for (int i = 0; i < expected.constant_count; i++) { 141 for (int i = 0; i < expected.constant_count; i++) {
144 CheckConstant(expected.constants[i], actual->constant_pool()->get(i)); 142 CheckConstant(expected.constants[i], actual->constant_pool()->get(i));
145 } 143 }
(...skipping 10 matching lines...) Expand all
156 << "] to be " << Bytecodes::ToString(static_cast<Bytecode>( 154 << "] to be " << Bytecodes::ToString(static_cast<Bytecode>(
157 expected.bytecode[bytecode_index])) 155 expected.bytecode[bytecode_index]))
158 << " but got " << Bytecodes::ToString(bytecode); 156 << " but got " << Bytecodes::ToString(bytecode);
159 FATAL(stream.str().c_str()); 157 FATAL(stream.str().c_str());
160 } 158 }
161 for (int j = 0; j < Bytecodes::NumberOfOperands(bytecode); ++j) { 159 for (int j = 0; j < Bytecodes::NumberOfOperands(bytecode); ++j) {
162 OperandType operand_type = Bytecodes::GetOperandType(bytecode, j); 160 OperandType operand_type = Bytecodes::GetOperandType(bytecode, j);
163 int operand_index = i; 161 int operand_index = i;
164 i += static_cast<int>(Bytecodes::SizeOfOperand(operand_type)); 162 i += static_cast<int>(Bytecodes::SizeOfOperand(operand_type));
165 uint32_t raw_operand = iterator.GetRawOperand(j, operand_type); 163 uint32_t raw_operand = iterator.GetRawOperand(j, operand_type);
166 if (has_unknown) {
167 // Check actual bytecode array doesn't have the same byte as the
168 // one we use to specify an unknown byte.
169 CHECK_NE(raw_operand, _);
170 if (expected.bytecode[operand_index] == _) {
171 continue;
172 }
173 }
174 uint32_t expected_operand; 164 uint32_t expected_operand;
175 switch (Bytecodes::SizeOfOperand(operand_type)) { 165 switch (Bytecodes::SizeOfOperand(operand_type)) {
176 case OperandSize::kNone: 166 case OperandSize::kNone:
177 UNREACHABLE(); 167 UNREACHABLE();
178 return; 168 return;
179 case OperandSize::kByte: 169 case OperandSize::kByte:
180 expected_operand = 170 expected_operand =
181 static_cast<uint32_t>(expected.bytecode[operand_index]); 171 static_cast<uint32_t>(expected.bytecode[operand_index]);
182 break; 172 break;
183 case OperandSize::kShort: 173 case OperandSize::kShort:
(...skipping 1334 matching lines...) Expand 10 before | Expand all | Expand 10 after
1518 B(Return) // 1508 B(Return) //
1519 }, 1509 },
1520 2, 1510 2,
1521 {InstanceType::FIXED_ARRAY_TYPE, 1511 {InstanceType::FIXED_ARRAY_TYPE,
1522 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, 1512 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
1523 }; 1513 };
1524 1514
1525 for (size_t i = 0; i < arraysize(snippets); i++) { 1515 for (size_t i = 0; i < arraysize(snippets); i++) {
1526 Handle<BytecodeArray> bytecode_array = 1516 Handle<BytecodeArray> bytecode_array =
1527 helper.MakeTopLevelBytecode(snippets[i].code_snippet); 1517 helper.MakeTopLevelBytecode(snippets[i].code_snippet);
1528 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true); 1518 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
1529 } 1519 }
1530 } 1520 }
1531 1521
1532 1522
1533 TEST(BasicLoops) { 1523 TEST(BasicLoops) {
1534 InitializedHandleScope handle_scope; 1524 InitializedHandleScope handle_scope;
1535 BytecodeGeneratorHelper helper; 1525 BytecodeGeneratorHelper helper;
1536 1526
1537 ExpectedSnippet<int> snippets[] = { 1527 ExpectedSnippet<int> snippets[] = {
1538 {"var x = 0;" 1528 {"var x = 0;"
(...skipping 1163 matching lines...) Expand 10 before | Expand all | Expand 10 after
2702 B(New), R(0), R(1), U8(3), // 2692 B(New), R(0), R(1), U8(3), //
2703 B(Return), // 2693 B(Return), //
2704 }, 2694 },
2705 1, 2695 1,
2706 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, 2696 {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
2707 }; 2697 };
2708 2698
2709 for (size_t i = 0; i < arraysize(snippets); i++) { 2699 for (size_t i = 0; i < arraysize(snippets); i++) {
2710 Handle<BytecodeArray> bytecode_array = 2700 Handle<BytecodeArray> bytecode_array =
2711 helper.MakeBytecode(snippets[i].code_snippet, "f"); 2701 helper.MakeBytecode(snippets[i].code_snippet, "f");
2712 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true); 2702 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
2713 } 2703 }
2714 } 2704 }
2715 2705
2716 2706
2717 TEST(ContextVariables) { 2707 TEST(ContextVariables) {
2718 InitializedHandleScope handle_scope; 2708 InitializedHandleScope handle_scope;
2719 BytecodeGeneratorHelper helper; 2709 BytecodeGeneratorHelper helper;
2720 2710
2721 int closure = Register::function_closure().index(); 2711 int closure = Register::function_closure().index();
2722 int first_context_slot = Context::MIN_CONTEXT_SLOTS; 2712 int first_context_slot = Context::MIN_CONTEXT_SLOTS;
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2831 } 2821 }
2832 } 2822 }
2833 2823
2834 2824
2835 TEST(ContextParameters) { 2825 TEST(ContextParameters) {
2836 InitializedHandleScope handle_scope; 2826 InitializedHandleScope handle_scope;
2837 BytecodeGeneratorHelper helper; 2827 BytecodeGeneratorHelper helper;
2838 2828
2839 int closure = Register::function_closure().index(); 2829 int closure = Register::function_closure().index();
2840 int first_context_slot = Context::MIN_CONTEXT_SLOTS; 2830 int first_context_slot = Context::MIN_CONTEXT_SLOTS;
2831
2841 ExpectedSnippet<InstanceType> snippets[] = { 2832 ExpectedSnippet<InstanceType> snippets[] = {
2842 {"function f(arg1) { return function() { arg1 = 2; }; }", 2833 {"function f(arg1) { return function() { arg1 = 2; }; }",
2843 1 * kPointerSize, 2834 1 * kPointerSize,
2844 2, 2835 2,
2845 17, 2836 17,
2846 { 2837 {
2847 B(CallRuntime), U16(Runtime::kNewFunctionContext), // 2838 B(CallRuntime), U16(Runtime::kNewFunctionContext), //
2848 R(closure), U8(1), // 2839 R(closure), U8(1), //
2849 B(PushContext), R(0), // 2840 B(PushContext), R(0), //
2850 B(Ldar), R(helper.kLastParamIndex), // 2841 B(Ldar), R(helper.kLastParamIndex), //
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after
3194 B(Ldar), R(0), // 3185 B(Ldar), R(0), //
3195 B(Return), 3186 B(Return),
3196 }, 3187 },
3197 1, 3188 1,
3198 {"unallocated"}}, 3189 {"unallocated"}},
3199 }; 3190 };
3200 3191
3201 for (size_t i = 0; i < arraysize(snippets); i++) { 3192 for (size_t i = 0; i < arraysize(snippets); i++) {
3202 Handle<BytecodeArray> bytecode_array = 3193 Handle<BytecodeArray> bytecode_array =
3203 helper.MakeBytecode(snippets[i].code_snippet, "f"); 3194 helper.MakeBytecode(snippets[i].code_snippet, "f");
3204 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true); 3195 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
3205 } 3196 }
3206 } 3197 }
3207 3198
3199
3200 TEST(CompoundExpressions) {
3201 InitializedHandleScope handle_scope;
3202 BytecodeGeneratorHelper helper;
3203 Zone zone;
3204
3205 int closure = Register::function_closure().index();
3206 int first_context_slot = Context::MIN_CONTEXT_SLOTS;
3207
3208 FeedbackVectorSpec feedback_spec(&zone);
3209 FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot();
3210 FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot();
3211
3212 Handle<i::TypeFeedbackVector> vector =
3213 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
3214
3215 int object_literal_flags =
3216 ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos;
3217 ExpectedSnippet<InstanceType> snippets[] = {
3218 {"var a = 1; a += 2;",
3219 1 * kPointerSize,
3220 1,
3221 12,
3222 {
3223 B(LdaSmi8), U8(1), //
3224 B(Star), R(0), //
3225 B(LdaSmi8), U8(2), //
3226 B(Add), R(0), //
3227 B(Star), R(0), //
3228 B(LdaUndefined), //
3229 B(Return), //
3230 }},
3231 {"var a = 1; a /= 2;",
3232 1 * kPointerSize,
3233 1,
3234 12,
3235 {
3236 B(LdaSmi8), U8(1), //
3237 B(Star), R(0), //
3238 B(LdaSmi8), U8(2), //
3239 B(Div), R(0), //
3240 B(Star), R(0), //
3241 B(LdaUndefined), //
3242 B(Return), //
3243 }},
3244 {"var a = { val: 2 }; a.name *= 2;",
3245 2 * kPointerSize,
3246 1,
3247 23,
3248 {
3249 B(LdaConstant), U8(0), //
3250 B(CreateObjectLiteral), U8(0), U8(object_literal_flags), //
3251 B(Star), R(0), //
3252 B(LoadICSloppy), R(0), U8(1), U8(vector->GetIndex(slot1)), //
3253 B(Star), R(1), //
3254 B(LdaSmi8), U8(2), //
3255 B(Mul), R(1), //
3256 B(StoreICSloppy), R(0), U8(1), U8(vector->GetIndex(slot2)), //
3257 B(LdaUndefined), //
3258 B(Return), //
3259 },
3260 2,
3261 {InstanceType::FIXED_ARRAY_TYPE,
3262 InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
3263 {"var a = { 1: 2 }; a[1] ^= 2;",
3264 3 * kPointerSize,
3265 1,
3266 26,
3267 {
3268 B(LdaConstant), U8(0), //
3269 B(CreateObjectLiteral), U8(0), U8(object_literal_flags), //
3270 B(Star), R(0), //
3271 B(LdaSmi8), U8(1), //
3272 B(Star), R(1), //
3273 B(KeyedLoadICSloppy), R(0), U8(vector->GetIndex(slot1)), //
3274 B(Star), R(2), //
3275 B(LdaSmi8), U8(2), //
3276 B(BitwiseXor), R(2), //
3277 B(KeyedStoreICSloppy), R(0), R(1), U8(vector->GetIndex(slot2)), //
3278 B(LdaUndefined), //
3279 B(Return), //
3280 },
3281 1,
3282 {InstanceType::FIXED_ARRAY_TYPE}},
3283 {"var a = 1; (function f() { return a; }); a |= 24;",
3284 2 * kPointerSize,
3285 1,
3286 30,
3287 {
3288 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), //
3289 U8(1), //
3290 B(PushContext), R(0), //
3291 B(LdaSmi8), U8(1), //
3292 B(StaContextSlot), R(0), U8(first_context_slot), //
3293 B(LdaConstant), U8(0), //
3294 B(CreateClosure), U8(0), //
3295 B(LdaContextSlot), R(0), U8(first_context_slot), //
3296 B(Star), R(1), //
3297 B(LdaSmi8), U8(24), //
3298 B(BitwiseOr), R(1), //
3299 B(StaContextSlot), R(0), U8(first_context_slot), //
3300 B(LdaUndefined), //
3301 B(Return), //
3302 },
3303 1,
3304 {InstanceType::SHARED_FUNCTION_INFO_TYPE}},
3305 };
3306
3307 for (size_t i = 0; i < arraysize(snippets); i++) {
3308 Handle<BytecodeArray> bytecode_array =
3309 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
3310 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
3311 }
3312 }
3313
3314
3315 TEST(GlobalCompoundExpressions) {
3316 InitializedHandleScope handle_scope;
3317 BytecodeGeneratorHelper helper;
3318 Zone zone;
3319
3320 FeedbackVectorSpec feedback_spec(&zone);
3321 FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot();
3322 FeedbackVectorSlot slot2 = feedback_spec.AddStoreICSlot();
3323
3324 Handle<i::TypeFeedbackVector> vector =
3325 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
3326
3327 ExpectedSnippet<const char*> snippets[] = {
3328 {"var global = 1;\nfunction f() { return global &= 1; }\nf()",
3329 1 * kPointerSize,
3330 1,
3331 13,
3332 {
3333 B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot1)), //
3334 B(Star), R(0), //
3335 B(LdaSmi8), U8(1), //
3336 B(BitwiseAnd), R(0), //
3337 B(StaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)), //
3338 B(Return), //
3339 },
3340 1,
3341 {"global"}},
3342 {"unallocated = 1;\nfunction f() { return unallocated += 1; }\nf()",
3343 1 * kPointerSize,
3344 1,
3345 13,
3346 {
3347 B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot1)), //
3348 B(Star), R(0), //
3349 B(LdaSmi8), U8(1), //
3350 B(Add), R(0), //
3351 B(StaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)), //
3352 B(Return), //
3353 },
3354 1,
3355 {"unallocated"}},
3356 };
3357
3358 for (size_t i = 0; i < arraysize(snippets); i++) {
3359 Handle<BytecodeArray> bytecode_array =
3360 helper.MakeBytecode(snippets[i].code_snippet, "f");
3361 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
3362 }
3363 }
3364
3208 } // namespace interpreter 3365 } // namespace interpreter
3209 } // namespace internal 3366 } // namespace internal
3210 } // namespace v8 3367 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-generator.cc ('k') | test/cctest/interpreter/test-interpreter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698