OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/interpreter/bytecode-array-builder.h" | 7 #include "src/interpreter/bytecode-array-builder.h" |
8 #include "src/interpreter/bytecode-array-iterator.h" | 8 #include "src/interpreter/bytecode-array-iterator.h" |
9 #include "src/interpreter/bytecode-register-allocator.h" | 9 #include "src/interpreter/bytecode-register-allocator.h" |
10 #include "test/unittests/test-utils.h" | 10 #include "test/unittests/test-utils.h" |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 builder.Call(reg, other, 1, 0) | 102 builder.Call(reg, other, 1, 0) |
103 .Call(reg, wide, 1, 0) | 103 .Call(reg, wide, 1, 0) |
104 .CallRuntime(Runtime::kIsArray, reg, 1) | 104 .CallRuntime(Runtime::kIsArray, reg, 1) |
105 .CallRuntime(Runtime::kIsArray, wide, 1) | 105 .CallRuntime(Runtime::kIsArray, wide, 1) |
106 .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, reg, 1, other) | 106 .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, reg, 1, other) |
107 .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, wide, 1, other) | 107 .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, wide, 1, other) |
108 .CallJSRuntime(Context::SPREAD_ITERABLE_INDEX, reg, 1) | 108 .CallJSRuntime(Context::SPREAD_ITERABLE_INDEX, reg, 1) |
109 .CallJSRuntime(Context::SPREAD_ITERABLE_INDEX, wide, 1); | 109 .CallJSRuntime(Context::SPREAD_ITERABLE_INDEX, wide, 1); |
110 | 110 |
111 // Emit binary operator invocations. | 111 // Emit binary operator invocations. |
112 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) | 112 builder.BinaryOperation(Token::Value::ADD, reg) |
113 .BinaryOperation(Token::Value::SUB, reg, Strength::WEAK) | 113 .BinaryOperation(Token::Value::SUB, reg) |
114 .BinaryOperation(Token::Value::MUL, reg, Strength::WEAK) | 114 .BinaryOperation(Token::Value::MUL, reg) |
115 .BinaryOperation(Token::Value::DIV, reg, Strength::WEAK) | 115 .BinaryOperation(Token::Value::DIV, reg) |
116 .BinaryOperation(Token::Value::MOD, reg, Strength::WEAK); | 116 .BinaryOperation(Token::Value::MOD, reg); |
117 | 117 |
118 // Emit bitwise operator invocations | 118 // Emit bitwise operator invocations |
119 builder.BinaryOperation(Token::Value::BIT_OR, reg, Strength::WEAK) | 119 builder.BinaryOperation(Token::Value::BIT_OR, reg) |
120 .BinaryOperation(Token::Value::BIT_XOR, reg, Strength::WEAK) | 120 .BinaryOperation(Token::Value::BIT_XOR, reg) |
121 .BinaryOperation(Token::Value::BIT_AND, reg, Strength::WEAK); | 121 .BinaryOperation(Token::Value::BIT_AND, reg); |
122 | 122 |
123 // Emit shift operator invocations | 123 // Emit shift operator invocations |
124 builder.BinaryOperation(Token::Value::SHL, reg, Strength::WEAK) | 124 builder.BinaryOperation(Token::Value::SHL, reg) |
125 .BinaryOperation(Token::Value::SAR, reg, Strength::WEAK) | 125 .BinaryOperation(Token::Value::SAR, reg) |
126 .BinaryOperation(Token::Value::SHR, reg, Strength::WEAK); | 126 .BinaryOperation(Token::Value::SHR, reg); |
127 | 127 |
128 // Emit count operatior invocations | 128 // Emit count operatior invocations |
129 builder.CountOperation(Token::Value::ADD, Strength::WEAK) | 129 builder.CountOperation(Token::Value::ADD).CountOperation(Token::Value::SUB); |
130 .CountOperation(Token::Value::SUB, Strength::WEAK); | |
131 | 130 |
132 // Emit unary operator invocations. | 131 // Emit unary operator invocations. |
133 builder.LogicalNot().TypeOf(); | 132 builder.LogicalNot().TypeOf(); |
134 | 133 |
135 // Emit delete | 134 // Emit delete |
136 builder.Delete(reg, LanguageMode::SLOPPY).Delete(reg, LanguageMode::STRICT); | 135 builder.Delete(reg, LanguageMode::SLOPPY).Delete(reg, LanguageMode::STRICT); |
137 | 136 |
138 // Emit new. | 137 // Emit new. |
139 builder.New(reg, reg, 0); | 138 builder.New(reg, reg, 0); |
140 builder.New(wide, wide, 0); | 139 builder.New(wide, wide, 0); |
141 | 140 |
142 // Emit test operator invocations. | 141 // Emit test operator invocations. |
143 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK) | 142 builder.CompareOperation(Token::Value::EQ, reg) |
144 .CompareOperation(Token::Value::NE, reg, Strength::WEAK) | 143 .CompareOperation(Token::Value::NE, reg) |
145 .CompareOperation(Token::Value::EQ_STRICT, reg, Strength::WEAK) | 144 .CompareOperation(Token::Value::EQ_STRICT, reg) |
146 .CompareOperation(Token::Value::NE_STRICT, reg, Strength::WEAK) | 145 .CompareOperation(Token::Value::NE_STRICT, reg) |
147 .CompareOperation(Token::Value::LT, reg, Strength::WEAK) | 146 .CompareOperation(Token::Value::LT, reg) |
148 .CompareOperation(Token::Value::GT, reg, Strength::WEAK) | 147 .CompareOperation(Token::Value::GT, reg) |
149 .CompareOperation(Token::Value::LTE, reg, Strength::WEAK) | 148 .CompareOperation(Token::Value::LTE, reg) |
150 .CompareOperation(Token::Value::GTE, reg, Strength::WEAK) | 149 .CompareOperation(Token::Value::GTE, reg) |
151 .CompareOperation(Token::Value::INSTANCEOF, reg, Strength::WEAK) | 150 .CompareOperation(Token::Value::INSTANCEOF, reg) |
152 .CompareOperation(Token::Value::IN, reg, Strength::WEAK); | 151 .CompareOperation(Token::Value::IN, reg); |
153 | 152 |
154 // Emit cast operator invocations. | 153 // Emit cast operator invocations. |
155 builder.CastAccumulatorToNumber() | 154 builder.CastAccumulatorToNumber() |
156 .CastAccumulatorToJSObject() | 155 .CastAccumulatorToJSObject() |
157 .CastAccumulatorToName(); | 156 .CastAccumulatorToName(); |
158 | 157 |
159 // Emit control flow. Return must be the last instruction. | 158 // Emit control flow. Return must be the last instruction. |
160 BytecodeLabel start; | 159 BytecodeLabel start; |
161 builder.Bind(&start); | 160 builder.Bind(&start); |
162 // Short jumps with Imm8 operands | 161 // Short jumps with Imm8 operands |
163 builder.Jump(&start) | 162 builder.Jump(&start) |
164 .JumpIfNull(&start) | 163 .JumpIfNull(&start) |
165 .JumpIfUndefined(&start) | 164 .JumpIfUndefined(&start) |
166 .JumpIfNotHole(&start); | 165 .JumpIfNotHole(&start); |
167 | 166 |
168 // Perform an operation that returns boolean value to | 167 // Perform an operation that returns boolean value to |
169 // generate JumpIfTrue/False | 168 // generate JumpIfTrue/False |
170 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK) | 169 builder.CompareOperation(Token::Value::EQ, reg) |
171 .JumpIfTrue(&start) | 170 .JumpIfTrue(&start) |
172 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK) | 171 .CompareOperation(Token::Value::EQ, reg) |
173 .JumpIfFalse(&start); | 172 .JumpIfFalse(&start); |
174 // Perform an operation that returns a non-boolean operation to | 173 // Perform an operation that returns a non-boolean operation to |
175 // generate JumpIfToBooleanTrue/False. | 174 // generate JumpIfToBooleanTrue/False. |
176 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) | 175 builder.BinaryOperation(Token::Value::ADD, reg) |
177 .JumpIfTrue(&start) | 176 .JumpIfTrue(&start) |
178 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) | 177 .BinaryOperation(Token::Value::ADD, reg) |
179 .JumpIfFalse(&start); | 178 .JumpIfFalse(&start); |
180 // Insert dummy ops to force longer jumps | 179 // Insert dummy ops to force longer jumps |
181 for (int i = 0; i < 128; i++) { | 180 for (int i = 0; i < 128; i++) { |
182 builder.LoadTrue(); | 181 builder.LoadTrue(); |
183 } | 182 } |
184 // Longer jumps requiring Constant operand | 183 // Longer jumps requiring Constant operand |
185 builder.Jump(&start).JumpIfNull(&start).JumpIfUndefined(&start).JumpIfNotHole( | 184 builder.Jump(&start).JumpIfNull(&start).JumpIfUndefined(&start).JumpIfNotHole( |
186 &start); | 185 &start); |
187 // Perform an operation that returns boolean value to | 186 // Perform an operation that returns boolean value to |
188 // generate JumpIfTrue/False | 187 // generate JumpIfTrue/False |
189 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK) | 188 builder.CompareOperation(Token::Value::EQ, reg) |
190 .JumpIfTrue(&start) | 189 .JumpIfTrue(&start) |
191 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK) | 190 .CompareOperation(Token::Value::EQ, reg) |
192 .JumpIfFalse(&start); | 191 .JumpIfFalse(&start); |
193 // Perform an operation that returns a non-boolean operation to | 192 // Perform an operation that returns a non-boolean operation to |
194 // generate JumpIfToBooleanTrue/False. | 193 // generate JumpIfToBooleanTrue/False. |
195 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) | 194 builder.BinaryOperation(Token::Value::ADD, reg) |
196 .JumpIfTrue(&start) | 195 .JumpIfTrue(&start) |
197 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) | 196 .BinaryOperation(Token::Value::ADD, reg) |
198 .JumpIfFalse(&start); | 197 .JumpIfFalse(&start); |
199 | 198 |
200 // Emit stack check bytecode. | 199 // Emit stack check bytecode. |
201 builder.StackCheck(); | 200 builder.StackCheck(); |
202 | 201 |
203 // Emit throw and re-throw in it's own basic block so that the rest of the | 202 // Emit throw and re-throw in it's own basic block so that the rest of the |
204 // code isn't omitted due to being dead. | 203 // code isn't omitted due to being dead. |
205 BytecodeLabel after_throw; | 204 BytecodeLabel after_throw; |
206 builder.Jump(&after_throw).Throw().Bind(&after_throw); | 205 builder.Jump(&after_throw).Throw().Bind(&after_throw); |
207 BytecodeLabel after_rethrow; | 206 BytecodeLabel after_rethrow; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 builder.CreateRegExpLiteral(factory->NewStringFromStaticChars("wide_literal"), | 262 builder.CreateRegExpLiteral(factory->NewStringFromStaticChars("wide_literal"), |
264 0, 0) | 263 0, 0) |
265 .CreateArrayLiteral(factory->NewFixedArray(2), 0, 0) | 264 .CreateArrayLiteral(factory->NewFixedArray(2), 0, 0) |
266 .CreateObjectLiteral(factory->NewFixedArray(2), 0, 0); | 265 .CreateObjectLiteral(factory->NewFixedArray(2), 0, 0); |
267 | 266 |
268 // Longer jumps requiring ConstantWide operand | 267 // Longer jumps requiring ConstantWide operand |
269 builder.Jump(&start).JumpIfNull(&start).JumpIfUndefined(&start).JumpIfNotHole( | 268 builder.Jump(&start).JumpIfNull(&start).JumpIfUndefined(&start).JumpIfNotHole( |
270 &start); | 269 &start); |
271 // Perform an operation that returns boolean value to | 270 // Perform an operation that returns boolean value to |
272 // generate JumpIfTrue/False | 271 // generate JumpIfTrue/False |
273 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK) | 272 builder.CompareOperation(Token::Value::EQ, reg) |
274 .JumpIfTrue(&start) | 273 .JumpIfTrue(&start) |
275 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK) | 274 .CompareOperation(Token::Value::EQ, reg) |
276 .JumpIfFalse(&start); | 275 .JumpIfFalse(&start); |
277 // Perform an operation that returns a non-boolean operation to | 276 // Perform an operation that returns a non-boolean operation to |
278 // generate JumpIfToBooleanTrue/False. | 277 // generate JumpIfToBooleanTrue/False. |
279 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) | 278 builder.BinaryOperation(Token::Value::ADD, reg) |
280 .JumpIfTrue(&start) | 279 .JumpIfTrue(&start) |
281 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) | 280 .BinaryOperation(Token::Value::ADD, reg) |
282 .JumpIfFalse(&start); | 281 .JumpIfFalse(&start); |
283 | 282 |
284 builder.Debugger(); | 283 builder.Debugger(); |
285 | 284 |
286 builder.Return(); | 285 builder.Return(); |
287 | 286 |
288 // Generate BytecodeArray. | 287 // Generate BytecodeArray. |
289 Handle<BytecodeArray> the_array = builder.ToBytecodeArray(); | 288 Handle<BytecodeArray> the_array = builder.ToBytecodeArray(); |
290 CHECK_EQ(the_array->frame_size(), | 289 CHECK_EQ(the_array->frame_size(), |
291 (builder.fixed_and_temporary_register_count() + | 290 (builder.fixed_and_temporary_register_count() + |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 | 404 |
406 TEST_F(BytecodeArrayBuilderTest, ForwardJumps) { | 405 TEST_F(BytecodeArrayBuilderTest, ForwardJumps) { |
407 static const int kFarJumpDistance = 256; | 406 static const int kFarJumpDistance = 256; |
408 | 407 |
409 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1); | 408 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1); |
410 Register reg(0); | 409 Register reg(0); |
411 BytecodeLabel far0, far1, far2, far3, far4; | 410 BytecodeLabel far0, far1, far2, far3, far4; |
412 BytecodeLabel near0, near1, near2, near3, near4; | 411 BytecodeLabel near0, near1, near2, near3, near4; |
413 | 412 |
414 builder.Jump(&near0) | 413 builder.Jump(&near0) |
415 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK) | 414 .CompareOperation(Token::Value::EQ, reg) |
416 .JumpIfTrue(&near1) | 415 .JumpIfTrue(&near1) |
417 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK) | 416 .CompareOperation(Token::Value::EQ, reg) |
418 .JumpIfFalse(&near2) | 417 .JumpIfFalse(&near2) |
419 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) | 418 .BinaryOperation(Token::Value::ADD, reg) |
420 .JumpIfTrue(&near3) | 419 .JumpIfTrue(&near3) |
421 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) | 420 .BinaryOperation(Token::Value::ADD, reg) |
422 .JumpIfFalse(&near4) | 421 .JumpIfFalse(&near4) |
423 .Bind(&near0) | 422 .Bind(&near0) |
424 .Bind(&near1) | 423 .Bind(&near1) |
425 .Bind(&near2) | 424 .Bind(&near2) |
426 .Bind(&near3) | 425 .Bind(&near3) |
427 .Bind(&near4) | 426 .Bind(&near4) |
428 .Jump(&far0) | 427 .Jump(&far0) |
429 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK) | 428 .CompareOperation(Token::Value::EQ, reg) |
430 .JumpIfTrue(&far1) | 429 .JumpIfTrue(&far1) |
431 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK) | 430 .CompareOperation(Token::Value::EQ, reg) |
432 .JumpIfFalse(&far2) | 431 .JumpIfFalse(&far2) |
433 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) | 432 .BinaryOperation(Token::Value::ADD, reg) |
434 .JumpIfTrue(&far3) | 433 .JumpIfTrue(&far3) |
435 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) | 434 .BinaryOperation(Token::Value::ADD, reg) |
436 .JumpIfFalse(&far4); | 435 .JumpIfFalse(&far4); |
437 for (int i = 0; i < kFarJumpDistance - 18; i++) { | 436 for (int i = 0; i < kFarJumpDistance - 18; i++) { |
438 builder.LoadUndefined(); | 437 builder.LoadUndefined(); |
439 } | 438 } |
440 builder.Bind(&far0).Bind(&far1).Bind(&far2).Bind(&far3).Bind(&far4); | 439 builder.Bind(&far0).Bind(&far1).Bind(&far2).Bind(&far3).Bind(&far4); |
441 builder.Return(); | 440 builder.Return(); |
442 | 441 |
443 Handle<BytecodeArray> array = builder.ToBytecodeArray(); | 442 Handle<BytecodeArray> array = builder.ToBytecodeArray(); |
444 DCHECK_EQ(array->length(), 36 + kFarJumpDistance - 18 + 1); | 443 DCHECK_EQ(array->length(), 36 + kFarJumpDistance - 18 + 1); |
445 | 444 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 | 517 |
519 | 518 |
520 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) { | 519 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) { |
521 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1); | 520 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1); |
522 Register reg(0); | 521 Register reg(0); |
523 | 522 |
524 BytecodeLabel label0, label1, label2, label3, label4; | 523 BytecodeLabel label0, label1, label2, label3, label4; |
525 builder.Bind(&label0) | 524 builder.Bind(&label0) |
526 .Jump(&label0) | 525 .Jump(&label0) |
527 .Bind(&label1) | 526 .Bind(&label1) |
528 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK) | 527 .CompareOperation(Token::Value::EQ, reg) |
529 .JumpIfTrue(&label1) | 528 .JumpIfTrue(&label1) |
530 .Bind(&label2) | 529 .Bind(&label2) |
531 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK) | 530 .CompareOperation(Token::Value::EQ, reg) |
532 .JumpIfFalse(&label2) | 531 .JumpIfFalse(&label2) |
533 .Bind(&label3) | 532 .Bind(&label3) |
534 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) | 533 .BinaryOperation(Token::Value::ADD, reg) |
535 .JumpIfTrue(&label3) | 534 .JumpIfTrue(&label3) |
536 .Bind(&label4) | 535 .Bind(&label4) |
537 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) | 536 .BinaryOperation(Token::Value::ADD, reg) |
538 .JumpIfFalse(&label4); | 537 .JumpIfFalse(&label4); |
539 for (int i = 0; i < 63; i++) { | 538 for (int i = 0; i < 63; i++) { |
540 builder.Jump(&label4); | 539 builder.Jump(&label4); |
541 } | 540 } |
542 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) | 541 builder.BinaryOperation(Token::Value::ADD, reg).JumpIfFalse(&label4); |
543 .JumpIfFalse(&label4); | 542 builder.BinaryOperation(Token::Value::ADD, reg).JumpIfTrue(&label3); |
544 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) | 543 builder.CompareOperation(Token::Value::EQ, reg).JumpIfFalse(&label2); |
545 .JumpIfTrue(&label3); | 544 builder.CompareOperation(Token::Value::EQ, reg).JumpIfTrue(&label1); |
546 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK) | |
547 .JumpIfFalse(&label2); | |
548 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK) | |
549 .JumpIfTrue(&label1); | |
550 builder.Jump(&label0); | 545 builder.Jump(&label0); |
551 builder.Return(); | 546 builder.Return(); |
552 | 547 |
553 Handle<BytecodeArray> array = builder.ToBytecodeArray(); | 548 Handle<BytecodeArray> array = builder.ToBytecodeArray(); |
554 BytecodeArrayIterator iterator(array); | 549 BytecodeArrayIterator iterator(array); |
555 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); | 550 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); |
556 CHECK_EQ(iterator.GetImmediateOperand(0), 0); | 551 CHECK_EQ(iterator.GetImmediateOperand(0), 0); |
557 iterator.Advance(); | 552 iterator.Advance(); |
558 // Ignore compare operation. | 553 // Ignore compare operation. |
559 iterator.Advance(); | 554 iterator.Advance(); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 iterator.Advance(); | 655 iterator.Advance(); |
661 } | 656 } |
662 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); | 657 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); |
663 iterator.Advance(); | 658 iterator.Advance(); |
664 CHECK(iterator.done()); | 659 CHECK(iterator.done()); |
665 } | 660 } |
666 | 661 |
667 } // namespace interpreter | 662 } // namespace interpreter |
668 } // namespace internal | 663 } // namespace internal |
669 } // namespace v8 | 664 } // namespace v8 |
OLD | NEW |