OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/interpreter/interpreter.h" | 5 #include "src/interpreter/interpreter.h" |
6 | 6 |
7 #include <fstream> | 7 #include <fstream> |
8 #include <memory> | 8 #include <memory> |
9 | 9 |
10 #include "src/ast/prettyprinter.h" | 10 #include "src/ast/prettyprinter.h" |
11 #include "src/code-factory.h" | 11 #include "src/code-factory.h" |
12 #include "src/compilation-info.h" | 12 #include "src/compilation-info.h" |
13 #include "src/compiler.h" | 13 #include "src/compiler.h" |
14 #include "src/factory.h" | 14 #include "src/factory.h" |
15 #include "src/interpreter/bytecode-flags.h" | 15 #include "src/interpreter/bytecode-flags.h" |
16 #include "src/interpreter/bytecode-generator.h" | 16 #include "src/interpreter/bytecode-generator.h" |
17 #include "src/interpreter/bytecodes.h" | 17 #include "src/interpreter/bytecodes.h" |
18 #include "src/interpreter/interpreter-assembler.h" | 18 #include "src/interpreter/interpreter-assembler.h" |
19 #include "src/interpreter/interpreter-intrinsics.h" | 19 #include "src/interpreter/interpreter-intrinsics.h" |
20 #include "src/log.h" | 20 #include "src/log.h" |
21 #include "src/zone/zone.h" | 21 #include "src/zone/zone.h" |
22 | 22 |
23 namespace v8 { | 23 namespace v8 { |
24 namespace internal { | 24 namespace internal { |
25 namespace interpreter { | 25 namespace interpreter { |
26 | 26 |
27 using compiler::Node; | 27 using compiler::Node; |
28 typedef CodeStubAssembler::Label Label; | 28 typedef CodeStubAssembler::Label Label; |
29 typedef CodeStubAssembler::Variable Variable; | 29 typedef CodeStubAssembler::Variable Variable; |
30 typedef InterpreterAssembler::Arg Arg; | |
31 | 30 |
32 #define __ assembler-> | 31 #define __ assembler-> |
33 | 32 |
34 class InterpreterCompilationJob final : public CompilationJob { | 33 class InterpreterCompilationJob final : public CompilationJob { |
35 public: | 34 public: |
36 explicit InterpreterCompilationJob(CompilationInfo* info); | 35 explicit InterpreterCompilationJob(CompilationInfo* info); |
37 | 36 |
38 protected: | 37 protected: |
39 Status PrepareJobImpl() final; | 38 Status PrepareJobImpl() final; |
40 Status ExecuteJobImpl() final; | 39 Status ExecuteJobImpl() final; |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 Node* src_index = __ BytecodeOperandReg(0); | 408 Node* src_index = __ BytecodeOperandReg(0); |
410 Node* src_value = __ LoadRegister(src_index); | 409 Node* src_value = __ LoadRegister(src_index); |
411 Node* dst_index = __ BytecodeOperandReg(1); | 410 Node* dst_index = __ BytecodeOperandReg(1); |
412 __ StoreRegister(src_value, dst_index); | 411 __ StoreRegister(src_value, dst_index); |
413 __ Dispatch(); | 412 __ Dispatch(); |
414 } | 413 } |
415 | 414 |
416 Node* Interpreter::BuildLoadGlobal(Callable ic, Node* context, Node* name_index, | 415 Node* Interpreter::BuildLoadGlobal(Callable ic, Node* context, Node* name_index, |
417 Node* feedback_slot, | 416 Node* feedback_slot, |
418 InterpreterAssembler* assembler) { | 417 InterpreterAssembler* assembler) { |
419 typedef LoadGlobalWithVectorDescriptor Descriptor; | |
420 | |
421 // Load the global via the LoadGlobalIC. | 418 // Load the global via the LoadGlobalIC. |
422 Node* code_target = __ HeapConstant(ic.code()); | 419 Node* code_target = __ HeapConstant(ic.code()); |
423 Node* name = __ LoadConstantPoolEntry(name_index); | 420 Node* name = __ LoadConstantPoolEntry(name_index); |
424 Node* smi_slot = __ SmiTag(feedback_slot); | 421 Node* smi_slot = __ SmiTag(feedback_slot); |
425 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 422 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
426 return __ CallStub(ic.descriptor(), code_target, context, | 423 return __ CallStub(ic.descriptor(), code_target, context, name, smi_slot, |
427 Arg(Descriptor::kName, name), | 424 type_feedback_vector); |
428 Arg(Descriptor::kSlot, smi_slot), | |
429 Arg(Descriptor::kVector, type_feedback_vector)); | |
430 } | 425 } |
431 | 426 |
432 // LdaGlobal <name_index> <slot> | 427 // LdaGlobal <name_index> <slot> |
433 // | 428 // |
434 // Load the global with name in constant pool entry <name_index> into the | 429 // Load the global with name in constant pool entry <name_index> into the |
435 // accumulator using FeedBackVector slot <slot> outside of a typeof. | 430 // accumulator using FeedBackVector slot <slot> outside of a typeof. |
436 void Interpreter::DoLdaGlobal(InterpreterAssembler* assembler) { | 431 void Interpreter::DoLdaGlobal(InterpreterAssembler* assembler) { |
437 Callable ic = | 432 Callable ic = |
438 CodeFactory::LoadGlobalICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF); | 433 CodeFactory::LoadGlobalICInOptimizedCode(isolate_, NOT_INSIDE_TYPEOF); |
439 | 434 |
(...skipping 17 matching lines...) Expand all Loading... |
457 Node* context = __ GetContext(); | 452 Node* context = __ GetContext(); |
458 | 453 |
459 Node* name_index = __ BytecodeOperandIdx(0); | 454 Node* name_index = __ BytecodeOperandIdx(0); |
460 Node* raw_slot = __ BytecodeOperandIdx(1); | 455 Node* raw_slot = __ BytecodeOperandIdx(1); |
461 Node* result = BuildLoadGlobal(ic, context, name_index, raw_slot, assembler); | 456 Node* result = BuildLoadGlobal(ic, context, name_index, raw_slot, assembler); |
462 __ SetAccumulator(result); | 457 __ SetAccumulator(result); |
463 __ Dispatch(); | 458 __ Dispatch(); |
464 } | 459 } |
465 | 460 |
466 void Interpreter::DoStaGlobal(Callable ic, InterpreterAssembler* assembler) { | 461 void Interpreter::DoStaGlobal(Callable ic, InterpreterAssembler* assembler) { |
467 typedef StoreWithVectorDescriptor Descriptor; | |
468 // Get the global object. | 462 // Get the global object. |
469 Node* context = __ GetContext(); | 463 Node* context = __ GetContext(); |
470 Node* native_context = __ LoadNativeContext(context); | 464 Node* native_context = __ LoadNativeContext(context); |
471 Node* global = | 465 Node* global = |
472 __ LoadContextElement(native_context, Context::EXTENSION_INDEX); | 466 __ LoadContextElement(native_context, Context::EXTENSION_INDEX); |
473 | 467 |
474 // Store the global via the StoreIC. | 468 // Store the global via the StoreIC. |
475 Node* code_target = __ HeapConstant(ic.code()); | 469 Node* code_target = __ HeapConstant(ic.code()); |
476 Node* constant_index = __ BytecodeOperandIdx(0); | 470 Node* constant_index = __ BytecodeOperandIdx(0); |
477 Node* name = __ LoadConstantPoolEntry(constant_index); | 471 Node* name = __ LoadConstantPoolEntry(constant_index); |
478 Node* value = __ GetAccumulator(); | 472 Node* value = __ GetAccumulator(); |
479 Node* raw_slot = __ BytecodeOperandIdx(1); | 473 Node* raw_slot = __ BytecodeOperandIdx(1); |
480 Node* smi_slot = __ SmiTag(raw_slot); | 474 Node* smi_slot = __ SmiTag(raw_slot); |
481 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 475 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
482 __ CallStub(ic.descriptor(), code_target, context, | 476 __ CallStub(ic.descriptor(), code_target, context, global, name, value, |
483 Arg(Descriptor::kReceiver, global), Arg(Descriptor::kName, name), | 477 smi_slot, type_feedback_vector); |
484 Arg(Descriptor::kValue, value), Arg(Descriptor::kSlot, smi_slot), | |
485 Arg(Descriptor::kVector, type_feedback_vector)); | |
486 __ Dispatch(); | 478 __ Dispatch(); |
487 } | 479 } |
488 | 480 |
489 // StaGlobalSloppy <name_index> <slot> | 481 // StaGlobalSloppy <name_index> <slot> |
490 // | 482 // |
491 // Store the value in the accumulator into the global with name in constant pool | 483 // Store the value in the accumulator into the global with name in constant pool |
492 // entry <name_index> using FeedBackVector slot <slot> in sloppy mode. | 484 // entry <name_index> using FeedBackVector slot <slot> in sloppy mode. |
493 void Interpreter::DoStaGlobalSloppy(InterpreterAssembler* assembler) { | 485 void Interpreter::DoStaGlobalSloppy(InterpreterAssembler* assembler) { |
494 Callable ic = CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY); | 486 Callable ic = CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY); |
495 DoStaGlobal(ic, assembler); | 487 DoStaGlobal(ic, assembler); |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
709 // pool entry |name_index| in strict mode. | 701 // pool entry |name_index| in strict mode. |
710 void Interpreter::DoStaLookupSlotStrict(InterpreterAssembler* assembler) { | 702 void Interpreter::DoStaLookupSlotStrict(InterpreterAssembler* assembler) { |
711 DoStaLookupSlot(LanguageMode::STRICT, assembler); | 703 DoStaLookupSlot(LanguageMode::STRICT, assembler); |
712 } | 704 } |
713 | 705 |
714 // LdaNamedProperty <object> <name_index> <slot> | 706 // LdaNamedProperty <object> <name_index> <slot> |
715 // | 707 // |
716 // Calls the LoadIC at FeedBackVector slot <slot> for <object> and the name at | 708 // Calls the LoadIC at FeedBackVector slot <slot> for <object> and the name at |
717 // constant pool entry <name_index>. | 709 // constant pool entry <name_index>. |
718 void Interpreter::DoLdaNamedProperty(InterpreterAssembler* assembler) { | 710 void Interpreter::DoLdaNamedProperty(InterpreterAssembler* assembler) { |
719 typedef LoadWithVectorDescriptor Descriptor; | |
720 Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_); | 711 Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_); |
721 Node* code_target = __ HeapConstant(ic.code()); | 712 Node* code_target = __ HeapConstant(ic.code()); |
722 Node* register_index = __ BytecodeOperandReg(0); | 713 Node* register_index = __ BytecodeOperandReg(0); |
723 Node* object = __ LoadRegister(register_index); | 714 Node* object = __ LoadRegister(register_index); |
724 Node* constant_index = __ BytecodeOperandIdx(1); | 715 Node* constant_index = __ BytecodeOperandIdx(1); |
725 Node* name = __ LoadConstantPoolEntry(constant_index); | 716 Node* name = __ LoadConstantPoolEntry(constant_index); |
726 Node* raw_slot = __ BytecodeOperandIdx(2); | 717 Node* raw_slot = __ BytecodeOperandIdx(2); |
727 Node* smi_slot = __ SmiTag(raw_slot); | 718 Node* smi_slot = __ SmiTag(raw_slot); |
728 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 719 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
729 Node* context = __ GetContext(); | 720 Node* context = __ GetContext(); |
730 Node* result = __ CallStub( | 721 Node* result = __ CallStub(ic.descriptor(), code_target, context, object, |
731 ic.descriptor(), code_target, context, Arg(Descriptor::kReceiver, object), | 722 name, smi_slot, type_feedback_vector); |
732 Arg(Descriptor::kName, name), Arg(Descriptor::kSlot, smi_slot), | |
733 Arg(Descriptor::kVector, type_feedback_vector)); | |
734 __ SetAccumulator(result); | 723 __ SetAccumulator(result); |
735 __ Dispatch(); | 724 __ Dispatch(); |
736 } | 725 } |
737 | 726 |
738 // KeyedLoadIC <object> <slot> | 727 // KeyedLoadIC <object> <slot> |
739 // | 728 // |
740 // Calls the KeyedLoadIC at FeedBackVector slot <slot> for <object> and the key | 729 // Calls the KeyedLoadIC at FeedBackVector slot <slot> for <object> and the key |
741 // in the accumulator. | 730 // in the accumulator. |
742 void Interpreter::DoLdaKeyedProperty(InterpreterAssembler* assembler) { | 731 void Interpreter::DoLdaKeyedProperty(InterpreterAssembler* assembler) { |
743 typedef LoadWithVectorDescriptor Descriptor; | |
744 Callable ic = CodeFactory::KeyedLoadICInOptimizedCode(isolate_); | 732 Callable ic = CodeFactory::KeyedLoadICInOptimizedCode(isolate_); |
745 Node* code_target = __ HeapConstant(ic.code()); | 733 Node* code_target = __ HeapConstant(ic.code()); |
746 Node* reg_index = __ BytecodeOperandReg(0); | 734 Node* reg_index = __ BytecodeOperandReg(0); |
747 Node* object = __ LoadRegister(reg_index); | 735 Node* object = __ LoadRegister(reg_index); |
748 Node* name = __ GetAccumulator(); | 736 Node* name = __ GetAccumulator(); |
749 Node* raw_slot = __ BytecodeOperandIdx(1); | 737 Node* raw_slot = __ BytecodeOperandIdx(1); |
750 Node* smi_slot = __ SmiTag(raw_slot); | 738 Node* smi_slot = __ SmiTag(raw_slot); |
751 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 739 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
752 Node* context = __ GetContext(); | 740 Node* context = __ GetContext(); |
753 Node* result = __ CallStub( | 741 Node* result = __ CallStub(ic.descriptor(), code_target, context, object, |
754 ic.descriptor(), code_target, context, Arg(Descriptor::kReceiver, object), | 742 name, smi_slot, type_feedback_vector); |
755 Arg(Descriptor::kName, name), Arg(Descriptor::kSlot, smi_slot), | |
756 Arg(Descriptor::kVector, type_feedback_vector)); | |
757 __ SetAccumulator(result); | 743 __ SetAccumulator(result); |
758 __ Dispatch(); | 744 __ Dispatch(); |
759 } | 745 } |
760 | 746 |
761 void Interpreter::DoStoreIC(Callable ic, InterpreterAssembler* assembler) { | 747 void Interpreter::DoStoreIC(Callable ic, InterpreterAssembler* assembler) { |
762 typedef StoreWithVectorDescriptor Descriptor; | |
763 Node* code_target = __ HeapConstant(ic.code()); | 748 Node* code_target = __ HeapConstant(ic.code()); |
764 Node* object_reg_index = __ BytecodeOperandReg(0); | 749 Node* object_reg_index = __ BytecodeOperandReg(0); |
765 Node* object = __ LoadRegister(object_reg_index); | 750 Node* object = __ LoadRegister(object_reg_index); |
766 Node* constant_index = __ BytecodeOperandIdx(1); | 751 Node* constant_index = __ BytecodeOperandIdx(1); |
767 Node* name = __ LoadConstantPoolEntry(constant_index); | 752 Node* name = __ LoadConstantPoolEntry(constant_index); |
768 Node* value = __ GetAccumulator(); | 753 Node* value = __ GetAccumulator(); |
769 Node* raw_slot = __ BytecodeOperandIdx(2); | 754 Node* raw_slot = __ BytecodeOperandIdx(2); |
770 Node* smi_slot = __ SmiTag(raw_slot); | 755 Node* smi_slot = __ SmiTag(raw_slot); |
771 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 756 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
772 Node* context = __ GetContext(); | 757 Node* context = __ GetContext(); |
773 __ CallStub(ic.descriptor(), code_target, context, | 758 __ CallStub(ic.descriptor(), code_target, context, object, name, value, |
774 Arg(Descriptor::kReceiver, object), Arg(Descriptor::kName, name), | 759 smi_slot, type_feedback_vector); |
775 Arg(Descriptor::kValue, value), Arg(Descriptor::kSlot, smi_slot), | |
776 Arg(Descriptor::kVector, type_feedback_vector)); | |
777 __ Dispatch(); | 760 __ Dispatch(); |
778 } | 761 } |
779 | 762 |
780 // StaNamedPropertySloppy <object> <name_index> <slot> | 763 // StaNamedPropertySloppy <object> <name_index> <slot> |
781 // | 764 // |
782 // Calls the sloppy mode StoreIC at FeedBackVector slot <slot> for <object> and | 765 // Calls the sloppy mode StoreIC at FeedBackVector slot <slot> for <object> and |
783 // the name in constant pool entry <name_index> with the value in the | 766 // the name in constant pool entry <name_index> with the value in the |
784 // accumulator. | 767 // accumulator. |
785 void Interpreter::DoStaNamedPropertySloppy(InterpreterAssembler* assembler) { | 768 void Interpreter::DoStaNamedPropertySloppy(InterpreterAssembler* assembler) { |
786 Callable ic = CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY); | 769 Callable ic = CodeFactory::StoreICInOptimizedCode(isolate_, SLOPPY); |
787 DoStoreIC(ic, assembler); | 770 DoStoreIC(ic, assembler); |
788 } | 771 } |
789 | 772 |
790 // StaNamedPropertyStrict <object> <name_index> <slot> | 773 // StaNamedPropertyStrict <object> <name_index> <slot> |
791 // | 774 // |
792 // Calls the strict mode StoreIC at FeedBackVector slot <slot> for <object> and | 775 // Calls the strict mode StoreIC at FeedBackVector slot <slot> for <object> and |
793 // the name in constant pool entry <name_index> with the value in the | 776 // the name in constant pool entry <name_index> with the value in the |
794 // accumulator. | 777 // accumulator. |
795 void Interpreter::DoStaNamedPropertyStrict(InterpreterAssembler* assembler) { | 778 void Interpreter::DoStaNamedPropertyStrict(InterpreterAssembler* assembler) { |
796 Callable ic = CodeFactory::StoreICInOptimizedCode(isolate_, STRICT); | 779 Callable ic = CodeFactory::StoreICInOptimizedCode(isolate_, STRICT); |
797 DoStoreIC(ic, assembler); | 780 DoStoreIC(ic, assembler); |
798 } | 781 } |
799 | 782 |
800 void Interpreter::DoKeyedStoreIC(Callable ic, InterpreterAssembler* assembler) { | 783 void Interpreter::DoKeyedStoreIC(Callable ic, InterpreterAssembler* assembler) { |
801 typedef StoreWithVectorDescriptor Descriptor; | |
802 Node* code_target = __ HeapConstant(ic.code()); | 784 Node* code_target = __ HeapConstant(ic.code()); |
803 Node* object_reg_index = __ BytecodeOperandReg(0); | 785 Node* object_reg_index = __ BytecodeOperandReg(0); |
804 Node* object = __ LoadRegister(object_reg_index); | 786 Node* object = __ LoadRegister(object_reg_index); |
805 Node* name_reg_index = __ BytecodeOperandReg(1); | 787 Node* name_reg_index = __ BytecodeOperandReg(1); |
806 Node* name = __ LoadRegister(name_reg_index); | 788 Node* name = __ LoadRegister(name_reg_index); |
807 Node* value = __ GetAccumulator(); | 789 Node* value = __ GetAccumulator(); |
808 Node* raw_slot = __ BytecodeOperandIdx(2); | 790 Node* raw_slot = __ BytecodeOperandIdx(2); |
809 Node* smi_slot = __ SmiTag(raw_slot); | 791 Node* smi_slot = __ SmiTag(raw_slot); |
810 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 792 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
811 Node* context = __ GetContext(); | 793 Node* context = __ GetContext(); |
812 __ CallStub(ic.descriptor(), code_target, context, | 794 __ CallStub(ic.descriptor(), code_target, context, object, name, value, |
813 Arg(Descriptor::kReceiver, object), Arg(Descriptor::kName, name), | 795 smi_slot, type_feedback_vector); |
814 Arg(Descriptor::kValue, value), Arg(Descriptor::kSlot, smi_slot), | |
815 Arg(Descriptor::kVector, type_feedback_vector)); | |
816 __ Dispatch(); | 796 __ Dispatch(); |
817 } | 797 } |
818 | 798 |
819 // StaKeyedPropertySloppy <object> <key> <slot> | 799 // StaKeyedPropertySloppy <object> <key> <slot> |
820 // | 800 // |
821 // Calls the sloppy mode KeyStoreIC at FeedBackVector slot <slot> for <object> | 801 // Calls the sloppy mode KeyStoreIC at FeedBackVector slot <slot> for <object> |
822 // and the key <key> with the value in the accumulator. | 802 // and the key <key> with the value in the accumulator. |
823 void Interpreter::DoStaKeyedPropertySloppy(InterpreterAssembler* assembler) { | 803 void Interpreter::DoStaKeyedPropertySloppy(InterpreterAssembler* assembler) { |
824 Callable ic = CodeFactory::KeyedStoreICInOptimizedCode(isolate_, SLOPPY); | 804 Callable ic = CodeFactory::KeyedStoreICInOptimizedCode(isolate_, SLOPPY); |
825 DoKeyedStoreIC(ic, assembler); | 805 DoKeyedStoreIC(ic, assembler); |
(...skipping 2030 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2856 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, | 2836 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, |
2857 __ SmiTag(new_state)); | 2837 __ SmiTag(new_state)); |
2858 __ SetAccumulator(old_state); | 2838 __ SetAccumulator(old_state); |
2859 | 2839 |
2860 __ Dispatch(); | 2840 __ Dispatch(); |
2861 } | 2841 } |
2862 | 2842 |
2863 } // namespace interpreter | 2843 } // namespace interpreter |
2864 } // namespace internal | 2844 } // namespace internal |
2865 } // namespace v8 | 2845 } // namespace v8 |
OLD | NEW |