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" |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
478 // | 478 // |
479 // Stores the value of register <src> to register <dst>. | 479 // Stores the value of register <src> to register <dst>. |
480 void Interpreter::DoMov(InterpreterAssembler* assembler) { | 480 void Interpreter::DoMov(InterpreterAssembler* assembler) { |
481 Node* src_index = __ BytecodeOperandReg(0); | 481 Node* src_index = __ BytecodeOperandReg(0); |
482 Node* src_value = __ LoadRegister(src_index); | 482 Node* src_value = __ LoadRegister(src_index); |
483 Node* dst_index = __ BytecodeOperandReg(1); | 483 Node* dst_index = __ BytecodeOperandReg(1); |
484 __ StoreRegister(src_value, dst_index); | 484 __ StoreRegister(src_value, dst_index); |
485 __ Dispatch(); | 485 __ Dispatch(); |
486 } | 486 } |
487 | 487 |
488 void Interpreter::BuildLoadGlobal(int slot_operand_index, | 488 void Interpreter::BuildLoadGlobalIC(int slot_operand_index, |
489 int name_operand_index, | 489 int name_operand_index, |
490 TypeofMode typeof_mode, | 490 TypeofMode typeof_mode, |
491 InterpreterAssembler* assembler) { | 491 InterpreterAssembler* assembler) { |
492 // Must be kept in sync with AccessorAssembler::LoadGlobalIC. | |
493 | |
492 // Load the global via the LoadGlobalIC. | 494 // Load the global via the LoadGlobalIC. |
493 Node* feedback_vector = __ LoadFeedbackVector(); | 495 Node* feedback_vector = __ LoadFeedbackVector(); |
494 Node* feedback_slot = __ BytecodeOperandIdx(slot_operand_index); | 496 Node* feedback_slot = __ BytecodeOperandIdx(slot_operand_index); |
495 | 497 |
496 AccessorAssembler accessor_asm(assembler->state()); | 498 AccessorAssembler accessor_asm(assembler->state()); |
497 | 499 |
498 Label try_handler(assembler, Label::kDeferred), | 500 Label try_handler(assembler, Label::kDeferred), |
499 miss(assembler, Label::kDeferred); | 501 miss(assembler, Label::kDeferred); |
500 | 502 |
501 // Fast path without frame construction for the data case. | 503 // Fast path without frame construction for the data case. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
553 } | 555 } |
554 | 556 |
555 // LdaGlobal <name_index> <slot> | 557 // LdaGlobal <name_index> <slot> |
556 // | 558 // |
557 // Load the global with name in constant pool entry <name_index> into the | 559 // Load the global with name in constant pool entry <name_index> into the |
558 // accumulator using FeedBackVector slot <slot> outside of a typeof. | 560 // accumulator using FeedBackVector slot <slot> outside of a typeof. |
559 void Interpreter::DoLdaGlobal(InterpreterAssembler* assembler) { | 561 void Interpreter::DoLdaGlobal(InterpreterAssembler* assembler) { |
560 static const int kNameOperandIndex = 0; | 562 static const int kNameOperandIndex = 0; |
561 static const int kSlotOperandIndex = 1; | 563 static const int kSlotOperandIndex = 1; |
562 | 564 |
563 BuildLoadGlobal(kSlotOperandIndex, kNameOperandIndex, NOT_INSIDE_TYPEOF, | 565 BuildLoadGlobalIC(kSlotOperandIndex, kNameOperandIndex, NOT_INSIDE_TYPEOF, |
564 assembler); | 566 assembler); |
565 } | 567 } |
566 | 568 |
567 // LdaGlobalInsideTypeof <name_index> <slot> | 569 // LdaGlobalInsideTypeof <name_index> <slot> |
568 // | 570 // |
569 // Load the global with name in constant pool entry <name_index> into the | 571 // Load the global with name in constant pool entry <name_index> into the |
570 // accumulator using FeedBackVector slot <slot> inside of a typeof. | 572 // accumulator using FeedBackVector slot <slot> inside of a typeof. |
571 void Interpreter::DoLdaGlobalInsideTypeof(InterpreterAssembler* assembler) { | 573 void Interpreter::DoLdaGlobalInsideTypeof(InterpreterAssembler* assembler) { |
572 static const int kNameOperandIndex = 0; | 574 static const int kNameOperandIndex = 0; |
573 static const int kSlotOperandIndex = 1; | 575 static const int kSlotOperandIndex = 1; |
574 | 576 |
575 BuildLoadGlobal(kSlotOperandIndex, kNameOperandIndex, INSIDE_TYPEOF, | 577 BuildLoadGlobalIC(kSlotOperandIndex, kNameOperandIndex, INSIDE_TYPEOF, |
576 assembler); | 578 assembler); |
577 } | 579 } |
578 | 580 |
579 void Interpreter::DoStaGlobal(Callable ic, InterpreterAssembler* assembler) { | 581 void Interpreter::DoStaGlobal(Callable ic, InterpreterAssembler* assembler) { |
580 // Get the global object. | 582 // Get the global object. |
581 Node* context = __ GetContext(); | 583 Node* context = __ GetContext(); |
582 Node* native_context = __ LoadNativeContext(context); | 584 Node* native_context = __ LoadNativeContext(context); |
583 Node* global = | 585 Node* global = |
584 __ LoadContextElement(native_context, Context::EXTENSION_INDEX); | 586 __ LoadContextElement(native_context, Context::EXTENSION_INDEX); |
585 | 587 |
586 // Store the global via the StoreIC. | 588 // Store the global via the StoreIC. |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
770 | 772 |
771 // Fast path does a normal load global | 773 // Fast path does a normal load global |
772 { | 774 { |
773 static const int kNameOperandIndex = 0; | 775 static const int kNameOperandIndex = 0; |
774 static const int kSlotOperandIndex = 1; | 776 static const int kSlotOperandIndex = 1; |
775 | 777 |
776 TypeofMode typeof_mode = function_id == Runtime::kLoadLookupSlotInsideTypeof | 778 TypeofMode typeof_mode = function_id == Runtime::kLoadLookupSlotInsideTypeof |
777 ? INSIDE_TYPEOF | 779 ? INSIDE_TYPEOF |
778 : NOT_INSIDE_TYPEOF; | 780 : NOT_INSIDE_TYPEOF; |
779 | 781 |
780 BuildLoadGlobal(kSlotOperandIndex, kNameOperandIndex, typeof_mode, | 782 BuildLoadGlobalIC(kSlotOperandIndex, kNameOperandIndex, typeof_mode, |
781 assembler); | 783 assembler); |
782 } | 784 } |
783 | 785 |
784 // Slow path when we have to call out to the runtime | 786 // Slow path when we have to call out to the runtime |
785 __ Bind(&slowpath); | 787 __ Bind(&slowpath); |
786 { | 788 { |
787 Node* name_index = __ BytecodeOperandIdx(0); | 789 Node* name_index = __ BytecodeOperandIdx(0); |
788 Node* name = __ LoadConstantPoolEntry(name_index); | 790 Node* name = __ LoadConstantPoolEntry(name_index); |
789 Node* result = __ CallRuntime(function_id, context, name); | 791 Node* result = __ CallRuntime(function_id, context, name); |
790 __ SetAccumulator(result); | 792 __ SetAccumulator(result); |
791 __ Dispatch(); | 793 __ Dispatch(); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
832 } | 834 } |
833 | 835 |
834 // StaLookupSlotStrict <name_index> | 836 // StaLookupSlotStrict <name_index> |
835 // | 837 // |
836 // Store the object in accumulator to the object with the name in constant | 838 // Store the object in accumulator to the object with the name in constant |
837 // pool entry |name_index| in strict mode. | 839 // pool entry |name_index| in strict mode. |
838 void Interpreter::DoStaLookupSlotStrict(InterpreterAssembler* assembler) { | 840 void Interpreter::DoStaLookupSlotStrict(InterpreterAssembler* assembler) { |
839 DoStaLookupSlot(LanguageMode::STRICT, assembler); | 841 DoStaLookupSlot(LanguageMode::STRICT, assembler); |
840 } | 842 } |
841 | 843 |
844 void Interpreter::BuildLoadIC(int recv_operand_index, int slot_operand_index, | |
845 int name_operand_index, | |
846 InterpreterAssembler* assembler) { | |
847 // Must be kept in sync with AccessorAssembler::LoadIC. | |
Igor Sheludko
2017/03/03 15:29:44
Please move the LoadIC related piece to AccessorAs
jgruber
2017/03/03 17:53:42
Done. I left optimizations like delayed loading an
| |
848 __ Comment("BuildLoadIC"); | |
849 | |
850 // Load vector and slot. | |
851 Node* feedback_vector = __ LoadFeedbackVector(); | |
852 Node* feedback_slot = __ BytecodeOperandIdx(slot_operand_index); | |
853 Node* smi_slot = __ SmiTag(feedback_slot); | |
854 | |
855 // Load receiver. | |
856 Node* register_index = __ BytecodeOperandReg(recv_operand_index); | |
857 Node* recv = __ LoadRegister(register_index); | |
858 | |
859 // Load the name. | |
860 // TODO(jgruber): Not needed for monomorphic smi handler constant/field case. | |
861 Node* constant_index = __ BytecodeOperandIdx(name_operand_index); | |
862 Node* name = __ LoadConstantPoolEntry(constant_index); | |
863 | |
864 Label done(assembler), stub_call(assembler, Label::kDeferred), | |
865 miss(assembler, Label::kDeferred); | |
866 | |
867 Variable var_result(assembler, MachineRepresentation::kTagged); | |
868 ExitPoint exit_point(assembler, &done, &var_result); | |
869 | |
870 // Inlined fast path for the monomorphic case. | |
871 { | |
872 __ Comment("BuildLoadIC_fast"); | |
873 | |
874 AccessorAssembler accessor_asm(assembler->state()); | |
875 | |
876 Node* recv_map = __ LoadReceiverMap(recv); | |
877 __ GotoIf(__ IsDeprecatedMap(recv_map), &miss); | |
878 | |
879 Node* feedback = nullptr; | |
880 Node* handler = nullptr; | |
881 std::tie(feedback, handler) = accessor_asm.TryMonomorphicCase( | |
882 smi_slot, feedback_vector, recv_map, &stub_call); | |
883 | |
884 Node* context = __ GetContext(); | |
885 AccessorAssembler::LoadICParameters params(context, recv, name, smi_slot, | |
886 feedback_vector); | |
887 accessor_asm.HandleLoadICHandlerCase(¶ms, handler, &miss, &exit_point); | |
888 } | |
889 | |
890 __ Bind(&stub_call); | |
891 { | |
892 __ Comment("BuildLoadIC_noninlined"); | |
893 | |
894 Callable ic = CodeFactory::LoadICInOptimizedCode_Noninlined(isolate_); | |
895 Node* code_target = __ HeapConstant(ic.code()); | |
896 Node* context = __ GetContext(); | |
897 exit_point.ReturnCallStub(ic.descriptor(), code_target, context, recv, name, | |
898 smi_slot, feedback_vector); | |
899 } | |
900 | |
901 __ Bind(&miss); | |
902 { | |
903 __ Comment("BuildLoadIC_miss"); | |
904 | |
905 Node* context = __ GetContext(); | |
906 exit_point.ReturnCallRuntime(Runtime::kLoadIC_Miss, context, recv, name, | |
907 smi_slot, feedback_vector); | |
908 } | |
909 | |
910 __ Bind(&done); | |
911 { | |
912 __ SetAccumulator(var_result.value()); | |
913 __ Dispatch(); | |
914 } | |
915 } | |
916 | |
842 // LdaNamedProperty <object> <name_index> <slot> | 917 // LdaNamedProperty <object> <name_index> <slot> |
843 // | 918 // |
844 // Calls the LoadIC at FeedBackVector slot <slot> for <object> and the name at | 919 // Calls the LoadIC at FeedBackVector slot <slot> for <object> and the name at |
845 // constant pool entry <name_index>. | 920 // constant pool entry <name_index>. |
846 void Interpreter::DoLdaNamedProperty(InterpreterAssembler* assembler) { | 921 void Interpreter::DoLdaNamedProperty(InterpreterAssembler* assembler) { |
847 Callable ic = CodeFactory::LoadICInOptimizedCode(isolate_); | 922 static const int kRecvOperandIndex = 0; |
848 Node* code_target = __ HeapConstant(ic.code()); | 923 static const int kNameOperandIndex = 1; |
849 Node* register_index = __ BytecodeOperandReg(0); | 924 static const int kSlotOperandIndex = 2; |
850 Node* object = __ LoadRegister(register_index); | 925 |
851 Node* constant_index = __ BytecodeOperandIdx(1); | 926 BuildLoadIC(kRecvOperandIndex, kSlotOperandIndex, kNameOperandIndex, |
852 Node* name = __ LoadConstantPoolEntry(constant_index); | 927 assembler); |
853 Node* raw_slot = __ BytecodeOperandIdx(2); | |
854 Node* smi_slot = __ SmiTag(raw_slot); | |
855 Node* feedback_vector = __ LoadFeedbackVector(); | |
856 Node* context = __ GetContext(); | |
857 Node* result = __ CallStub(ic.descriptor(), code_target, context, object, | |
858 name, smi_slot, feedback_vector); | |
859 __ SetAccumulator(result); | |
860 __ Dispatch(); | |
861 } | 928 } |
862 | 929 |
863 // KeyedLoadIC <object> <slot> | 930 // KeyedLoadIC <object> <slot> |
864 // | 931 // |
865 // Calls the KeyedLoadIC at FeedBackVector slot <slot> for <object> and the key | 932 // Calls the KeyedLoadIC at FeedBackVector slot <slot> for <object> and the key |
866 // in the accumulator. | 933 // in the accumulator. |
867 void Interpreter::DoLdaKeyedProperty(InterpreterAssembler* assembler) { | 934 void Interpreter::DoLdaKeyedProperty(InterpreterAssembler* assembler) { |
868 Callable ic = CodeFactory::KeyedLoadICInOptimizedCode(isolate_); | 935 Callable ic = CodeFactory::KeyedLoadICInOptimizedCode(isolate_); |
869 Node* code_target = __ HeapConstant(ic.code()); | 936 Node* code_target = __ HeapConstant(ic.code()); |
870 Node* reg_index = __ BytecodeOperandReg(0); | 937 Node* reg_index = __ BytecodeOperandReg(0); |
(...skipping 2509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3380 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, | 3447 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, |
3381 __ SmiTag(new_state)); | 3448 __ SmiTag(new_state)); |
3382 __ SetAccumulator(old_state); | 3449 __ SetAccumulator(old_state); |
3383 | 3450 |
3384 __ Dispatch(); | 3451 __ Dispatch(); |
3385 } | 3452 } |
3386 | 3453 |
3387 } // namespace interpreter | 3454 } // namespace interpreter |
3388 } // namespace internal | 3455 } // namespace internal |
3389 } // namespace v8 | 3456 } // namespace v8 |
OLD | NEW |