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

Side by Side Diff: src/interpreter/interpreter.cc

Issue 1998593002: [Interpreter] Inline ToBooleanStub and do some cleanup on unary ops. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 months 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/interpreter.h ('k') | no next file » | 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/interpreter/interpreter.h" 5 #include "src/interpreter/interpreter.h"
6 6
7 #include <fstream> 7 #include <fstream>
8 8
9 #include "src/ast/prettyprinter.h" 9 #include "src/ast/prettyprinter.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 __ Dispatch(); 286 __ Dispatch();
287 } 287 }
288 288
289 void Interpreter::DoLoadConstant(InterpreterAssembler* assembler) { 289 void Interpreter::DoLoadConstant(InterpreterAssembler* assembler) {
290 Node* index = __ BytecodeOperandIdx(0); 290 Node* index = __ BytecodeOperandIdx(0);
291 Node* constant = __ LoadConstantPoolEntry(index); 291 Node* constant = __ LoadConstantPoolEntry(index);
292 __ SetAccumulator(constant); 292 __ SetAccumulator(constant);
293 __ Dispatch(); 293 __ Dispatch();
294 } 294 }
295 295
296
297 // LdaConstant <idx> 296 // LdaConstant <idx>
298 // 297 //
299 // Load constant literal at |idx| in the constant pool into the accumulator. 298 // Load constant literal at |idx| in the constant pool into the accumulator.
300 void Interpreter::DoLdaConstant(InterpreterAssembler* assembler) { 299 void Interpreter::DoLdaConstant(InterpreterAssembler* assembler) {
301 DoLoadConstant(assembler); 300 DoLoadConstant(assembler);
302 } 301 }
303 302
304 // LdaUndefined 303 // LdaUndefined
305 // 304 //
306 // Load Undefined into the accumulator. 305 // Load Undefined into the accumulator.
307 void Interpreter::DoLdaUndefined(InterpreterAssembler* assembler) { 306 void Interpreter::DoLdaUndefined(InterpreterAssembler* assembler) {
308 Node* undefined_value = 307 Node* undefined_value =
309 __ HeapConstant(isolate_->factory()->undefined_value()); 308 __ HeapConstant(isolate_->factory()->undefined_value());
310 __ SetAccumulator(undefined_value); 309 __ SetAccumulator(undefined_value);
311 __ Dispatch(); 310 __ Dispatch();
312 } 311 }
313 312
314
315 // LdaNull 313 // LdaNull
316 // 314 //
317 // Load Null into the accumulator. 315 // Load Null into the accumulator.
318 void Interpreter::DoLdaNull(InterpreterAssembler* assembler) { 316 void Interpreter::DoLdaNull(InterpreterAssembler* assembler) {
319 Node* null_value = __ HeapConstant(isolate_->factory()->null_value()); 317 Node* null_value = __ HeapConstant(isolate_->factory()->null_value());
320 __ SetAccumulator(null_value); 318 __ SetAccumulator(null_value);
321 __ Dispatch(); 319 __ Dispatch();
322 } 320 }
323 321
324
325 // LdaTheHole 322 // LdaTheHole
326 // 323 //
327 // Load TheHole into the accumulator. 324 // Load TheHole into the accumulator.
328 void Interpreter::DoLdaTheHole(InterpreterAssembler* assembler) { 325 void Interpreter::DoLdaTheHole(InterpreterAssembler* assembler) {
329 Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value()); 326 Node* the_hole_value = __ HeapConstant(isolate_->factory()->the_hole_value());
330 __ SetAccumulator(the_hole_value); 327 __ SetAccumulator(the_hole_value);
331 __ Dispatch(); 328 __ Dispatch();
332 } 329 }
333 330
334
335 // LdaTrue 331 // LdaTrue
336 // 332 //
337 // Load True into the accumulator. 333 // Load True into the accumulator.
338 void Interpreter::DoLdaTrue(InterpreterAssembler* assembler) { 334 void Interpreter::DoLdaTrue(InterpreterAssembler* assembler) {
339 Node* true_value = __ HeapConstant(isolate_->factory()->true_value()); 335 Node* true_value = __ HeapConstant(isolate_->factory()->true_value());
340 __ SetAccumulator(true_value); 336 __ SetAccumulator(true_value);
341 __ Dispatch(); 337 __ Dispatch();
342 } 338 }
343 339
344
345 // LdaFalse 340 // LdaFalse
346 // 341 //
347 // Load False into the accumulator. 342 // Load False into the accumulator.
348 void Interpreter::DoLdaFalse(InterpreterAssembler* assembler) { 343 void Interpreter::DoLdaFalse(InterpreterAssembler* assembler) {
349 Node* false_value = __ HeapConstant(isolate_->factory()->false_value()); 344 Node* false_value = __ HeapConstant(isolate_->factory()->false_value());
350 __ SetAccumulator(false_value); 345 __ SetAccumulator(false_value);
351 __ Dispatch(); 346 __ Dispatch();
352 } 347 }
353 348
354
355 // Ldar <src> 349 // Ldar <src>
356 // 350 //
357 // Load accumulator with value from register <src>. 351 // Load accumulator with value from register <src>.
358 void Interpreter::DoLdar(InterpreterAssembler* assembler) { 352 void Interpreter::DoLdar(InterpreterAssembler* assembler) {
359 Node* reg_index = __ BytecodeOperandReg(0); 353 Node* reg_index = __ BytecodeOperandReg(0);
360 Node* value = __ LoadRegister(reg_index); 354 Node* value = __ LoadRegister(reg_index);
361 __ SetAccumulator(value); 355 __ SetAccumulator(value);
362 __ Dispatch(); 356 __ Dispatch();
363 } 357 }
364 358
365
366 // Star <dst> 359 // Star <dst>
367 // 360 //
368 // Store accumulator to register <dst>. 361 // Store accumulator to register <dst>.
369 void Interpreter::DoStar(InterpreterAssembler* assembler) { 362 void Interpreter::DoStar(InterpreterAssembler* assembler) {
370 Node* reg_index = __ BytecodeOperandReg(0); 363 Node* reg_index = __ BytecodeOperandReg(0);
371 Node* accumulator = __ GetAccumulator(); 364 Node* accumulator = __ GetAccumulator();
372 __ StoreRegister(accumulator, reg_index); 365 __ StoreRegister(accumulator, reg_index);
373 __ Dispatch(); 366 __ Dispatch();
374 } 367 }
375 368
376
377 // Mov <src> <dst> 369 // Mov <src> <dst>
378 // 370 //
379 // Stores the value of register <src> to register <dst>. 371 // Stores the value of register <src> to register <dst>.
380 void Interpreter::DoMov(InterpreterAssembler* assembler) { 372 void Interpreter::DoMov(InterpreterAssembler* assembler) {
381 Node* src_index = __ BytecodeOperandReg(0); 373 Node* src_index = __ BytecodeOperandReg(0);
382 Node* src_value = __ LoadRegister(src_index); 374 Node* src_value = __ LoadRegister(src_index);
383 Node* dst_index = __ BytecodeOperandReg(1); 375 Node* dst_index = __ BytecodeOperandReg(1);
384 __ StoreRegister(src_value, dst_index); 376 __ StoreRegister(src_value, dst_index);
385 __ Dispatch(); 377 __ Dispatch();
386 } 378 }
387 379
388
389 void Interpreter::DoLoadGlobal(Callable ic, InterpreterAssembler* assembler) { 380 void Interpreter::DoLoadGlobal(Callable ic, InterpreterAssembler* assembler) {
390 // Get the global object. 381 // Get the global object.
391 Node* context = __ GetContext(); 382 Node* context = __ GetContext();
392 Node* native_context = 383 Node* native_context =
393 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX); 384 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX);
394 Node* global = __ LoadContextSlot(native_context, Context::EXTENSION_INDEX); 385 Node* global = __ LoadContextSlot(native_context, Context::EXTENSION_INDEX);
395 386
396 // Load the global via the LoadIC. 387 // Load the global via the LoadIC.
397 Node* code_target = __ HeapConstant(ic.code()); 388 Node* code_target = __ HeapConstant(ic.code());
398 Node* constant_index = __ BytecodeOperandIdx(0); 389 Node* constant_index = __ BytecodeOperandIdx(0);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 Node* name = __ LoadConstantPoolEntry(constant_index); 430 Node* name = __ LoadConstantPoolEntry(constant_index);
440 Node* value = __ GetAccumulator(); 431 Node* value = __ GetAccumulator();
441 Node* raw_slot = __ BytecodeOperandIdx(1); 432 Node* raw_slot = __ BytecodeOperandIdx(1);
442 Node* smi_slot = __ SmiTag(raw_slot); 433 Node* smi_slot = __ SmiTag(raw_slot);
443 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); 434 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
444 __ CallStub(ic.descriptor(), code_target, context, global, name, value, 435 __ CallStub(ic.descriptor(), code_target, context, global, name, value,
445 smi_slot, type_feedback_vector); 436 smi_slot, type_feedback_vector);
446 __ Dispatch(); 437 __ Dispatch();
447 } 438 }
448 439
449
450 // StaGlobalSloppy <name_index> <slot> 440 // StaGlobalSloppy <name_index> <slot>
451 // 441 //
452 // Store the value in the accumulator into the global with name in constant pool 442 // Store the value in the accumulator into the global with name in constant pool
453 // entry <name_index> using FeedBackVector slot <slot> in sloppy mode. 443 // entry <name_index> using FeedBackVector slot <slot> in sloppy mode.
454 void Interpreter::DoStaGlobalSloppy(InterpreterAssembler* assembler) { 444 void Interpreter::DoStaGlobalSloppy(InterpreterAssembler* assembler) {
455 Callable ic = 445 Callable ic =
456 CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); 446 CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
457 DoStoreGlobal(ic, assembler); 447 DoStoreGlobal(ic, assembler);
458 } 448 }
459 449
460
461 // StaGlobalStrict <name_index> <slot> 450 // StaGlobalStrict <name_index> <slot>
462 // 451 //
463 // Store the value in the accumulator into the global with name in constant pool 452 // Store the value in the accumulator into the global with name in constant pool
464 // entry <name_index> using FeedBackVector slot <slot> in strict mode. 453 // entry <name_index> using FeedBackVector slot <slot> in strict mode.
465 void Interpreter::DoStaGlobalStrict(InterpreterAssembler* assembler) { 454 void Interpreter::DoStaGlobalStrict(InterpreterAssembler* assembler) {
466 Callable ic = 455 Callable ic =
467 CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); 456 CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
468 DoStoreGlobal(ic, assembler); 457 DoStoreGlobal(ic, assembler);
469 } 458 }
470 459
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 } 522 }
534 523
535 // StaLookupSlotSloppy <name_index> 524 // StaLookupSlotSloppy <name_index>
536 // 525 //
537 // Store the object in accumulator to the object with the name in constant 526 // Store the object in accumulator to the object with the name in constant
538 // pool entry |name_index| in sloppy mode. 527 // pool entry |name_index| in sloppy mode.
539 void Interpreter::DoStaLookupSlotSloppy(InterpreterAssembler* assembler) { 528 void Interpreter::DoStaLookupSlotSloppy(InterpreterAssembler* assembler) {
540 DoStoreLookupSlot(LanguageMode::SLOPPY, assembler); 529 DoStoreLookupSlot(LanguageMode::SLOPPY, assembler);
541 } 530 }
542 531
543
544 // StaLookupSlotStrict <name_index> 532 // StaLookupSlotStrict <name_index>
545 // 533 //
546 // Store the object in accumulator to the object with the name in constant 534 // Store the object in accumulator to the object with the name in constant
547 // pool entry |name_index| in strict mode. 535 // pool entry |name_index| in strict mode.
548 void Interpreter::DoStaLookupSlotStrict(InterpreterAssembler* assembler) { 536 void Interpreter::DoStaLookupSlotStrict(InterpreterAssembler* assembler) {
549 DoStoreLookupSlot(LanguageMode::STRICT, assembler); 537 DoStoreLookupSlot(LanguageMode::STRICT, assembler);
550 } 538 }
551 539
552 void Interpreter::DoLoadIC(Callable ic, InterpreterAssembler* assembler) { 540 void Interpreter::DoLoadIC(Callable ic, InterpreterAssembler* assembler) {
553 Node* code_target = __ HeapConstant(ic.code()); 541 Node* code_target = __ HeapConstant(ic.code());
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 Node* value = __ GetAccumulator(); 597 Node* value = __ GetAccumulator();
610 Node* raw_slot = __ BytecodeOperandIdx(2); 598 Node* raw_slot = __ BytecodeOperandIdx(2);
611 Node* smi_slot = __ SmiTag(raw_slot); 599 Node* smi_slot = __ SmiTag(raw_slot);
612 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); 600 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
613 Node* context = __ GetContext(); 601 Node* context = __ GetContext();
614 __ CallStub(ic.descriptor(), code_target, context, object, name, value, 602 __ CallStub(ic.descriptor(), code_target, context, object, name, value,
615 smi_slot, type_feedback_vector); 603 smi_slot, type_feedback_vector);
616 __ Dispatch(); 604 __ Dispatch();
617 } 605 }
618 606
619
620 // StoreICSloppy <object> <name_index> <slot> 607 // StoreICSloppy <object> <name_index> <slot>
621 // 608 //
622 // Calls the sloppy mode StoreIC at FeedBackVector slot <slot> for <object> and 609 // Calls the sloppy mode StoreIC at FeedBackVector slot <slot> for <object> and
623 // the name in constant pool entry <name_index> with the value in the 610 // the name in constant pool entry <name_index> with the value in the
624 // accumulator. 611 // accumulator.
625 void Interpreter::DoStoreICSloppy(InterpreterAssembler* assembler) { 612 void Interpreter::DoStoreICSloppy(InterpreterAssembler* assembler) {
626 Callable ic = 613 Callable ic =
627 CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); 614 CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
628 DoStoreIC(ic, assembler); 615 DoStoreIC(ic, assembler);
629 } 616 }
630 617
631
632 // StoreICStrict <object> <name_index> <slot> 618 // StoreICStrict <object> <name_index> <slot>
633 // 619 //
634 // Calls the strict mode StoreIC at FeedBackVector slot <slot> for <object> and 620 // Calls the strict mode StoreIC at FeedBackVector slot <slot> for <object> and
635 // the name in constant pool entry <name_index> with the value in the 621 // the name in constant pool entry <name_index> with the value in the
636 // accumulator. 622 // accumulator.
637 void Interpreter::DoStoreICStrict(InterpreterAssembler* assembler) { 623 void Interpreter::DoStoreICStrict(InterpreterAssembler* assembler) {
638 Callable ic = 624 Callable ic =
639 CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); 625 CodeFactory::StoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
640 DoStoreIC(ic, assembler); 626 DoStoreIC(ic, assembler);
641 } 627 }
642 628
643 void Interpreter::DoKeyedStoreIC(Callable ic, InterpreterAssembler* assembler) { 629 void Interpreter::DoKeyedStoreIC(Callable ic, InterpreterAssembler* assembler) {
644 Node* code_target = __ HeapConstant(ic.code()); 630 Node* code_target = __ HeapConstant(ic.code());
645 Node* object_reg_index = __ BytecodeOperandReg(0); 631 Node* object_reg_index = __ BytecodeOperandReg(0);
646 Node* object = __ LoadRegister(object_reg_index); 632 Node* object = __ LoadRegister(object_reg_index);
647 Node* name_reg_index = __ BytecodeOperandReg(1); 633 Node* name_reg_index = __ BytecodeOperandReg(1);
648 Node* name = __ LoadRegister(name_reg_index); 634 Node* name = __ LoadRegister(name_reg_index);
649 Node* value = __ GetAccumulator(); 635 Node* value = __ GetAccumulator();
650 Node* raw_slot = __ BytecodeOperandIdx(2); 636 Node* raw_slot = __ BytecodeOperandIdx(2);
651 Node* smi_slot = __ SmiTag(raw_slot); 637 Node* smi_slot = __ SmiTag(raw_slot);
652 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); 638 Node* type_feedback_vector = __ LoadTypeFeedbackVector();
653 Node* context = __ GetContext(); 639 Node* context = __ GetContext();
654 __ CallStub(ic.descriptor(), code_target, context, object, name, value, 640 __ CallStub(ic.descriptor(), code_target, context, object, name, value,
655 smi_slot, type_feedback_vector); 641 smi_slot, type_feedback_vector);
656 __ Dispatch(); 642 __ Dispatch();
657 } 643 }
658 644
659
660 // KeyedStoreICSloppy <object> <key> <slot> 645 // KeyedStoreICSloppy <object> <key> <slot>
661 // 646 //
662 // Calls the sloppy mode KeyStoreIC at FeedBackVector slot <slot> for <object> 647 // Calls the sloppy mode KeyStoreIC at FeedBackVector slot <slot> for <object>
663 // and the key <key> with the value in the accumulator. 648 // and the key <key> with the value in the accumulator.
664 void Interpreter::DoKeyedStoreICSloppy(InterpreterAssembler* assembler) { 649 void Interpreter::DoKeyedStoreICSloppy(InterpreterAssembler* assembler) {
665 Callable ic = 650 Callable ic =
666 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED); 651 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, SLOPPY, UNINITIALIZED);
667 DoKeyedStoreIC(ic, assembler); 652 DoKeyedStoreIC(ic, assembler);
668 } 653 }
669 654
670
671 // KeyedStoreICStore <object> <key> <slot> 655 // KeyedStoreICStore <object> <key> <slot>
672 // 656 //
673 // Calls the strict mode KeyStoreIC at FeedBackVector slot <slot> for <object> 657 // Calls the strict mode KeyStoreIC at FeedBackVector slot <slot> for <object>
674 // and the key <key> with the value in the accumulator. 658 // and the key <key> with the value in the accumulator.
675 void Interpreter::DoKeyedStoreICStrict(InterpreterAssembler* assembler) { 659 void Interpreter::DoKeyedStoreICStrict(InterpreterAssembler* assembler) {
676 Callable ic = 660 Callable ic =
677 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED); 661 CodeFactory::KeyedStoreICInOptimizedCode(isolate_, STRICT, UNINITIALIZED);
678 DoKeyedStoreIC(ic, assembler); 662 DoKeyedStoreIC(ic, assembler);
679 } 663 }
680 664
681 // PushContext <context> 665 // PushContext <context>
682 // 666 //
683 // Saves the current context in <context>, and pushes the accumulator as the 667 // Saves the current context in <context>, and pushes the accumulator as the
684 // new current context. 668 // new current context.
685 void Interpreter::DoPushContext(InterpreterAssembler* assembler) { 669 void Interpreter::DoPushContext(InterpreterAssembler* assembler) {
686 Node* reg_index = __ BytecodeOperandReg(0); 670 Node* reg_index = __ BytecodeOperandReg(0);
687 Node* new_context = __ GetAccumulator(); 671 Node* new_context = __ GetAccumulator();
688 Node* old_context = __ GetContext(); 672 Node* old_context = __ GetContext();
689 __ StoreRegister(old_context, reg_index); 673 __ StoreRegister(old_context, reg_index);
690 __ SetContext(new_context); 674 __ SetContext(new_context);
691 __ Dispatch(); 675 __ Dispatch();
692 } 676 }
693 677
694
695 // PopContext <context> 678 // PopContext <context>
696 // 679 //
697 // Pops the current context and sets <context> as the new context. 680 // Pops the current context and sets <context> as the new context.
698 void Interpreter::DoPopContext(InterpreterAssembler* assembler) { 681 void Interpreter::DoPopContext(InterpreterAssembler* assembler) {
699 Node* reg_index = __ BytecodeOperandReg(0); 682 Node* reg_index = __ BytecodeOperandReg(0);
700 Node* context = __ LoadRegister(reg_index); 683 Node* context = __ LoadRegister(reg_index);
701 __ SetContext(context); 684 __ SetContext(context);
702 __ Dispatch(); 685 __ Dispatch();
703 } 686 }
704 687
705 void Interpreter::DoBinaryOp(Callable callable, 688 void Interpreter::DoBinaryOp(Callable callable,
706 InterpreterAssembler* assembler) { 689 InterpreterAssembler* assembler) {
707 // TODO(bmeurer): Collect definition side type feedback for various 690 // TODO(bmeurer): Collect definition side type feedback for various
708 // binary operations. 691 // binary operations.
709 Node* target = __ HeapConstant(callable.code()); 692 Node* target = __ HeapConstant(callable.code());
710 Node* reg_index = __ BytecodeOperandReg(0); 693 Node* reg_index = __ BytecodeOperandReg(0);
711 Node* lhs = __ LoadRegister(reg_index); 694 Node* lhs = __ LoadRegister(reg_index);
712 Node* rhs = __ GetAccumulator(); 695 Node* rhs = __ GetAccumulator();
713 Node* context = __ GetContext(); 696 Node* context = __ GetContext();
714 Node* result = __ CallStub(callable.descriptor(), target, context, lhs, rhs); 697 Node* result = __ CallStub(callable.descriptor(), target, context, lhs, rhs);
715 __ SetAccumulator(result); 698 __ SetAccumulator(result);
716 __ Dispatch(); 699 __ Dispatch();
717 } 700 }
718 701
719 void Interpreter::DoBinaryOp(Runtime::FunctionId function_id,
720 InterpreterAssembler* assembler) {
721 // TODO(rmcilroy): Call ICs which back-patch bytecode with type specialized
722 // operations, instead of calling builtins directly.
723 Node* reg_index = __ BytecodeOperandReg(0);
724 Node* lhs = __ LoadRegister(reg_index);
725 Node* rhs = __ GetAccumulator();
726 Node* context = __ GetContext();
727 Node* result = __ CallRuntime(function_id, context, lhs, rhs);
728 __ SetAccumulator(result);
729 __ Dispatch();
730 }
731
732 template <class Generator> 702 template <class Generator>
733 void Interpreter::DoBinaryOp(InterpreterAssembler* assembler) { 703 void Interpreter::DoBinaryOp(InterpreterAssembler* assembler) {
734 Node* reg_index = __ BytecodeOperandReg(0); 704 Node* reg_index = __ BytecodeOperandReg(0);
735 Node* lhs = __ LoadRegister(reg_index); 705 Node* lhs = __ LoadRegister(reg_index);
736 Node* rhs = __ GetAccumulator(); 706 Node* rhs = __ GetAccumulator();
737 Node* context = __ GetContext(); 707 Node* context = __ GetContext();
738 Node* result = Generator::Generate(assembler, lhs, rhs, context); 708 Node* result = Generator::Generate(assembler, lhs, rhs, context);
739 __ SetAccumulator(result); 709 __ SetAccumulator(result);
740 __ Dispatch(); 710 __ Dispatch();
741 } 711 }
742 712
743 // Add <src> 713 // Add <src>
744 // 714 //
745 // Add register <src> to accumulator. 715 // Add register <src> to accumulator.
746 void Interpreter::DoAdd(InterpreterAssembler* assembler) { 716 void Interpreter::DoAdd(InterpreterAssembler* assembler) {
747 DoBinaryOp<AddStub>(assembler); 717 DoBinaryOp<AddStub>(assembler);
748 } 718 }
749 719
750
751 // Sub <src> 720 // Sub <src>
752 // 721 //
753 // Subtract register <src> from accumulator. 722 // Subtract register <src> from accumulator.
754 void Interpreter::DoSub(InterpreterAssembler* assembler) { 723 void Interpreter::DoSub(InterpreterAssembler* assembler) {
755 DoBinaryOp<SubtractStub>(assembler); 724 DoBinaryOp<SubtractStub>(assembler);
756 } 725 }
757 726
758
759 // Mul <src> 727 // Mul <src>
760 // 728 //
761 // Multiply accumulator by register <src>. 729 // Multiply accumulator by register <src>.
762 void Interpreter::DoMul(InterpreterAssembler* assembler) { 730 void Interpreter::DoMul(InterpreterAssembler* assembler) {
763 DoBinaryOp<MultiplyStub>(assembler); 731 DoBinaryOp<MultiplyStub>(assembler);
764 } 732 }
765 733
766
767 // Div <src> 734 // Div <src>
768 // 735 //
769 // Divide register <src> by accumulator. 736 // Divide register <src> by accumulator.
770 void Interpreter::DoDiv(InterpreterAssembler* assembler) { 737 void Interpreter::DoDiv(InterpreterAssembler* assembler) {
771 DoBinaryOp<DivideStub>(assembler); 738 DoBinaryOp<DivideStub>(assembler);
772 } 739 }
773 740
774
775 // Mod <src> 741 // Mod <src>
776 // 742 //
777 // Modulo register <src> by accumulator. 743 // Modulo register <src> by accumulator.
778 void Interpreter::DoMod(InterpreterAssembler* assembler) { 744 void Interpreter::DoMod(InterpreterAssembler* assembler) {
779 DoBinaryOp<ModulusStub>(assembler); 745 DoBinaryOp<ModulusStub>(assembler);
780 } 746 }
781 747
782
783 // BitwiseOr <src> 748 // BitwiseOr <src>
784 // 749 //
785 // BitwiseOr register <src> to accumulator. 750 // BitwiseOr register <src> to accumulator.
786 void Interpreter::DoBitwiseOr(InterpreterAssembler* assembler) { 751 void Interpreter::DoBitwiseOr(InterpreterAssembler* assembler) {
787 DoBinaryOp<BitwiseOrStub>(assembler); 752 DoBinaryOp<BitwiseOrStub>(assembler);
788 } 753 }
789 754
790
791 // BitwiseXor <src> 755 // BitwiseXor <src>
792 // 756 //
793 // BitwiseXor register <src> to accumulator. 757 // BitwiseXor register <src> to accumulator.
794 void Interpreter::DoBitwiseXor(InterpreterAssembler* assembler) { 758 void Interpreter::DoBitwiseXor(InterpreterAssembler* assembler) {
795 DoBinaryOp<BitwiseXorStub>(assembler); 759 DoBinaryOp<BitwiseXorStub>(assembler);
796 } 760 }
797 761
798
799 // BitwiseAnd <src> 762 // BitwiseAnd <src>
800 // 763 //
801 // BitwiseAnd register <src> to accumulator. 764 // BitwiseAnd register <src> to accumulator.
802 void Interpreter::DoBitwiseAnd(InterpreterAssembler* assembler) { 765 void Interpreter::DoBitwiseAnd(InterpreterAssembler* assembler) {
803 DoBinaryOp<BitwiseAndStub>(assembler); 766 DoBinaryOp<BitwiseAndStub>(assembler);
804 } 767 }
805 768
806
807 // ShiftLeft <src> 769 // ShiftLeft <src>
808 // 770 //
809 // Left shifts register <src> by the count specified in the accumulator. 771 // Left shifts register <src> by the count specified in the accumulator.
810 // Register <src> is converted to an int32 and the accumulator to uint32 772 // Register <src> is converted to an int32 and the accumulator to uint32
811 // before the operation. 5 lsb bits from the accumulator are used as count 773 // before the operation. 5 lsb bits from the accumulator are used as count
812 // i.e. <src> << (accumulator & 0x1F). 774 // i.e. <src> << (accumulator & 0x1F).
813 void Interpreter::DoShiftLeft(InterpreterAssembler* assembler) { 775 void Interpreter::DoShiftLeft(InterpreterAssembler* assembler) {
814 DoBinaryOp<ShiftLeftStub>(assembler); 776 DoBinaryOp<ShiftLeftStub>(assembler);
815 } 777 }
816 778
817
818 // ShiftRight <src> 779 // ShiftRight <src>
819 // 780 //
820 // Right shifts register <src> by the count specified in the accumulator. 781 // Right shifts register <src> by the count specified in the accumulator.
821 // Result is sign extended. Register <src> is converted to an int32 and the 782 // Result is sign extended. Register <src> is converted to an int32 and the
822 // accumulator to uint32 before the operation. 5 lsb bits from the accumulator 783 // accumulator to uint32 before the operation. 5 lsb bits from the accumulator
823 // are used as count i.e. <src> >> (accumulator & 0x1F). 784 // are used as count i.e. <src> >> (accumulator & 0x1F).
824 void Interpreter::DoShiftRight(InterpreterAssembler* assembler) { 785 void Interpreter::DoShiftRight(InterpreterAssembler* assembler) {
825 DoBinaryOp<ShiftRightStub>(assembler); 786 DoBinaryOp<ShiftRightStub>(assembler);
826 } 787 }
827 788
828
829 // ShiftRightLogical <src> 789 // ShiftRightLogical <src>
830 // 790 //
831 // Right Shifts register <src> by the count specified in the accumulator. 791 // Right Shifts register <src> by the count specified in the accumulator.
832 // Result is zero-filled. The accumulator and register <src> are converted to 792 // Result is zero-filled. The accumulator and register <src> are converted to
833 // uint32 before the operation 5 lsb bits from the accumulator are used as 793 // uint32 before the operation 5 lsb bits from the accumulator are used as
834 // count i.e. <src> << (accumulator & 0x1F). 794 // count i.e. <src> << (accumulator & 0x1F).
835 void Interpreter::DoShiftRightLogical(InterpreterAssembler* assembler) { 795 void Interpreter::DoShiftRightLogical(InterpreterAssembler* assembler) {
836 DoBinaryOp<ShiftRightLogicalStub>(assembler); 796 DoBinaryOp<ShiftRightLogicalStub>(assembler);
837 } 797 }
838 798
799 void Interpreter::DoUnaryOp(Callable callable,
800 InterpreterAssembler* assembler) {
801 Node* target = __ HeapConstant(callable.code());
802 Node* accumulator = __ GetAccumulator();
803 Node* context = __ GetContext();
804 Node* result =
805 __ CallStub(callable.descriptor(), target, context, accumulator);
806 __ SetAccumulator(result);
807 __ Dispatch();
808 }
809
839 template <class Generator> 810 template <class Generator>
840 void Interpreter::DoUnaryOp(InterpreterAssembler* assembler) { 811 void Interpreter::DoUnaryOp(InterpreterAssembler* assembler) {
841 Node* value = __ GetAccumulator(); 812 Node* value = __ GetAccumulator();
842 Node* context = __ GetContext(); 813 Node* context = __ GetContext();
843 Node* result = Generator::Generate(assembler, value, context); 814 Node* result = Generator::Generate(assembler, value, context);
844 __ SetAccumulator(result); 815 __ SetAccumulator(result);
845 __ Dispatch(); 816 __ Dispatch();
846 } 817 }
847 818
819 // ToName
820 //
821 // Cast the object referenced by the accumulator to a name.
822 void Interpreter::DoToName(InterpreterAssembler* assembler) {
823 DoUnaryOp(CodeFactory::ToName(isolate_), assembler);
824 }
825
826 // ToNumber
827 //
828 // Cast the object referenced by the accumulator to a number.
829 void Interpreter::DoToNumber(InterpreterAssembler* assembler) {
830 DoUnaryOp(CodeFactory::ToNumber(isolate_), assembler);
831 }
832
833 // ToObject
834 //
835 // Cast the object referenced by the accumulator to a JSObject.
836 void Interpreter::DoToObject(InterpreterAssembler* assembler) {
837 DoUnaryOp(CodeFactory::ToObject(isolate_), assembler);
838 }
839
848 // Inc 840 // Inc
849 // 841 //
850 // Increments value in the accumulator by one. 842 // Increments value in the accumulator by one.
851 void Interpreter::DoInc(InterpreterAssembler* assembler) { 843 void Interpreter::DoInc(InterpreterAssembler* assembler) {
852 DoUnaryOp<IncStub>(assembler); 844 DoUnaryOp<IncStub>(assembler);
853 } 845 }
854 846
855 // Dec 847 // Dec
856 // 848 //
857 // Decrements value in the accumulator by one. 849 // Decrements value in the accumulator by one.
858 void Interpreter::DoDec(InterpreterAssembler* assembler) { 850 void Interpreter::DoDec(InterpreterAssembler* assembler) {
859 DoUnaryOp<DecStub>(assembler); 851 DoUnaryOp<DecStub>(assembler);
860 } 852 }
861 853
862 void Interpreter::DoLogicalNotOp(Node* value, InterpreterAssembler* assembler) { 854 Node* Interpreter::BuildToBoolean(Node* value,
855 InterpreterAssembler* assembler) {
856 Node* context = __ GetContext();
857 return ToBooleanStub::Generate(assembler, value, context);
858 }
859
860 Node* Interpreter::BuildLogicalNot(Node* value,
861 InterpreterAssembler* assembler) {
862 Variable result(assembler, MachineRepresentation::kTagged);
863 Label if_true(assembler), if_false(assembler), end(assembler); 863 Label if_true(assembler), if_false(assembler), end(assembler);
864 Node* true_value = __ BooleanConstant(true); 864 Node* true_value = __ BooleanConstant(true);
865 Node* false_value = __ BooleanConstant(false); 865 Node* false_value = __ BooleanConstant(false);
866 __ BranchIfWordEqual(value, true_value, &if_true, &if_false); 866 __ BranchIfWordEqual(value, true_value, &if_true, &if_false);
867 __ Bind(&if_true); 867 __ Bind(&if_true);
868 { 868 {
869 __ SetAccumulator(false_value); 869 result.Bind(false_value);
870 __ Goto(&end); 870 __ Goto(&end);
871 } 871 }
872 __ Bind(&if_false); 872 __ Bind(&if_false);
873 { 873 {
874 if (FLAG_debug_code) { 874 if (FLAG_debug_code) {
875 __ AbortIfWordNotEqual(value, false_value, 875 __ AbortIfWordNotEqual(value, false_value,
876 BailoutReason::kExpectedBooleanValue); 876 BailoutReason::kExpectedBooleanValue);
877 } 877 }
878 __ SetAccumulator(true_value); 878 result.Bind(true_value);
879 __ Goto(&end); 879 __ Goto(&end);
880 } 880 }
881 __ Bind(&end); 881 __ Bind(&end);
882 return result.value();
882 } 883 }
883 884
884 // ToBooleanLogicalNot 885 // LogicalNot
885 // 886 //
886 // Perform logical-not on the accumulator, first casting the 887 // Perform logical-not on the accumulator, first casting the
887 // accumulator to a boolean value if required. 888 // accumulator to a boolean value if required.
889 // ToBooleanLogicalNot
888 void Interpreter::DoToBooleanLogicalNot(InterpreterAssembler* assembler) { 890 void Interpreter::DoToBooleanLogicalNot(InterpreterAssembler* assembler) {
889 Callable callable = CodeFactory::ToBoolean(isolate_); 891 Node* value = __ GetAccumulator();
890 Node* target = __ HeapConstant(callable.code()); 892 Node* to_boolean_value = BuildToBoolean(value, assembler);
891 Node* accumulator = __ GetAccumulator(); 893 Node* result = BuildLogicalNot(to_boolean_value, assembler);
892 Node* context = __ GetContext(); 894 __ SetAccumulator(result);
893 Node* to_boolean_value =
894 __ CallStub(callable.descriptor(), target, context, accumulator);
895 DoLogicalNotOp(to_boolean_value, assembler);
896 __ Dispatch(); 895 __ Dispatch();
897 } 896 }
898 897
899 // LogicalNot 898 // LogicalNot
900 // 899 //
901 // Perform logical-not on the accumulator, which must already be a boolean 900 // Perform logical-not on the accumulator, which must already be a boolean
902 // value. 901 // value.
903 void Interpreter::DoLogicalNot(InterpreterAssembler* assembler) { 902 void Interpreter::DoLogicalNot(InterpreterAssembler* assembler) {
904 Node* value = __ GetAccumulator(); 903 Node* value = __ GetAccumulator();
905 DoLogicalNotOp(value, assembler); 904 Node* result = BuildLogicalNot(value, assembler);
905 __ SetAccumulator(result);
906 __ Dispatch(); 906 __ Dispatch();
907 } 907 }
908 908
909 // TypeOf 909 // TypeOf
910 // 910 //
911 // Load the accumulator with the string representating type of the 911 // Load the accumulator with the string representating type of the
912 // object in the accumulator. 912 // object in the accumulator.
913 void Interpreter::DoTypeOf(InterpreterAssembler* assembler) { 913 void Interpreter::DoTypeOf(InterpreterAssembler* assembler) {
914 Callable callable = CodeFactory::Typeof(isolate_); 914 DoUnaryOp(CodeFactory::Typeof(isolate_), assembler);
915 Node* target = __ HeapConstant(callable.code());
916 Node* accumulator = __ GetAccumulator();
917 Node* context = __ GetContext();
918 Node* result =
919 __ CallStub(callable.descriptor(), target, context, accumulator);
920 __ SetAccumulator(result);
921 __ Dispatch();
922 } 915 }
923 916
924 void Interpreter::DoDelete(Runtime::FunctionId function_id, 917 void Interpreter::DoDelete(Runtime::FunctionId function_id,
925 InterpreterAssembler* assembler) { 918 InterpreterAssembler* assembler) {
926 Node* reg_index = __ BytecodeOperandReg(0); 919 Node* reg_index = __ BytecodeOperandReg(0);
927 Node* object = __ LoadRegister(reg_index); 920 Node* object = __ LoadRegister(reg_index);
928 Node* key = __ GetAccumulator(); 921 Node* key = __ GetAccumulator();
929 Node* context = __ GetContext(); 922 Node* context = __ GetContext();
930 Node* result = __ CallRuntime(function_id, context, object, key); 923 Node* result = __ CallRuntime(function_id, context, object, key);
931 __ SetAccumulator(result); 924 __ SetAccumulator(result);
932 __ Dispatch(); 925 __ Dispatch();
933 } 926 }
934 927
935
936 // DeletePropertyStrict 928 // DeletePropertyStrict
937 // 929 //
938 // Delete the property specified in the accumulator from the object 930 // Delete the property specified in the accumulator from the object
939 // referenced by the register operand following strict mode semantics. 931 // referenced by the register operand following strict mode semantics.
940 void Interpreter::DoDeletePropertyStrict(InterpreterAssembler* assembler) { 932 void Interpreter::DoDeletePropertyStrict(InterpreterAssembler* assembler) {
941 DoDelete(Runtime::kDeleteProperty_Strict, assembler); 933 DoDelete(Runtime::kDeleteProperty_Strict, assembler);
942 } 934 }
943 935
944
945 // DeletePropertySloppy 936 // DeletePropertySloppy
946 // 937 //
947 // Delete the property specified in the accumulator from the object 938 // Delete the property specified in the accumulator from the object
948 // referenced by the register operand following sloppy mode semantics. 939 // referenced by the register operand following sloppy mode semantics.
949 void Interpreter::DoDeletePropertySloppy(InterpreterAssembler* assembler) { 940 void Interpreter::DoDeletePropertySloppy(InterpreterAssembler* assembler) {
950 DoDelete(Runtime::kDeleteProperty_Sloppy, assembler); 941 DoDelete(Runtime::kDeleteProperty_Sloppy, assembler);
951 } 942 }
952 943
953 void Interpreter::DoJSCall(InterpreterAssembler* assembler, 944 void Interpreter::DoJSCall(InterpreterAssembler* assembler,
954 TailCallMode tail_call_mode) { 945 TailCallMode tail_call_mode) {
955 Node* function_reg = __ BytecodeOperandReg(0); 946 Node* function_reg = __ BytecodeOperandReg(0);
956 Node* function = __ LoadRegister(function_reg); 947 Node* function = __ LoadRegister(function_reg);
957 Node* receiver_reg = __ BytecodeOperandReg(1); 948 Node* receiver_reg = __ BytecodeOperandReg(1);
958 Node* receiver_arg = __ RegisterLocation(receiver_reg); 949 Node* receiver_arg = __ RegisterLocation(receiver_reg);
959 Node* receiver_args_count = __ BytecodeOperandCount(2); 950 Node* receiver_args_count = __ BytecodeOperandCount(2);
960 Node* receiver_count = __ Int32Constant(1); 951 Node* receiver_count = __ Int32Constant(1);
961 Node* args_count = __ Int32Sub(receiver_args_count, receiver_count); 952 Node* args_count = __ Int32Sub(receiver_args_count, receiver_count);
962 Node* context = __ GetContext(); 953 Node* context = __ GetContext();
963 // TODO(rmcilroy): Use the call type feedback slot to call via CallStub. 954 // TODO(rmcilroy): Use the call type feedback slot to call via CallStub.
964 Node* result = 955 Node* result =
965 __ CallJS(function, context, receiver_arg, args_count, tail_call_mode); 956 __ CallJS(function, context, receiver_arg, args_count, tail_call_mode);
966 __ SetAccumulator(result); 957 __ SetAccumulator(result);
967 __ Dispatch(); 958 __ Dispatch();
968 } 959 }
969 960
970
971 // Call <callable> <receiver> <arg_count> 961 // Call <callable> <receiver> <arg_count>
972 // 962 //
973 // Call a JSfunction or Callable in |callable| with the |receiver| and 963 // Call a JSfunction or Callable in |callable| with the |receiver| and
974 // |arg_count| arguments in subsequent registers. 964 // |arg_count| arguments in subsequent registers.
975 void Interpreter::DoCall(InterpreterAssembler* assembler) { 965 void Interpreter::DoCall(InterpreterAssembler* assembler) {
976 DoJSCall(assembler, TailCallMode::kDisallow); 966 DoJSCall(assembler, TailCallMode::kDisallow);
977 } 967 }
978 968
979 // TailCall <callable> <receiver> <arg_count> 969 // TailCall <callable> <receiver> <arg_count>
980 // 970 //
981 // Tail call a JSfunction or Callable in |callable| with the |receiver| and 971 // Tail call a JSfunction or Callable in |callable| with the |receiver| and
982 // |arg_count| arguments in subsequent registers. 972 // |arg_count| arguments in subsequent registers.
983 void Interpreter::DoTailCall(InterpreterAssembler* assembler) { 973 void Interpreter::DoTailCall(InterpreterAssembler* assembler) {
984 DoJSCall(assembler, TailCallMode::kAllow); 974 DoJSCall(assembler, TailCallMode::kAllow);
985 } 975 }
986 976
987 void Interpreter::DoCallRuntimeCommon(InterpreterAssembler* assembler) { 977 void Interpreter::DoCallRuntimeCommon(InterpreterAssembler* assembler) {
988 Node* function_id = __ BytecodeOperandRuntimeId(0); 978 Node* function_id = __ BytecodeOperandRuntimeId(0);
989 Node* first_arg_reg = __ BytecodeOperandReg(1); 979 Node* first_arg_reg = __ BytecodeOperandReg(1);
990 Node* first_arg = __ RegisterLocation(first_arg_reg); 980 Node* first_arg = __ RegisterLocation(first_arg_reg);
991 Node* args_count = __ BytecodeOperandCount(2); 981 Node* args_count = __ BytecodeOperandCount(2);
992 Node* context = __ GetContext(); 982 Node* context = __ GetContext();
993 Node* result = __ CallRuntimeN(function_id, context, first_arg, args_count); 983 Node* result = __ CallRuntimeN(function_id, context, first_arg, args_count);
994 __ SetAccumulator(result); 984 __ SetAccumulator(result);
995 __ Dispatch(); 985 __ Dispatch();
996 } 986 }
997 987
998
999 // CallRuntime <function_id> <first_arg> <arg_count> 988 // CallRuntime <function_id> <first_arg> <arg_count>
1000 // 989 //
1001 // Call the runtime function |function_id| with the first argument in 990 // Call the runtime function |function_id| with the first argument in
1002 // register |first_arg| and |arg_count| arguments in subsequent 991 // register |first_arg| and |arg_count| arguments in subsequent
1003 // registers. 992 // registers.
1004 void Interpreter::DoCallRuntime(InterpreterAssembler* assembler) { 993 void Interpreter::DoCallRuntime(InterpreterAssembler* assembler) {
1005 DoCallRuntimeCommon(assembler); 994 DoCallRuntimeCommon(assembler);
1006 } 995 }
1007 996
1008 // InvokeIntrinsic <function_id> <first_arg> <arg_count> 997 // InvokeIntrinsic <function_id> <first_arg> <arg_count>
(...skipping 26 matching lines...) Expand all
1035 // Store the results in <first_return> and <first_return + 1> 1024 // Store the results in <first_return> and <first_return + 1>
1036 Node* first_return_reg = __ BytecodeOperandReg(3); 1025 Node* first_return_reg = __ BytecodeOperandReg(3);
1037 Node* second_return_reg = __ NextRegister(first_return_reg); 1026 Node* second_return_reg = __ NextRegister(first_return_reg);
1038 Node* result0 = __ Projection(0, result_pair); 1027 Node* result0 = __ Projection(0, result_pair);
1039 Node* result1 = __ Projection(1, result_pair); 1028 Node* result1 = __ Projection(1, result_pair);
1040 __ StoreRegister(result0, first_return_reg); 1029 __ StoreRegister(result0, first_return_reg);
1041 __ StoreRegister(result1, second_return_reg); 1030 __ StoreRegister(result1, second_return_reg);
1042 __ Dispatch(); 1031 __ Dispatch();
1043 } 1032 }
1044 1033
1045
1046 // CallRuntimeForPair <function_id> <first_arg> <arg_count> <first_return> 1034 // CallRuntimeForPair <function_id> <first_arg> <arg_count> <first_return>
1047 // 1035 //
1048 // Call the runtime function |function_id| which returns a pair, with the 1036 // Call the runtime function |function_id| which returns a pair, with the
1049 // first argument in register |first_arg| and |arg_count| arguments in 1037 // first argument in register |first_arg| and |arg_count| arguments in
1050 // subsequent registers. Returns the result in <first_return> and 1038 // subsequent registers. Returns the result in <first_return> and
1051 // <first_return + 1> 1039 // <first_return + 1>
1052 void Interpreter::DoCallRuntimeForPair(InterpreterAssembler* assembler) { 1040 void Interpreter::DoCallRuntimeForPair(InterpreterAssembler* assembler) {
1053 DoCallRuntimeForPairCommon(assembler); 1041 DoCallRuntimeForPairCommon(assembler);
1054 } 1042 }
1055 1043
(...skipping 11 matching lines...) Expand all
1067 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX); 1055 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX);
1068 Node* function = __ LoadContextSlot(native_context, context_index); 1056 Node* function = __ LoadContextSlot(native_context, context_index);
1069 1057
1070 // Call the function. 1058 // Call the function.
1071 Node* result = __ CallJS(function, context, first_arg, args_count, 1059 Node* result = __ CallJS(function, context, first_arg, args_count,
1072 TailCallMode::kDisallow); 1060 TailCallMode::kDisallow);
1073 __ SetAccumulator(result); 1061 __ SetAccumulator(result);
1074 __ Dispatch(); 1062 __ Dispatch();
1075 } 1063 }
1076 1064
1077
1078 // CallJSRuntime <context_index> <receiver> <arg_count> 1065 // CallJSRuntime <context_index> <receiver> <arg_count>
1079 // 1066 //
1080 // Call the JS runtime function that has the |context_index| with the receiver 1067 // Call the JS runtime function that has the |context_index| with the receiver
1081 // in register |receiver| and |arg_count| arguments in subsequent registers. 1068 // in register |receiver| and |arg_count| arguments in subsequent registers.
1082 void Interpreter::DoCallJSRuntime(InterpreterAssembler* assembler) { 1069 void Interpreter::DoCallJSRuntime(InterpreterAssembler* assembler) {
1083 DoCallJSRuntimeCommon(assembler); 1070 DoCallJSRuntimeCommon(assembler);
1084 } 1071 }
1085 1072
1086 void Interpreter::DoCallConstruct(InterpreterAssembler* assembler) { 1073 void Interpreter::DoCallConstruct(InterpreterAssembler* assembler) {
1087 Callable ic = CodeFactory::InterpreterPushArgsAndConstruct(isolate_); 1074 Callable ic = CodeFactory::InterpreterPushArgsAndConstruct(isolate_);
1088 Node* new_target = __ GetAccumulator(); 1075 Node* new_target = __ GetAccumulator();
1089 Node* constructor_reg = __ BytecodeOperandReg(0); 1076 Node* constructor_reg = __ BytecodeOperandReg(0);
1090 Node* constructor = __ LoadRegister(constructor_reg); 1077 Node* constructor = __ LoadRegister(constructor_reg);
1091 Node* first_arg_reg = __ BytecodeOperandReg(1); 1078 Node* first_arg_reg = __ BytecodeOperandReg(1);
1092 Node* first_arg = __ RegisterLocation(first_arg_reg); 1079 Node* first_arg = __ RegisterLocation(first_arg_reg);
1093 Node* args_count = __ BytecodeOperandCount(2); 1080 Node* args_count = __ BytecodeOperandCount(2);
1094 Node* context = __ GetContext(); 1081 Node* context = __ GetContext();
1095 Node* result = 1082 Node* result =
1096 __ CallConstruct(constructor, context, new_target, first_arg, args_count); 1083 __ CallConstruct(constructor, context, new_target, first_arg, args_count);
1097 __ SetAccumulator(result); 1084 __ SetAccumulator(result);
1098 __ Dispatch(); 1085 __ Dispatch();
1099 } 1086 }
1100 1087
1101
1102 // New <constructor> <first_arg> <arg_count> 1088 // New <constructor> <first_arg> <arg_count>
1103 // 1089 //
1104 // Call operator new with |constructor| and the first argument in 1090 // Call operator new with |constructor| and the first argument in
1105 // register |first_arg| and |arg_count| arguments in subsequent 1091 // register |first_arg| and |arg_count| arguments in subsequent
1106 // registers. The new.target is in the accumulator. 1092 // registers. The new.target is in the accumulator.
1107 // 1093 //
1108 void Interpreter::DoNew(InterpreterAssembler* assembler) { 1094 void Interpreter::DoNew(InterpreterAssembler* assembler) {
1109 DoCallConstruct(assembler); 1095 DoCallConstruct(assembler);
1110 } 1096 }
1111 1097
1112 // TestEqual <src> 1098 // TestEqual <src>
1113 // 1099 //
1114 // Test if the value in the <src> register equals the accumulator. 1100 // Test if the value in the <src> register equals the accumulator.
1115 void Interpreter::DoTestEqual(InterpreterAssembler* assembler) { 1101 void Interpreter::DoTestEqual(InterpreterAssembler* assembler) {
1116 DoBinaryOp(CodeFactory::Equal(isolate_), assembler); 1102 DoBinaryOp(CodeFactory::Equal(isolate_), assembler);
1117 } 1103 }
1118 1104
1119
1120 // TestNotEqual <src> 1105 // TestNotEqual <src>
1121 // 1106 //
1122 // Test if the value in the <src> register is not equal to the accumulator. 1107 // Test if the value in the <src> register is not equal to the accumulator.
1123 void Interpreter::DoTestNotEqual(InterpreterAssembler* assembler) { 1108 void Interpreter::DoTestNotEqual(InterpreterAssembler* assembler) {
1124 DoBinaryOp(CodeFactory::NotEqual(isolate_), assembler); 1109 DoBinaryOp(CodeFactory::NotEqual(isolate_), assembler);
1125 } 1110 }
1126 1111
1127
1128 // TestEqualStrict <src> 1112 // TestEqualStrict <src>
1129 // 1113 //
1130 // Test if the value in the <src> register is strictly equal to the accumulator. 1114 // Test if the value in the <src> register is strictly equal to the accumulator.
1131 void Interpreter::DoTestEqualStrict(InterpreterAssembler* assembler) { 1115 void Interpreter::DoTestEqualStrict(InterpreterAssembler* assembler) {
1132 DoBinaryOp(CodeFactory::StrictEqual(isolate_), assembler); 1116 DoBinaryOp(CodeFactory::StrictEqual(isolate_), assembler);
1133 } 1117 }
1134 1118
1135
1136 // TestLessThan <src> 1119 // TestLessThan <src>
1137 // 1120 //
1138 // Test if the value in the <src> register is less than the accumulator. 1121 // Test if the value in the <src> register is less than the accumulator.
1139 void Interpreter::DoTestLessThan(InterpreterAssembler* assembler) { 1122 void Interpreter::DoTestLessThan(InterpreterAssembler* assembler) {
1140 DoBinaryOp(CodeFactory::LessThan(isolate_), assembler); 1123 DoBinaryOp(CodeFactory::LessThan(isolate_), assembler);
1141 } 1124 }
1142 1125
1143
1144 // TestGreaterThan <src> 1126 // TestGreaterThan <src>
1145 // 1127 //
1146 // Test if the value in the <src> register is greater than the accumulator. 1128 // Test if the value in the <src> register is greater than the accumulator.
1147 void Interpreter::DoTestGreaterThan(InterpreterAssembler* assembler) { 1129 void Interpreter::DoTestGreaterThan(InterpreterAssembler* assembler) {
1148 DoBinaryOp(CodeFactory::GreaterThan(isolate_), assembler); 1130 DoBinaryOp(CodeFactory::GreaterThan(isolate_), assembler);
1149 } 1131 }
1150 1132
1151
1152 // TestLessThanOrEqual <src> 1133 // TestLessThanOrEqual <src>
1153 // 1134 //
1154 // Test if the value in the <src> register is less than or equal to the 1135 // Test if the value in the <src> register is less than or equal to the
1155 // accumulator. 1136 // accumulator.
1156 void Interpreter::DoTestLessThanOrEqual(InterpreterAssembler* assembler) { 1137 void Interpreter::DoTestLessThanOrEqual(InterpreterAssembler* assembler) {
1157 DoBinaryOp(CodeFactory::LessThanOrEqual(isolate_), assembler); 1138 DoBinaryOp(CodeFactory::LessThanOrEqual(isolate_), assembler);
1158 } 1139 }
1159 1140
1160
1161 // TestGreaterThanOrEqual <src> 1141 // TestGreaterThanOrEqual <src>
1162 // 1142 //
1163 // Test if the value in the <src> register is greater than or equal to the 1143 // Test if the value in the <src> register is greater than or equal to the
1164 // accumulator. 1144 // accumulator.
1165 void Interpreter::DoTestGreaterThanOrEqual(InterpreterAssembler* assembler) { 1145 void Interpreter::DoTestGreaterThanOrEqual(InterpreterAssembler* assembler) {
1166 DoBinaryOp(CodeFactory::GreaterThanOrEqual(isolate_), assembler); 1146 DoBinaryOp(CodeFactory::GreaterThanOrEqual(isolate_), assembler);
1167 } 1147 }
1168 1148
1169
1170 // TestIn <src> 1149 // TestIn <src>
1171 // 1150 //
1172 // Test if the object referenced by the register operand is a property of the 1151 // Test if the object referenced by the register operand is a property of the
1173 // object referenced by the accumulator. 1152 // object referenced by the accumulator.
1174 void Interpreter::DoTestIn(InterpreterAssembler* assembler) { 1153 void Interpreter::DoTestIn(InterpreterAssembler* assembler) {
1175 DoBinaryOp(CodeFactory::HasProperty(isolate_), assembler); 1154 DoBinaryOp(CodeFactory::HasProperty(isolate_), assembler);
1176 } 1155 }
1177 1156
1178
1179 // TestInstanceOf <src> 1157 // TestInstanceOf <src>
1180 // 1158 //
1181 // Test if the object referenced by the <src> register is an an instance of type 1159 // Test if the object referenced by the <src> register is an an instance of type
1182 // referenced by the accumulator. 1160 // referenced by the accumulator.
1183 void Interpreter::DoTestInstanceOf(InterpreterAssembler* assembler) { 1161 void Interpreter::DoTestInstanceOf(InterpreterAssembler* assembler) {
1184 DoBinaryOp(CodeFactory::InstanceOf(isolate_), assembler); 1162 DoBinaryOp(CodeFactory::InstanceOf(isolate_), assembler);
1185 } 1163 }
1186 1164
1187 void Interpreter::DoTypeConversionOp(Callable callable,
1188 InterpreterAssembler* assembler) {
1189 Node* target = __ HeapConstant(callable.code());
1190 Node* accumulator = __ GetAccumulator();
1191 Node* context = __ GetContext();
1192 Node* result =
1193 __ CallStub(callable.descriptor(), target, context, accumulator);
1194 __ SetAccumulator(result);
1195 __ Dispatch();
1196 }
1197
1198 // ToName
1199 //
1200 // Cast the object referenced by the accumulator to a name.
1201 void Interpreter::DoToName(InterpreterAssembler* assembler) {
1202 DoTypeConversionOp(CodeFactory::ToName(isolate_), assembler);
1203 }
1204
1205
1206 // ToNumber
1207 //
1208 // Cast the object referenced by the accumulator to a number.
1209 void Interpreter::DoToNumber(InterpreterAssembler* assembler) {
1210 DoTypeConversionOp(CodeFactory::ToNumber(isolate_), assembler);
1211 }
1212
1213
1214 // ToObject
1215 //
1216 // Cast the object referenced by the accumulator to a JSObject.
1217 void Interpreter::DoToObject(InterpreterAssembler* assembler) {
1218 DoTypeConversionOp(CodeFactory::ToObject(isolate_), assembler);
1219 }
1220
1221 // Jump <imm> 1165 // Jump <imm>
1222 // 1166 //
1223 // Jump by number of bytes represented by the immediate operand |imm|. 1167 // Jump by number of bytes represented by the immediate operand |imm|.
1224 void Interpreter::DoJump(InterpreterAssembler* assembler) { 1168 void Interpreter::DoJump(InterpreterAssembler* assembler) {
1225 Node* relative_jump = __ BytecodeOperandImm(0); 1169 Node* relative_jump = __ BytecodeOperandImm(0);
1226 __ Jump(relative_jump); 1170 __ Jump(relative_jump);
1227 } 1171 }
1228 1172
1229 // JumpConstant <idx> 1173 // JumpConstant <idx>
1230 // 1174 //
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1282 Node* relative_jump = __ SmiUntag(constant); 1226 Node* relative_jump = __ SmiUntag(constant);
1283 Node* false_value = __ BooleanConstant(false); 1227 Node* false_value = __ BooleanConstant(false);
1284 __ JumpIfWordEqual(accumulator, false_value, relative_jump); 1228 __ JumpIfWordEqual(accumulator, false_value, relative_jump);
1285 } 1229 }
1286 1230
1287 // JumpIfToBooleanTrue <imm> 1231 // JumpIfToBooleanTrue <imm>
1288 // 1232 //
1289 // Jump by number of bytes represented by an immediate operand if the object 1233 // Jump by number of bytes represented by an immediate operand if the object
1290 // referenced by the accumulator is true when the object is cast to boolean. 1234 // referenced by the accumulator is true when the object is cast to boolean.
1291 void Interpreter::DoJumpIfToBooleanTrue(InterpreterAssembler* assembler) { 1235 void Interpreter::DoJumpIfToBooleanTrue(InterpreterAssembler* assembler) {
1292 Callable callable = CodeFactory::ToBoolean(isolate_);
1293 Node* target = __ HeapConstant(callable.code());
1294 Node* accumulator = __ GetAccumulator(); 1236 Node* accumulator = __ GetAccumulator();
1295 Node* context = __ GetContext(); 1237 Node* to_boolean_value = BuildToBoolean(accumulator, assembler);
1296 Node* to_boolean_value =
1297 __ CallStub(callable.descriptor(), target, context, accumulator);
1298 Node* relative_jump = __ BytecodeOperandImm(0); 1238 Node* relative_jump = __ BytecodeOperandImm(0);
1299 Node* true_value = __ BooleanConstant(true); 1239 Node* true_value = __ BooleanConstant(true);
1300 __ JumpIfWordEqual(to_boolean_value, true_value, relative_jump); 1240 __ JumpIfWordEqual(to_boolean_value, true_value, relative_jump);
1301 } 1241 }
1302 1242
1303 // JumpIfToBooleanTrueConstant <idx> 1243 // JumpIfToBooleanTrueConstant <idx>
1304 // 1244 //
1305 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool 1245 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool
1306 // if the object referenced by the accumulator is true when the object is cast 1246 // if the object referenced by the accumulator is true when the object is cast
1307 // to boolean. 1247 // to boolean.
1308 void Interpreter::DoJumpIfToBooleanTrueConstant( 1248 void Interpreter::DoJumpIfToBooleanTrueConstant(
1309 InterpreterAssembler* assembler) { 1249 InterpreterAssembler* assembler) {
1310 Callable callable = CodeFactory::ToBoolean(isolate_);
1311 Node* target = __ HeapConstant(callable.code());
1312 Node* accumulator = __ GetAccumulator(); 1250 Node* accumulator = __ GetAccumulator();
1313 Node* context = __ GetContext(); 1251 Node* to_boolean_value = BuildToBoolean(accumulator, assembler);
1314 Node* to_boolean_value =
1315 __ CallStub(callable.descriptor(), target, context, accumulator);
1316 Node* index = __ BytecodeOperandIdx(0); 1252 Node* index = __ BytecodeOperandIdx(0);
1317 Node* constant = __ LoadConstantPoolEntry(index); 1253 Node* constant = __ LoadConstantPoolEntry(index);
1318 Node* relative_jump = __ SmiUntag(constant); 1254 Node* relative_jump = __ SmiUntag(constant);
1319 Node* true_value = __ BooleanConstant(true); 1255 Node* true_value = __ BooleanConstant(true);
1320 __ JumpIfWordEqual(to_boolean_value, true_value, relative_jump); 1256 __ JumpIfWordEqual(to_boolean_value, true_value, relative_jump);
1321 } 1257 }
1322 1258
1323 // JumpIfToBooleanFalse <imm> 1259 // JumpIfToBooleanFalse <imm>
1324 // 1260 //
1325 // Jump by number of bytes represented by an immediate operand if the object 1261 // Jump by number of bytes represented by an immediate operand if the object
1326 // referenced by the accumulator is false when the object is cast to boolean. 1262 // referenced by the accumulator is false when the object is cast to boolean.
1327 void Interpreter::DoJumpIfToBooleanFalse(InterpreterAssembler* assembler) { 1263 void Interpreter::DoJumpIfToBooleanFalse(InterpreterAssembler* assembler) {
1328 Callable callable = CodeFactory::ToBoolean(isolate_);
1329 Node* target = __ HeapConstant(callable.code());
1330 Node* accumulator = __ GetAccumulator(); 1264 Node* accumulator = __ GetAccumulator();
1331 Node* context = __ GetContext(); 1265 Node* to_boolean_value = BuildToBoolean(accumulator, assembler);
1332 Node* to_boolean_value =
1333 __ CallStub(callable.descriptor(), target, context, accumulator);
1334 Node* relative_jump = __ BytecodeOperandImm(0); 1266 Node* relative_jump = __ BytecodeOperandImm(0);
1335 Node* false_value = __ BooleanConstant(false); 1267 Node* false_value = __ BooleanConstant(false);
1336 __ JumpIfWordEqual(to_boolean_value, false_value, relative_jump); 1268 __ JumpIfWordEqual(to_boolean_value, false_value, relative_jump);
1337 } 1269 }
1338 1270
1339 // JumpIfToBooleanFalseConstant <idx> 1271 // JumpIfToBooleanFalseConstant <idx>
1340 // 1272 //
1341 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool 1273 // Jump by number of bytes in the Smi in the |idx| entry in the constant pool
1342 // if the object referenced by the accumulator is false when the object is cast 1274 // if the object referenced by the accumulator is false when the object is cast
1343 // to boolean. 1275 // to boolean.
1344 void Interpreter::DoJumpIfToBooleanFalseConstant( 1276 void Interpreter::DoJumpIfToBooleanFalseConstant(
1345 InterpreterAssembler* assembler) { 1277 InterpreterAssembler* assembler) {
1346 Callable callable = CodeFactory::ToBoolean(isolate_);
1347 Node* target = __ HeapConstant(callable.code());
1348 Node* accumulator = __ GetAccumulator(); 1278 Node* accumulator = __ GetAccumulator();
1349 Node* context = __ GetContext(); 1279 Node* to_boolean_value = BuildToBoolean(accumulator, assembler);
1350 Node* to_boolean_value =
1351 __ CallStub(callable.descriptor(), target, context, accumulator);
1352 Node* index = __ BytecodeOperandIdx(0); 1280 Node* index = __ BytecodeOperandIdx(0);
1353 Node* constant = __ LoadConstantPoolEntry(index); 1281 Node* constant = __ LoadConstantPoolEntry(index);
1354 Node* relative_jump = __ SmiUntag(constant); 1282 Node* relative_jump = __ SmiUntag(constant);
1355 Node* false_value = __ BooleanConstant(false); 1283 Node* false_value = __ BooleanConstant(false);
1356 __ JumpIfWordEqual(to_boolean_value, false_value, relative_jump); 1284 __ JumpIfWordEqual(to_boolean_value, false_value, relative_jump);
1357 } 1285 }
1358 1286
1359 // JumpIfNull <imm> 1287 // JumpIfNull <imm>
1360 // 1288 //
1361 // Jump by number of bytes represented by an immediate operand if the object 1289 // Jump by number of bytes represented by an immediate operand if the object
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
1572 1500
1573 __ Bind(&if_duplicate_parameters); 1501 __ Bind(&if_duplicate_parameters);
1574 { 1502 {
1575 Node* result = 1503 Node* result =
1576 __ CallRuntime(Runtime::kNewSloppyArguments_Generic, context, closure); 1504 __ CallRuntime(Runtime::kNewSloppyArguments_Generic, context, closure);
1577 __ SetAccumulator(result); 1505 __ SetAccumulator(result);
1578 __ Dispatch(); 1506 __ Dispatch();
1579 } 1507 }
1580 } 1508 }
1581 1509
1582
1583 // CreateUnmappedArguments 1510 // CreateUnmappedArguments
1584 // 1511 //
1585 // Creates a new unmapped arguments object. 1512 // Creates a new unmapped arguments object.
1586 void Interpreter::DoCreateUnmappedArguments(InterpreterAssembler* assembler) { 1513 void Interpreter::DoCreateUnmappedArguments(InterpreterAssembler* assembler) {
1587 // TODO(rmcilroy): Inline FastNewStrictArguments when it is a TurboFan stub. 1514 // TODO(rmcilroy): Inline FastNewStrictArguments when it is a TurboFan stub.
1588 Callable callable = CodeFactory::FastNewStrictArguments(isolate_, true); 1515 Callable callable = CodeFactory::FastNewStrictArguments(isolate_, true);
1589 Node* target = __ HeapConstant(callable.code()); 1516 Node* target = __ HeapConstant(callable.code());
1590 Node* context = __ GetContext(); 1517 Node* context = __ GetContext();
1591 Node* closure = __ LoadRegister(Register::function_closure()); 1518 Node* closure = __ LoadRegister(Register::function_closure());
1592 Node* result = __ CallStub(callable.descriptor(), target, context, closure); 1519 Node* result = __ CallStub(callable.descriptor(), target, context, closure);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1632 // 1559 //
1633 // Throws the exception in the accumulator. 1560 // Throws the exception in the accumulator.
1634 void Interpreter::DoThrow(InterpreterAssembler* assembler) { 1561 void Interpreter::DoThrow(InterpreterAssembler* assembler) {
1635 Node* exception = __ GetAccumulator(); 1562 Node* exception = __ GetAccumulator();
1636 Node* context = __ GetContext(); 1563 Node* context = __ GetContext();
1637 __ CallRuntime(Runtime::kThrow, context, exception); 1564 __ CallRuntime(Runtime::kThrow, context, exception);
1638 // We shouldn't ever return from a throw. 1565 // We shouldn't ever return from a throw.
1639 __ Abort(kUnexpectedReturnFromThrow); 1566 __ Abort(kUnexpectedReturnFromThrow);
1640 } 1567 }
1641 1568
1642
1643 // ReThrow 1569 // ReThrow
1644 // 1570 //
1645 // Re-throws the exception in the accumulator. 1571 // Re-throws the exception in the accumulator.
1646 void Interpreter::DoReThrow(InterpreterAssembler* assembler) { 1572 void Interpreter::DoReThrow(InterpreterAssembler* assembler) {
1647 Node* exception = __ GetAccumulator(); 1573 Node* exception = __ GetAccumulator();
1648 Node* context = __ GetContext(); 1574 Node* context = __ GetContext();
1649 __ CallRuntime(Runtime::kReThrow, context, exception); 1575 __ CallRuntime(Runtime::kReThrow, context, exception);
1650 // We shouldn't ever return from a throw. 1576 // We shouldn't ever return from a throw.
1651 __ Abort(kUnexpectedReturnFromThrow); 1577 __ Abort(kUnexpectedReturnFromThrow);
1652 } 1578 }
1653 1579
1654
1655 // Return 1580 // Return
1656 // 1581 //
1657 // Return the value in the accumulator. 1582 // Return the value in the accumulator.
1658 void Interpreter::DoReturn(InterpreterAssembler* assembler) { 1583 void Interpreter::DoReturn(InterpreterAssembler* assembler) {
1659 __ UpdateInterruptBudgetOnReturn(); 1584 __ UpdateInterruptBudgetOnReturn();
1660 Node* accumulator = __ GetAccumulator(); 1585 Node* accumulator = __ GetAccumulator();
1661 __ Return(accumulator); 1586 __ Return(accumulator);
1662 } 1587 }
1663 1588
1664 // Debugger 1589 // Debugger
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1855 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, 1780 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset,
1856 __ SmiTag(new_state)); 1781 __ SmiTag(new_state));
1857 __ SetAccumulator(old_state); 1782 __ SetAccumulator(old_state);
1858 1783
1859 __ Dispatch(); 1784 __ Dispatch();
1860 } 1785 }
1861 1786
1862 } // namespace interpreter 1787 } // namespace interpreter
1863 } // namespace internal 1788 } // namespace internal
1864 } // namespace v8 1789 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/interpreter.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698