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

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

Issue 2733563002: [ic] Inline LoadIC into LdaNamedProperty bytecode handler (Closed)
Patch Set: Created 3 years, 9 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
« src/ic/accessor-assembler.cc ('K') | « 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 #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
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
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
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
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(&params, 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
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
OLDNEW
« src/ic/accessor-assembler.cc ('K') | « src/interpreter/interpreter.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698