Chromium Code Reviews| 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 |