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/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/interpreter/bytecode-array-builder.h" | 8 #include "src/interpreter/bytecode-array-builder.h" |
9 #include "src/interpreter/bytecode-array-iterator.h" | 9 #include "src/interpreter/bytecode-array-iterator.h" |
10 #include "src/interpreter/bytecode-label.h" | 10 #include "src/interpreter/bytecode-label.h" |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 // Emit test operator invocations. | 208 // Emit test operator invocations. |
209 builder.CompareOperation(Token::Value::EQ, reg, 1) | 209 builder.CompareOperation(Token::Value::EQ, reg, 1) |
210 .CompareOperation(Token::Value::EQ_STRICT, reg, 2) | 210 .CompareOperation(Token::Value::EQ_STRICT, reg, 2) |
211 .CompareOperation(Token::Value::EQ_STRICT, reg) | 211 .CompareOperation(Token::Value::EQ_STRICT, reg) |
212 .CompareOperation(Token::Value::LT, reg, 3) | 212 .CompareOperation(Token::Value::LT, reg, 3) |
213 .CompareOperation(Token::Value::GT, reg, 4) | 213 .CompareOperation(Token::Value::GT, reg, 4) |
214 .CompareOperation(Token::Value::LTE, reg, 5) | 214 .CompareOperation(Token::Value::LTE, reg, 5) |
215 .CompareOperation(Token::Value::GTE, reg, 6) | 215 .CompareOperation(Token::Value::GTE, reg, 6) |
216 .CompareTypeOf(TestTypeOfFlags::LiteralFlag::kNumber) | 216 .CompareTypeOf(TestTypeOfFlags::LiteralFlag::kNumber) |
217 .CompareOperation(Token::Value::INSTANCEOF, reg) | 217 .CompareOperation(Token::Value::INSTANCEOF, reg) |
218 .CompareOperation(Token::Value::IN, reg); | 218 .CompareOperation(Token::Value::IN, reg) |
| 219 .CompareUndetectable() |
| 220 .CompareUndefined() |
| 221 .CompareNull(); |
219 | 222 |
220 // Emit peephole optimizations of equality with Null or Undefined. | 223 // Emit peephole optimizations of equality with Null or Undefined. |
221 builder.LoadUndefined() | 224 builder.LoadUndefined() |
222 .CompareOperation(Token::Value::EQ, reg, 1) | 225 .CompareOperation(Token::Value::EQ, reg, 1) |
223 .LoadNull() | 226 .LoadNull() |
224 .CompareOperation(Token::Value::EQ, reg, 1) | 227 .CompareOperation(Token::Value::EQ, reg, 1) |
225 .LoadUndefined() | 228 .LoadUndefined() |
226 .CompareOperation(Token::Value::EQ_STRICT, reg, 1) | 229 .CompareOperation(Token::Value::EQ_STRICT, reg, 1) |
227 .LoadNull() | 230 .LoadNull() |
228 .CompareOperation(Token::Value::EQ_STRICT, reg, 1); | 231 .CompareOperation(Token::Value::EQ_STRICT, reg, 1); |
229 | 232 |
230 // Emit conversion operator invocations. | 233 // Emit conversion operator invocations. |
231 builder.ConvertAccumulatorToNumber(reg) | 234 builder.ConvertAccumulatorToNumber(reg) |
232 .ConvertAccumulatorToObject(reg) | 235 .ConvertAccumulatorToObject(reg) |
233 .ConvertAccumulatorToName(reg); | 236 .ConvertAccumulatorToName(reg); |
234 | 237 |
235 // Emit GetSuperConstructor. | 238 // Emit GetSuperConstructor. |
236 builder.GetSuperConstructor(reg); | 239 builder.GetSuperConstructor(reg); |
237 | 240 |
238 // Short jumps with Imm8 operands | 241 // Short jumps with Imm8 operands |
239 { | 242 { |
240 BytecodeLabel start, after_jump1, after_jump2, after_jump3, after_jump4, | 243 BytecodeLabel start, after_jump1, after_jump2, after_jump3, after_jump4, |
241 after_jump5; | 244 after_jump5, after_jump6, after_jump7; |
242 builder.Bind(&start) | 245 builder.Bind(&start) |
243 .Jump(&after_jump1) | 246 .Jump(&after_jump1) |
244 .Bind(&after_jump1) | 247 .Bind(&after_jump1) |
245 .JumpIfNull(&after_jump2) | 248 .JumpIfNull(&after_jump2) |
246 .Bind(&after_jump2) | 249 .Bind(&after_jump2) |
247 .JumpIfUndefined(&after_jump3) | 250 .JumpIfNotNull(&after_jump3) |
248 .Bind(&after_jump3) | 251 .Bind(&after_jump3) |
249 .JumpIfNotHole(&after_jump4) | 252 .JumpIfUndefined(&after_jump4) |
250 .Bind(&after_jump4) | 253 .Bind(&after_jump4) |
251 .JumpIfJSReceiver(&after_jump5) | 254 .JumpIfNotUndefined(&after_jump5) |
252 .Bind(&after_jump5) | 255 .Bind(&after_jump5) |
| 256 .JumpIfNotHole(&after_jump6) |
| 257 .Bind(&after_jump6) |
| 258 .JumpIfJSReceiver(&after_jump7) |
| 259 .Bind(&after_jump7) |
253 .JumpLoop(&start, 0); | 260 .JumpLoop(&start, 0); |
254 } | 261 } |
255 | 262 |
256 // Longer jumps with constant operands | 263 // Longer jumps with constant operands |
257 BytecodeLabel end[9]; | 264 BytecodeLabel end[11]; |
258 { | 265 { |
259 BytecodeLabel after_jump; | 266 BytecodeLabel after_jump; |
260 builder.Jump(&end[0]) | 267 builder.Jump(&end[0]) |
261 .Bind(&after_jump) | 268 .Bind(&after_jump) |
262 .LoadTrue() | 269 .LoadTrue() |
263 .JumpIfTrue(&end[1]) | 270 .JumpIfTrue(&end[1]) |
264 .LoadTrue() | 271 .LoadTrue() |
265 .JumpIfFalse(&end[2]) | 272 .JumpIfFalse(&end[2]) |
266 .LoadLiteral(Smi::kZero) | 273 .LoadLiteral(Smi::kZero) |
267 .JumpIfTrue(&end[3]) | 274 .JumpIfTrue(&end[3]) |
268 .LoadLiteral(Smi::kZero) | 275 .LoadLiteral(Smi::kZero) |
269 .JumpIfFalse(&end[4]) | 276 .JumpIfFalse(&end[4]) |
270 .JumpIfNull(&end[5]) | 277 .JumpIfNull(&end[5]) |
271 .JumpIfUndefined(&end[6]) | 278 .JumpIfNotNull(&end[6]) |
272 .JumpIfNotHole(&end[7]) | 279 .JumpIfUndefined(&end[7]) |
| 280 .JumpIfNotUndefined(&end[8]) |
| 281 .JumpIfNotHole(&end[9]) |
273 .LoadLiteral(ast_factory.prototype_string()) | 282 .LoadLiteral(ast_factory.prototype_string()) |
274 .JumpIfJSReceiver(&end[8]); | 283 .JumpIfJSReceiver(&end[10]); |
275 } | 284 } |
276 | 285 |
277 // Perform an operation that returns boolean value to | 286 // Perform an operation that returns boolean value to |
278 // generate JumpIfTrue/False | 287 // generate JumpIfTrue/False |
279 { | 288 { |
280 BytecodeLabel after_jump1, after_jump2; | 289 BytecodeLabel after_jump1, after_jump2; |
281 builder.CompareOperation(Token::Value::EQ, reg, 1) | 290 builder.CompareOperation(Token::Value::EQ, reg, 1) |
282 .JumpIfTrue(&after_jump1) | 291 .JumpIfTrue(&after_jump1) |
283 .Bind(&after_jump1) | 292 .Bind(&after_jump1) |
284 .CompareOperation(Token::Value::EQ, reg, 2) | 293 .CompareOperation(Token::Value::EQ, reg, 2) |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 scorecard[Bytecodes::ToByte(Bytecode::kJumpIfTrue)] = 1; | 444 scorecard[Bytecodes::ToByte(Bytecode::kJumpIfTrue)] = 1; |
436 scorecard[Bytecodes::ToByte(Bytecode::kJumpIfFalse)] = 1; | 445 scorecard[Bytecodes::ToByte(Bytecode::kJumpIfFalse)] = 1; |
437 scorecard[Bytecodes::ToByte(Bytecode::kJumpIfTrueConstant)] = 1; | 446 scorecard[Bytecodes::ToByte(Bytecode::kJumpIfTrueConstant)] = 1; |
438 scorecard[Bytecodes::ToByte(Bytecode::kJumpIfFalseConstant)] = 1; | 447 scorecard[Bytecodes::ToByte(Bytecode::kJumpIfFalseConstant)] = 1; |
439 scorecard[Bytecodes::ToByte(Bytecode::kAddSmi)] = 1; | 448 scorecard[Bytecodes::ToByte(Bytecode::kAddSmi)] = 1; |
440 scorecard[Bytecodes::ToByte(Bytecode::kSubSmi)] = 1; | 449 scorecard[Bytecodes::ToByte(Bytecode::kSubSmi)] = 1; |
441 scorecard[Bytecodes::ToByte(Bytecode::kBitwiseAndSmi)] = 1; | 450 scorecard[Bytecodes::ToByte(Bytecode::kBitwiseAndSmi)] = 1; |
442 scorecard[Bytecodes::ToByte(Bytecode::kBitwiseOrSmi)] = 1; | 451 scorecard[Bytecodes::ToByte(Bytecode::kBitwiseOrSmi)] = 1; |
443 scorecard[Bytecodes::ToByte(Bytecode::kShiftLeftSmi)] = 1; | 452 scorecard[Bytecodes::ToByte(Bytecode::kShiftLeftSmi)] = 1; |
444 scorecard[Bytecodes::ToByte(Bytecode::kShiftRightSmi)] = 1; | 453 scorecard[Bytecodes::ToByte(Bytecode::kShiftRightSmi)] = 1; |
445 scorecard[Bytecodes::ToByte(Bytecode::kTestUndetectable)] = 1; | |
446 scorecard[Bytecodes::ToByte(Bytecode::kTestUndefined)] = 1; | |
447 scorecard[Bytecodes::ToByte(Bytecode::kTestNull)] = 1; | |
448 } | 454 } |
449 | 455 |
450 if (!FLAG_type_profile) { | 456 if (!FLAG_type_profile) { |
451 // Bytecode for CollectTypeProfile is only emitted when | 457 // Bytecode for CollectTypeProfile is only emitted when |
452 // Type Information for DevTools is turned on. | 458 // Type Information for DevTools is turned on. |
453 scorecard[Bytecodes::ToByte(Bytecode::kCollectTypeProfile)] = 1; | 459 scorecard[Bytecodes::ToByte(Bytecode::kCollectTypeProfile)] = 1; |
454 } | 460 } |
455 | 461 |
456 // Check return occurs at the end and only once in the BytecodeArray. | 462 // Check return occurs at the end and only once in the BytecodeArray. |
457 CHECK_EQ(final_bytecode, Bytecode::kReturn); | 463 CHECK_EQ(final_bytecode, Bytecode::kReturn); |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 iterator.Advance(); | 794 iterator.Advance(); |
789 } | 795 } |
790 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); | 796 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); |
791 iterator.Advance(); | 797 iterator.Advance(); |
792 CHECK(iterator.done()); | 798 CHECK(iterator.done()); |
793 } | 799 } |
794 | 800 |
795 } // namespace interpreter | 801 } // namespace interpreter |
796 } // namespace internal | 802 } // namespace internal |
797 } // namespace v8 | 803 } // namespace v8 |
OLD | NEW |