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

Side by Side Diff: src/x64/stub-cache-x64.cc

Issue 8404030: Version 3.7.1 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « src/x64/regexp-macro-assembler-x64.cc ('k') | test/cctest/cctest.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 75
76 __ bind(&miss); 76 __ bind(&miss);
77 } 77 }
78 78
79 79
80 // Helper function used to check that the dictionary doesn't contain 80 // Helper function used to check that the dictionary doesn't contain
81 // the property. This function may return false negatives, so miss_label 81 // the property. This function may return false negatives, so miss_label
82 // must always call a backup property check that is complete. 82 // must always call a backup property check that is complete.
83 // This function is safe to call if the receiver has fast properties. 83 // This function is safe to call if the receiver has fast properties.
84 // Name must be a symbol and receiver must be a heap object. 84 // Name must be a symbol and receiver must be a heap object.
85 MUST_USE_RESULT static MaybeObject* GenerateDictionaryNegativeLookup( 85 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
86 Label* miss_label,
87 Register receiver,
88 Handle<String> name,
89 Register r0,
90 Register r1) {
91 ASSERT(name->IsSymbol());
92 Counters* counters = masm->isolate()->counters();
93 __ IncrementCounter(counters->negative_lookups(), 1);
94 __ IncrementCounter(counters->negative_lookups_miss(), 1);
95
96 __ movq(r0, FieldOperand(receiver, HeapObject::kMapOffset));
97
98 const int kInterceptorOrAccessCheckNeededMask =
99 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
100
101 // Bail out if the receiver has a named interceptor or requires access checks.
102 __ testb(FieldOperand(r0, Map::kBitFieldOffset),
103 Immediate(kInterceptorOrAccessCheckNeededMask));
104 __ j(not_zero, miss_label);
105
106 // Check that receiver is a JSObject.
107 __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE);
108 __ j(below, miss_label);
109
110 // Load properties array.
111 Register properties = r0;
112 __ movq(properties, FieldOperand(receiver, JSObject::kPropertiesOffset));
113
114 // Check that the properties array is a dictionary.
115 __ CompareRoot(FieldOperand(properties, HeapObject::kMapOffset),
116 Heap::kHashTableMapRootIndex);
117 __ j(not_equal, miss_label);
118
119 Label done;
120 StringDictionaryLookupStub::GenerateNegativeLookup(masm,
121 miss_label,
122 &done,
123 properties,
124 name,
125 r1);
126 __ bind(&done);
127 __ DecrementCounter(counters->negative_lookups_miss(), 1);
128 }
129
130
131 // TODO(kmillikin): Eliminate this function when the stub cache is fully
132 // handlified.
133 MUST_USE_RESULT static MaybeObject* TryGenerateDictionaryNegativeLookup(
86 MacroAssembler* masm, 134 MacroAssembler* masm,
87 Label* miss_label, 135 Label* miss_label,
88 Register receiver, 136 Register receiver,
89 String* name, 137 String* name,
90 Register r0, 138 Register r0,
91 Register r1) { 139 Register r1) {
92 ASSERT(name->IsSymbol()); 140 ASSERT(name->IsSymbol());
93 Counters* counters = masm->isolate()->counters(); 141 Counters* counters = masm->isolate()->counters();
94 __ IncrementCounter(counters->negative_lookups(), 1); 142 __ IncrementCounter(counters->negative_lookups(), 1);
95 __ IncrementCounter(counters->negative_lookups_miss(), 1); 143 __ IncrementCounter(counters->negative_lookups_miss(), 1);
(...skipping 15 matching lines...) Expand all
111 // Load properties array. 159 // Load properties array.
112 Register properties = r0; 160 Register properties = r0;
113 __ movq(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); 161 __ movq(properties, FieldOperand(receiver, JSObject::kPropertiesOffset));
114 162
115 // Check that the properties array is a dictionary. 163 // Check that the properties array is a dictionary.
116 __ CompareRoot(FieldOperand(properties, HeapObject::kMapOffset), 164 __ CompareRoot(FieldOperand(properties, HeapObject::kMapOffset),
117 Heap::kHashTableMapRootIndex); 165 Heap::kHashTableMapRootIndex);
118 __ j(not_equal, miss_label); 166 __ j(not_equal, miss_label);
119 167
120 Label done; 168 Label done;
121 MaybeObject* result = StringDictionaryLookupStub::GenerateNegativeLookup( 169 MaybeObject* result = StringDictionaryLookupStub::TryGenerateNegativeLookup(
122 masm, 170 masm,
123 miss_label, 171 miss_label,
124 &done, 172 &done,
125 properties, 173 properties,
126 name, 174 name,
127 r1); 175 r1);
128 if (result->IsFailure()) return result; 176 if (result->IsFailure()) return result;
129 177
130 __ bind(&done); 178 __ bind(&done);
131 __ DecrementCounter(counters->negative_lookups_miss(), 1); 179 __ DecrementCounter(counters->negative_lookups_miss(), 1);
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 __ TryGetFunctionPrototype(receiver, result, miss_label); 353 __ TryGetFunctionPrototype(receiver, result, miss_label);
306 if (!result.is(rax)) __ movq(rax, result); 354 if (!result.is(rax)) __ movq(rax, result);
307 __ ret(0); 355 __ ret(0);
308 } 356 }
309 357
310 358
311 // Load a fast property out of a holder object (src). In-object properties 359 // Load a fast property out of a holder object (src). In-object properties
312 // are loaded directly otherwise the property is loaded from the properties 360 // are loaded directly otherwise the property is loaded from the properties
313 // fixed array. 361 // fixed array.
314 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, 362 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
315 Register dst, Register src, 363 Register dst,
316 JSObject* holder, int index) { 364 Register src,
365 Handle<JSObject> holder,
366 int index) {
317 // Adjust for the number of properties stored in the holder. 367 // Adjust for the number of properties stored in the holder.
318 index -= holder->map()->inobject_properties(); 368 index -= holder->map()->inobject_properties();
319 if (index < 0) { 369 if (index < 0) {
320 // Get the property straight out of the holder. 370 // Get the property straight out of the holder.
321 int offset = holder->map()->instance_size() + (index * kPointerSize); 371 int offset = holder->map()->instance_size() + (index * kPointerSize);
322 __ movq(dst, FieldOperand(src, offset)); 372 __ movq(dst, FieldOperand(src, offset));
323 } else { 373 } else {
324 // Calculate the offset into the properties array. 374 // Calculate the offset into the properties array.
325 int offset = index * kPointerSize + FixedArray::kHeaderSize; 375 int offset = index * kPointerSize + FixedArray::kHeaderSize;
326 __ movq(dst, FieldOperand(src, JSObject::kPropertiesOffset)); 376 __ movq(dst, FieldOperand(src, JSObject::kPropertiesOffset));
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 743
694 StubCompiler* stub_compiler_; 744 StubCompiler* stub_compiler_;
695 const ParameterCount& arguments_; 745 const ParameterCount& arguments_;
696 Register name_; 746 Register name_;
697 Code::ExtraICState extra_ic_state_; 747 Code::ExtraICState extra_ic_state_;
698 }; 748 };
699 749
700 750
701 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { 751 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) {
702 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); 752 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
703 Code* code = NULL; 753 Handle<Code> code = (kind == Code::LOAD_IC)
704 if (kind == Code::LOAD_IC) { 754 ? masm->isolate()->builtins()->LoadIC_Miss()
705 code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss); 755 : masm->isolate()->builtins()->KeyedLoadIC_Miss();
706 } else { 756 __ Jump(code, RelocInfo::CODE_TARGET);
707 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss);
708 }
709
710 Handle<Code> ic(code);
711 __ Jump(ic, RelocInfo::CODE_TARGET);
712 } 757 }
713 758
714 759
715 void StubCompiler::GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm) { 760 void StubCompiler::GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm) {
716 Code* code = masm->isolate()->builtins()->builtin( 761 Code* code = masm->isolate()->builtins()->builtin(
717 Builtins::kKeyedLoadIC_MissForceGeneric); 762 Builtins::kKeyedLoadIC_MissForceGeneric);
718 Handle<Code> ic(code); 763 Handle<Code> ic(code);
719 __ Jump(ic, RelocInfo::CODE_TARGET); 764 __ Jump(ic, RelocInfo::CODE_TARGET);
720 } 765 }
721 766
722 767
723 // Both name_reg and receiver_reg are preserved on jumps to miss_label, 768 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
724 // but may be destroyed if store is successful. 769 // but may be destroyed if store is successful.
725 void StubCompiler::GenerateStoreField(MacroAssembler* masm, 770 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
726 JSObject* object, 771 Handle<JSObject> object,
727 int index, 772 int index,
728 Map* transition, 773 Handle<Map> transition,
729 Register receiver_reg, 774 Register receiver_reg,
730 Register name_reg, 775 Register name_reg,
731 Register scratch, 776 Register scratch,
732 Label* miss_label) { 777 Label* miss_label) {
733 // Check that the object isn't a smi. 778 // Check that the object isn't a smi.
734 __ JumpIfSmi(receiver_reg, miss_label); 779 __ JumpIfSmi(receiver_reg, miss_label);
735 780
736 // Check that the map of the object hasn't changed. 781 // Check that the map of the object hasn't changed.
737 __ Cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset), 782 __ Cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset),
738 Handle<Map>(object->map())); 783 Handle<Map>(object->map()));
739 __ j(not_equal, miss_label); 784 __ j(not_equal, miss_label);
740 785
741 // Perform global security token check if needed. 786 // Perform global security token check if needed.
742 if (object->IsJSGlobalProxy()) { 787 if (object->IsJSGlobalProxy()) {
743 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); 788 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label);
744 } 789 }
745 790
746 // Stub never generated for non-global objects that require access 791 // Stub never generated for non-global objects that require access
747 // checks. 792 // checks.
748 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 793 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
749 794
750 // Perform map transition for the receiver if necessary. 795 // Perform map transition for the receiver if necessary.
751 if ((transition != NULL) && (object->map()->unused_property_fields() == 0)) { 796 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) {
752 // The properties must be extended before we can store the value. 797 // The properties must be extended before we can store the value.
753 // We jump to a runtime call that extends the properties array. 798 // We jump to a runtime call that extends the properties array.
754 __ pop(scratch); // Return address. 799 __ pop(scratch); // Return address.
755 __ push(receiver_reg); 800 __ push(receiver_reg);
756 __ Push(Handle<Map>(transition)); 801 __ Push(transition);
757 __ push(rax); 802 __ push(rax);
758 __ push(scratch); 803 __ push(scratch);
759 __ TailCallExternalReference( 804 __ TailCallExternalReference(
760 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 805 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
761 masm->isolate()), 806 masm->isolate()),
762 3, 807 3,
763 1); 808 1);
764 return; 809 return;
765 } 810 }
766 811
767 if (transition != NULL) { 812 if (!transition.is_null()) {
768 // Update the map of the object; no write barrier updating is 813 // Update the map of the object; no write barrier updating is
769 // needed because the map is never in new space. 814 // needed because the map is never in new space.
770 __ Move(FieldOperand(receiver_reg, HeapObject::kMapOffset), 815 __ Move(FieldOperand(receiver_reg, HeapObject::kMapOffset), transition);
771 Handle<Map>(transition));
772 } 816 }
773 817
774 // Adjust for the number of properties stored in the object. Even in the 818 // Adjust for the number of properties stored in the object. Even in the
775 // face of a transition we can use the old map here because the size of the 819 // face of a transition we can use the old map here because the size of the
776 // object and the number of in-object properties is not going to change. 820 // object and the number of in-object properties is not going to change.
777 index -= object->map()->inobject_properties(); 821 index -= object->map()->inobject_properties();
778 822
779 if (index < 0) { 823 if (index < 0) {
780 // Set the property straight into the object. 824 // Set the property straight into the object.
781 int offset = object->map()->instance_size() + (index * kPointerSize); 825 int offset = object->map()->instance_size() + (index * kPointerSize);
(...skipping 19 matching lines...) Expand all
801 } 845 }
802 846
803 // Return the value (register rax). 847 // Return the value (register rax).
804 __ ret(0); 848 __ ret(0);
805 } 849 }
806 850
807 851
808 // Generate code to check that a global property cell is empty. Create 852 // Generate code to check that a global property cell is empty. Create
809 // the property cell at compilation time if no cell exists for the 853 // the property cell at compilation time if no cell exists for the
810 // property. 854 // property.
811 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCell( 855 static void GenerateCheckPropertyCell(MacroAssembler* masm,
856 Handle<GlobalObject> global,
857 Handle<String> name,
858 Register scratch,
859 Label* miss) {
860 Handle<JSGlobalPropertyCell> cell =
861 GlobalObject::EnsurePropertyCell(global, name);
862 ASSERT(cell->value()->IsTheHole());
863 __ Move(scratch, cell);
864 __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset),
865 masm->isolate()->factory()->the_hole_value());
866 __ j(not_equal, miss);
867 }
868
869
870 // TODO(kmillikin): Eliminate this function when the stub cache is fully
871 // handlified.
872 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCell(
812 MacroAssembler* masm, 873 MacroAssembler* masm,
813 GlobalObject* global, 874 GlobalObject* global,
814 String* name, 875 String* name,
815 Register scratch, 876 Register scratch,
816 Label* miss) { 877 Label* miss) {
817 Object* probe; 878 Object* probe;
818 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); 879 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name);
819 if (!maybe_probe->ToObject(&probe)) return maybe_probe; 880 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
820 } 881 }
821 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); 882 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe);
822 ASSERT(cell->value()->IsTheHole()); 883 ASSERT(cell->value()->IsTheHole());
823 __ Move(scratch, Handle<Object>(cell)); 884 __ Move(scratch, Handle<Object>(cell));
824 __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), 885 __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset),
825 masm->isolate()->factory()->the_hole_value()); 886 masm->isolate()->factory()->the_hole_value());
826 __ j(not_equal, miss); 887 __ j(not_equal, miss);
827 return cell; 888 return cell;
828 } 889 }
829 890
830 891
892 // Calls GenerateCheckPropertyCell for each global object in the prototype chain
893 // from object to (but not including) holder.
894 static void GenerateCheckPropertyCells(MacroAssembler* masm,
895 Handle<JSObject> object,
896 Handle<JSObject> holder,
897 Handle<String> name,
898 Register scratch,
899 Label* miss) {
900 Handle<JSObject> current = object;
901 while (!current.is_identical_to(holder)) {
902 if (current->IsGlobalObject()) {
903 GenerateCheckPropertyCell(masm,
904 Handle<GlobalObject>::cast(current),
905 name,
906 scratch,
907 miss);
908 }
909 current = Handle<JSObject>(JSObject::cast(current->GetPrototype()));
910 }
911 }
912
913
914 // TODO(kmillikin): Eliminate this function when the stub cache is fully
915 // handlified.
916 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCells(
917 MacroAssembler* masm,
918 JSObject* object,
919 JSObject* holder,
920 String* name,
921 Register scratch,
922 Label* miss) {
923 JSObject* current = object;
924 while (current != holder) {
925 if (current->IsGlobalObject()) {
926 // Returns a cell or a failure.
927 MaybeObject* result = TryGenerateCheckPropertyCell(
928 masm,
929 GlobalObject::cast(current),
930 name,
931 scratch,
932 miss);
933 if (result->IsFailure()) return result;
934 }
935 ASSERT(current->IsJSObject());
936 current = JSObject::cast(current->GetPrototype());
937 }
938 return NULL;
939 }
940
941
831 #undef __ 942 #undef __
832 #define __ ACCESS_MASM((masm())) 943 #define __ ACCESS_MASM((masm()))
833 944
834 945
946 Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
947 Register object_reg,
948 Handle<JSObject> holder,
949 Register holder_reg,
950 Register scratch1,
951 Register scratch2,
952 Handle<String> name,
953 int save_at_depth,
954 Label* miss) {
955 // Make sure there's no overlap between holder and object registers.
956 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
957 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
958 && !scratch2.is(scratch1));
959
960 // Keep track of the current object in register reg. On the first
961 // iteration, reg is an alias for object_reg, on later iterations,
962 // it is an alias for holder_reg.
963 Register reg = object_reg;
964 int depth = 0;
965
966 if (save_at_depth == depth) {
967 __ movq(Operand(rsp, kPointerSize), object_reg);
968 }
969
970 // Check the maps in the prototype chain.
971 // Traverse the prototype chain from the object and do map checks.
972 Handle<JSObject> current = object;
973 while (!current.is_identical_to(holder)) {
974 ++depth;
975
976 // Only global objects and objects that do not require access
977 // checks are allowed in stubs.
978 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded());
979
980 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype()));
981 if (!current->HasFastProperties() &&
982 !current->IsJSGlobalObject() &&
983 !current->IsJSGlobalProxy()) {
984 if (!name->IsSymbol()) {
985 name = factory()->LookupSymbol(name);
986 }
987 ASSERT(current->property_dictionary()->FindEntry(*name) ==
988 StringDictionary::kNotFound);
989
990 GenerateDictionaryNegativeLookup(masm(), miss, reg, name,
991 scratch1, scratch2);
992
993 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
994 reg = holder_reg; // From now on the object will be in holder_reg.
995 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
996 } else {
997 bool in_new_space = heap()->InNewSpace(*prototype);
998 Handle<Map> current_map(current->map());
999 if (in_new_space) {
1000 // Save the map in scratch1 for later.
1001 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
1002 __ Cmp(scratch1, current_map);
1003 } else {
1004 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), current_map);
1005 }
1006 // Branch on the result of the map check.
1007 __ j(not_equal, miss);
1008 // Check access rights to the global object. This has to happen after
1009 // the map check so that we know that the object is actually a global
1010 // object.
1011 if (current->IsJSGlobalProxy()) {
1012 __ CheckAccessGlobalProxy(reg, scratch2, miss);
1013 }
1014 reg = holder_reg; // From now on the object will be in holder_reg.
1015
1016 if (in_new_space) {
1017 // The prototype is in new space; we cannot store a reference to it
1018 // in the code. Load it from the map.
1019 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
1020 } else {
1021 // The prototype is in old space; load it directly.
1022 __ Move(reg, prototype);
1023 }
1024 }
1025
1026 if (save_at_depth == depth) {
1027 __ movq(Operand(rsp, kPointerSize), reg);
1028 }
1029
1030 // Go to the next object in the prototype chain.
1031 current = prototype;
1032 }
1033 ASSERT(current.is_identical_to(holder));
1034
1035 // Log the check depth.
1036 LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
1037
1038 // Check the holder map.
1039 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), Handle<Map>(holder->map()));
1040 __ j(not_equal, miss);
1041
1042 // Perform security check for access to the global object.
1043 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded());
1044 if (current->IsJSGlobalProxy()) {
1045 __ CheckAccessGlobalProxy(reg, scratch1, miss);
1046 }
1047
1048 // If we've skipped any global objects, it's not enough to verify that
1049 // their maps haven't changed. We also need to check that the property
1050 // cell for the property is still empty.
1051 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss);
1052
1053 // Return the register containing the holder.
1054 return reg;
1055 }
1056
1057
835 Register StubCompiler::CheckPrototypes(JSObject* object, 1058 Register StubCompiler::CheckPrototypes(JSObject* object,
836 Register object_reg, 1059 Register object_reg,
837 JSObject* holder, 1060 JSObject* holder,
838 Register holder_reg, 1061 Register holder_reg,
839 Register scratch1, 1062 Register scratch1,
840 Register scratch2, 1063 Register scratch2,
841 String* name, 1064 String* name,
842 int save_at_depth, 1065 int save_at_depth,
843 Label* miss) { 1066 Label* miss) {
844 // Make sure there's no overlap between holder and object registers. 1067 // Make sure there's no overlap between holder and object registers.
(...skipping 30 matching lines...) Expand all
875 if (lookup_result->IsFailure()) { 1098 if (lookup_result->IsFailure()) {
876 set_failure(Failure::cast(lookup_result)); 1099 set_failure(Failure::cast(lookup_result));
877 return reg; 1100 return reg;
878 } else { 1101 } else {
879 name = String::cast(lookup_result->ToObjectUnchecked()); 1102 name = String::cast(lookup_result->ToObjectUnchecked());
880 } 1103 }
881 } 1104 }
882 ASSERT(current->property_dictionary()->FindEntry(name) == 1105 ASSERT(current->property_dictionary()->FindEntry(name) ==
883 StringDictionary::kNotFound); 1106 StringDictionary::kNotFound);
884 1107
885 MaybeObject* negative_lookup = GenerateDictionaryNegativeLookup(masm(), 1108 MaybeObject* negative_lookup =
886 miss, 1109 TryGenerateDictionaryNegativeLookup(masm(),
887 reg, 1110 miss,
888 name, 1111 reg,
889 scratch1, 1112 name,
890 scratch2); 1113 scratch1,
1114 scratch2);
891 if (negative_lookup->IsFailure()) { 1115 if (negative_lookup->IsFailure()) {
892 set_failure(Failure::cast(negative_lookup)); 1116 set_failure(Failure::cast(negative_lookup));
893 return reg; 1117 return reg;
894 } 1118 }
895 1119
896 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 1120 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
897 reg = holder_reg; // from now the object is in holder_reg 1121 reg = holder_reg; // from now the object is in holder_reg
898 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 1122 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
899 } else if (heap()->InNewSpace(prototype)) { 1123 } else if (heap()->InNewSpace(prototype)) {
900 // Get the map of the current object. 1124 // Get the map of the current object.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
953 // the holder register. 1177 // the holder register.
954 ASSERT(current == holder); 1178 ASSERT(current == holder);
955 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); 1179 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded());
956 if (current->IsJSGlobalProxy()) { 1180 if (current->IsJSGlobalProxy()) {
957 __ CheckAccessGlobalProxy(reg, scratch1, miss); 1181 __ CheckAccessGlobalProxy(reg, scratch1, miss);
958 } 1182 }
959 1183
960 // If we've skipped any global objects, it's not enough to verify 1184 // If we've skipped any global objects, it's not enough to verify
961 // that their maps haven't changed. We also need to check that the 1185 // that their maps haven't changed. We also need to check that the
962 // property cell for the property is still empty. 1186 // property cell for the property is still empty.
963 current = object; 1187 MaybeObject* result = TryGenerateCheckPropertyCells(masm(),
964 while (current != holder) { 1188 object,
965 if (current->IsGlobalObject()) { 1189 holder,
966 MaybeObject* cell = GenerateCheckPropertyCell(masm(), 1190 name,
967 GlobalObject::cast(current), 1191 scratch1,
968 name, 1192 miss);
969 scratch1, 1193 if (result->IsFailure()) set_failure(Failure::cast(result));
970 miss);
971 if (cell->IsFailure()) {
972 set_failure(Failure::cast(cell));
973 return reg;
974 }
975 }
976 current = JSObject::cast(current->GetPrototype());
977 }
978 1194
979 // Return the register containing the holder. 1195 // Return the register containing the holder.
980 return reg; 1196 return reg;
981 } 1197 }
982 1198
983 1199
984 void StubCompiler::GenerateLoadField(JSObject* object, 1200 void StubCompiler::GenerateLoadField(Handle<JSObject> object,
985 JSObject* holder, 1201 Handle<JSObject> holder,
986 Register receiver, 1202 Register receiver,
987 Register scratch1, 1203 Register scratch1,
988 Register scratch2, 1204 Register scratch2,
989 Register scratch3, 1205 Register scratch3,
990 int index, 1206 int index,
991 String* name, 1207 Handle<String> name,
992 Label* miss) { 1208 Label* miss) {
993 // Check that the receiver isn't a smi. 1209 // Check that the receiver isn't a smi.
994 __ JumpIfSmi(receiver, miss); 1210 __ JumpIfSmi(receiver, miss);
995 1211
996 // Check the prototype chain. 1212 // Check the prototype chain.
997 Register reg = 1213 Register reg = CheckPrototypes(
998 CheckPrototypes(object, receiver, holder, 1214 object, receiver, holder, scratch1, scratch2, scratch3, name, miss);
999 scratch1, scratch2, scratch3, name, miss);
1000 1215
1001 // Get the value from the properties. 1216 // Get the value from the properties.
1002 GenerateFastPropertyLoad(masm(), rax, reg, holder, index); 1217 GenerateFastPropertyLoad(masm(), rax, reg, holder, index);
1003 __ ret(0); 1218 __ ret(0);
1004 } 1219 }
1005 1220
1006 1221
1007 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, 1222 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object,
1008 JSObject* holder, 1223 JSObject* holder,
1009 Register receiver, 1224 Register receiver,
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 __ lea(accessor_info_arg, StackSpaceOperand(0)); 1289 __ lea(accessor_info_arg, StackSpaceOperand(0));
1075 1290
1076 // Emitting a stub call may try to allocate (if the code is not 1291 // Emitting a stub call may try to allocate (if the code is not
1077 // already generated). Do not allow the assembler to perform a 1292 // already generated). Do not allow the assembler to perform a
1078 // garbage collection but instead return the allocation failure 1293 // garbage collection but instead return the allocation failure
1079 // object. 1294 // object.
1080 return masm()->TryCallApiFunctionAndReturn(&fun, kStackSpace); 1295 return masm()->TryCallApiFunctionAndReturn(&fun, kStackSpace);
1081 } 1296 }
1082 1297
1083 1298
1084 void StubCompiler::GenerateLoadConstant(JSObject* object, 1299 void StubCompiler::GenerateLoadConstant(Handle<JSObject> object,
1085 JSObject* holder, 1300 Handle<JSObject> holder,
1086 Register receiver, 1301 Register receiver,
1087 Register scratch1, 1302 Register scratch1,
1088 Register scratch2, 1303 Register scratch2,
1089 Register scratch3, 1304 Register scratch3,
1090 Object* value, 1305 Handle<Object> value,
1091 String* name, 1306 Handle<String> name,
1092 Label* miss) { 1307 Label* miss) {
1093 // Check that the receiver isn't a smi. 1308 // Check that the receiver isn't a smi.
1094 __ JumpIfSmi(receiver, miss); 1309 __ JumpIfSmi(receiver, miss);
1095 1310
1096 // Check that the maps haven't changed. 1311 // Check that the maps haven't changed.
1097 CheckPrototypes(object, receiver, holder, 1312 CheckPrototypes(
1098 scratch1, scratch2, scratch3, name, miss); 1313 object, receiver, holder, scratch1, scratch2, scratch3, name, miss);
1099 1314
1100 // Return the constant value. 1315 // Return the constant value.
1101 __ Move(rax, Handle<Object>(value)); 1316 __ Move(rax, value);
1102 __ ret(0); 1317 __ ret(0);
1103 } 1318 }
1104 1319
1105 1320
1106 void StubCompiler::GenerateLoadInterceptor(JSObject* object, 1321 void StubCompiler::GenerateLoadInterceptor(JSObject* object,
1107 JSObject* interceptor_holder, 1322 JSObject* interceptor_holder,
1108 LookupResult* lookup, 1323 LookupResult* lookup,
1109 Register receiver, 1324 Register receiver,
1110 Register name_reg, 1325 Register name_reg,
1111 Register scratch1, 1326 Register scratch1,
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 scratch2, 1406 scratch2,
1192 scratch3, 1407 scratch3,
1193 name, 1408 name,
1194 miss); 1409 miss);
1195 } 1410 }
1196 1411
1197 if (lookup->type() == FIELD) { 1412 if (lookup->type() == FIELD) {
1198 // We found FIELD property in prototype chain of interceptor's holder. 1413 // We found FIELD property in prototype chain of interceptor's holder.
1199 // Retrieve a field from field's holder. 1414 // Retrieve a field from field's holder.
1200 GenerateFastPropertyLoad(masm(), rax, holder_reg, 1415 GenerateFastPropertyLoad(masm(), rax, holder_reg,
1201 lookup->holder(), lookup->GetFieldIndex()); 1416 Handle<JSObject>(lookup->holder()),
1417 lookup->GetFieldIndex());
1202 __ ret(0); 1418 __ ret(0);
1203 } else { 1419 } else {
1204 // We found CALLBACKS property in prototype chain of interceptor's 1420 // We found CALLBACKS property in prototype chain of interceptor's
1205 // holder. 1421 // holder.
1206 ASSERT(lookup->type() == CALLBACKS); 1422 ASSERT(lookup->type() == CALLBACKS);
1207 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); 1423 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo());
1208 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); 1424 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject());
1209 ASSERT(callback != NULL); 1425 ASSERT(callback != NULL);
1210 ASSERT(callback->getter() != NULL); 1426 ASSERT(callback->getter() != NULL);
1211 1427
(...skipping 25 matching lines...) Expand all
1237 name_reg, interceptor_holder); 1453 name_reg, interceptor_holder);
1238 __ push(scratch2); // restore old return address 1454 __ push(scratch2); // restore old return address
1239 1455
1240 ExternalReference ref = ExternalReference( 1456 ExternalReference ref = ExternalReference(
1241 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate()); 1457 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate());
1242 __ TailCallExternalReference(ref, 5, 1); 1458 __ TailCallExternalReference(ref, 5, 1);
1243 } 1459 }
1244 } 1460 }
1245 1461
1246 1462
1247 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { 1463 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) {
1248 if (kind_ == Code::KEYED_CALL_IC) { 1464 if (kind_ == Code::KEYED_CALL_IC) {
1249 __ Cmp(rcx, Handle<String>(name)); 1465 __ Cmp(rcx, name);
1250 __ j(not_equal, miss); 1466 __ j(not_equal, miss);
1251 } 1467 }
1252 } 1468 }
1253 1469
1254 1470
1255 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, 1471 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object,
1256 JSObject* holder, 1472 JSObject* holder,
1257 String* name, 1473 String* name,
1258 Label* miss) { 1474 Label* miss) {
1259 ASSERT(holder->IsGlobalObject()); 1475 ASSERT(holder->IsGlobalObject());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1298 __ Move(rax, Handle<SharedFunctionInfo>(function->shared())); 1514 __ Move(rax, Handle<SharedFunctionInfo>(function->shared()));
1299 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax); 1515 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax);
1300 __ j(not_equal, miss); 1516 __ j(not_equal, miss);
1301 } else { 1517 } else {
1302 __ Cmp(rdi, Handle<JSFunction>(function)); 1518 __ Cmp(rdi, Handle<JSFunction>(function));
1303 __ j(not_equal, miss); 1519 __ j(not_equal, miss);
1304 } 1520 }
1305 } 1521 }
1306 1522
1307 1523
1308 MaybeObject* CallStubCompiler::GenerateMissBranch() { 1524 void CallStubCompiler::GenerateMissBranch() {
1309 MaybeObject* maybe_obj = 1525 Handle<Code> code =
1310 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), 1526 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(),
1311 kind_, 1527 kind_,
1312 extra_ic_state_); 1528 extra_state_);
1529 __ Jump(code, RelocInfo::CODE_TARGET);
1530 }
1531
1532
1533 // TODO(kmillikin): Eliminate this function when the stub cache is fully
1534 // handlified.
1535 MaybeObject* CallStubCompiler::TryGenerateMissBranch() {
1536 MaybeObject* maybe_obj =
1537 isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(),
1538 kind_,
1539 extra_state_);
1313 Object* obj; 1540 Object* obj;
1314 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1541 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1315 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); 1542 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET);
1316 return obj; 1543 return obj;
1317 } 1544 }
1318 1545
1319 1546
1320 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object, 1547 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
1321 JSObject* holder, 1548 Handle<JSObject> holder,
1322 int index, 1549 int index,
1323 String* name) { 1550 Handle<String> name) {
1324 // ----------- S t a t e ------------- 1551 // ----------- S t a t e -------------
1325 // rcx : function name 1552 // rcx : function name
1326 // rsp[0] : return address 1553 // rsp[0] : return address
1327 // rsp[8] : argument argc 1554 // rsp[8] : argument argc
1328 // rsp[16] : argument argc - 1 1555 // rsp[16] : argument argc - 1
1329 // ... 1556 // ...
1330 // rsp[argc * 8] : argument 1 1557 // rsp[argc * 8] : argument 1
1331 // rsp[(argc + 1) * 8] : argument 0 = receiver 1558 // rsp[(argc + 1) * 8] : argument 0 = receiver
1332 // ----------------------------------- 1559 // -----------------------------------
1333 Label miss; 1560 Label miss;
(...skipping 19 matching lines...) Expand all
1353 __ j(not_equal, &miss); 1580 __ j(not_equal, &miss);
1354 1581
1355 // Patch the receiver on the stack with the global proxy if 1582 // Patch the receiver on the stack with the global proxy if
1356 // necessary. 1583 // necessary.
1357 if (object->IsGlobalObject()) { 1584 if (object->IsGlobalObject()) {
1358 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 1585 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
1359 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 1586 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
1360 } 1587 }
1361 1588
1362 // Invoke the function. 1589 // Invoke the function.
1363 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) 1590 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
1364 ? CALL_AS_FUNCTION 1591 ? CALL_AS_FUNCTION
1365 : CALL_AS_METHOD; 1592 : CALL_AS_METHOD;
1366 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, 1593 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
1367 NullCallWrapper(), call_kind); 1594 NullCallWrapper(), call_kind);
1368 1595
1369 // Handle call cache miss. 1596 // Handle call cache miss.
1370 __ bind(&miss); 1597 __ bind(&miss);
1371 MaybeObject* maybe_result = GenerateMissBranch(); 1598 GenerateMissBranch();
1372 if (maybe_result->IsFailure()) return maybe_result;
1373 1599
1374 // Return the generated code. 1600 // Return the generated code.
1375 return GetCode(FIELD, name); 1601 return GetCode(FIELD, name);
1376 } 1602 }
1377 1603
1378 1604
1379 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, 1605 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object,
1380 JSObject* holder, 1606 JSObject* holder,
1381 JSGlobalPropertyCell* cell, 1607 JSGlobalPropertyCell* cell,
1382 JSFunction* function, 1608 JSFunction* function,
1383 String* name) { 1609 String* name) {
1384 // ----------- S t a t e ------------- 1610 // ----------- S t a t e -------------
1385 // -- rcx : name 1611 // -- rcx : name
1386 // -- rsp[0] : return address 1612 // -- rsp[0] : return address
1387 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 1613 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
1388 // -- ... 1614 // -- ...
1389 // -- rsp[(argc + 1) * 8] : receiver 1615 // -- rsp[(argc + 1) * 8] : receiver
1390 // ----------------------------------- 1616 // -----------------------------------
1391 1617
1392 // If object is not an array, bail out to regular call. 1618 // If object is not an array, bail out to regular call.
1393 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); 1619 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value();
1394 1620
1395 Label miss; 1621 Label miss;
1396 1622
1397 GenerateNameCheck(name, &miss); 1623 GenerateNameCheck(Handle<String>(name), &miss);
1398 1624
1399 // Get the receiver from the stack. 1625 // Get the receiver from the stack.
1400 const int argc = arguments().immediate(); 1626 const int argc = arguments().immediate();
1401 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 1627 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
1402 1628
1403 // Check that the receiver isn't a smi. 1629 // Check that the receiver isn't a smi.
1404 __ JumpIfSmi(rdx, &miss); 1630 __ JumpIfSmi(rdx, &miss);
1405 1631
1406 CheckPrototypes(JSObject::cast(object), 1632 CheckPrototypes(JSObject::cast(object),
1407 rdx, 1633 rdx,
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1481 __ bind(&attempt_to_grow_elements); 1707 __ bind(&attempt_to_grow_elements);
1482 if (!FLAG_inline_new) { 1708 if (!FLAG_inline_new) {
1483 __ jmp(&call_builtin); 1709 __ jmp(&call_builtin);
1484 } 1710 }
1485 1711
1486 __ movq(rdi, Operand(rsp, argc * kPointerSize)); 1712 __ movq(rdi, Operand(rsp, argc * kPointerSize));
1487 // Growing elements that are SMI-only requires special handling in case 1713 // Growing elements that are SMI-only requires special handling in case
1488 // the new element is non-Smi. For now, delegate to the builtin. 1714 // the new element is non-Smi. For now, delegate to the builtin.
1489 Label no_fast_elements_check; 1715 Label no_fast_elements_check;
1490 __ JumpIfSmi(rdi, &no_fast_elements_check); 1716 __ JumpIfSmi(rdi, &no_fast_elements_check);
1491 __ movq(rsi, FieldOperand(rdx, HeapObject::kMapOffset)); 1717 __ movq(rcx, FieldOperand(rdx, HeapObject::kMapOffset));
1492 __ CheckFastObjectElements(rsi, &call_builtin, Label::kFar); 1718 __ CheckFastObjectElements(rcx, &call_builtin, Label::kFar);
1493 __ bind(&no_fast_elements_check); 1719 __ bind(&no_fast_elements_check);
1494 1720
1495 ExternalReference new_space_allocation_top = 1721 ExternalReference new_space_allocation_top =
1496 ExternalReference::new_space_allocation_top_address(isolate()); 1722 ExternalReference::new_space_allocation_top_address(isolate());
1497 ExternalReference new_space_allocation_limit = 1723 ExternalReference new_space_allocation_limit =
1498 ExternalReference::new_space_allocation_limit_address(isolate()); 1724 ExternalReference::new_space_allocation_limit_address(isolate());
1499 1725
1500 const int kAllocationDelta = 4; 1726 const int kAllocationDelta = 4;
1501 // Load top. 1727 // Load top.
1502 __ Load(rcx, new_space_allocation_top); 1728 __ Load(rcx, new_space_allocation_top);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1546 } 1772 }
1547 1773
1548 __ bind(&call_builtin); 1774 __ bind(&call_builtin);
1549 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, 1775 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush,
1550 isolate()), 1776 isolate()),
1551 argc + 1, 1777 argc + 1,
1552 1); 1778 1);
1553 } 1779 }
1554 1780
1555 __ bind(&miss); 1781 __ bind(&miss);
1556 MaybeObject* maybe_result = GenerateMissBranch(); 1782 MaybeObject* maybe_result = TryGenerateMissBranch();
1557 if (maybe_result->IsFailure()) return maybe_result; 1783 if (maybe_result->IsFailure()) return maybe_result;
1558 1784
1559 // Return the generated code. 1785 // Return the generated code.
1560 return GetCode(function); 1786 return TryGetCode(function);
1561 } 1787 }
1562 1788
1563 1789
1564 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, 1790 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object,
1565 JSObject* holder, 1791 JSObject* holder,
1566 JSGlobalPropertyCell* cell, 1792 JSGlobalPropertyCell* cell,
1567 JSFunction* function, 1793 JSFunction* function,
1568 String* name) { 1794 String* name) {
1569 // ----------- S t a t e ------------- 1795 // ----------- S t a t e -------------
1570 // -- rcx : name 1796 // -- rcx : name
1571 // -- rsp[0] : return address 1797 // -- rsp[0] : return address
1572 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 1798 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
1573 // -- ... 1799 // -- ...
1574 // -- rsp[(argc + 1) * 8] : receiver 1800 // -- rsp[(argc + 1) * 8] : receiver
1575 // ----------------------------------- 1801 // -----------------------------------
1576 1802
1577 // If object is not an array, bail out to regular call. 1803 // If object is not an array, bail out to regular call.
1578 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); 1804 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value();
1579 1805
1580 Label miss, return_undefined, call_builtin; 1806 Label miss, return_undefined, call_builtin;
1581 1807
1582 GenerateNameCheck(name, &miss); 1808 GenerateNameCheck(Handle<String>(name), &miss);
1583 1809
1584 // Get the receiver from the stack. 1810 // Get the receiver from the stack.
1585 const int argc = arguments().immediate(); 1811 const int argc = arguments().immediate();
1586 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 1812 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
1587 1813
1588 // Check that the receiver isn't a smi. 1814 // Check that the receiver isn't a smi.
1589 __ JumpIfSmi(rdx, &miss); 1815 __ JumpIfSmi(rdx, &miss);
1590 1816
1591 CheckPrototypes(JSObject::cast(object), rdx, 1817 CheckPrototypes(JSObject::cast(object), rdx,
1592 holder, rbx, 1818 holder, rbx,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1629 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 1855 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
1630 __ ret((argc + 1) * kPointerSize); 1856 __ ret((argc + 1) * kPointerSize);
1631 1857
1632 __ bind(&call_builtin); 1858 __ bind(&call_builtin);
1633 __ TailCallExternalReference( 1859 __ TailCallExternalReference(
1634 ExternalReference(Builtins::c_ArrayPop, isolate()), 1860 ExternalReference(Builtins::c_ArrayPop, isolate()),
1635 argc + 1, 1861 argc + 1,
1636 1); 1862 1);
1637 1863
1638 __ bind(&miss); 1864 __ bind(&miss);
1639 MaybeObject* maybe_result = GenerateMissBranch(); 1865 MaybeObject* maybe_result = TryGenerateMissBranch();
1640 if (maybe_result->IsFailure()) return maybe_result; 1866 if (maybe_result->IsFailure()) return maybe_result;
1641 1867
1642 // Return the generated code. 1868 // Return the generated code.
1643 return GetCode(function); 1869 return TryGetCode(function);
1644 } 1870 }
1645 1871
1646 1872
1647 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( 1873 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall(
1648 Object* object, 1874 Object* object,
1649 JSObject* holder, 1875 JSObject* holder,
1650 JSGlobalPropertyCell* cell, 1876 JSGlobalPropertyCell* cell,
1651 JSFunction* function, 1877 JSFunction* function,
1652 String* name) { 1878 String* name) {
1653 // ----------- S t a t e ------------- 1879 // ----------- S t a t e -------------
1654 // -- rcx : function name 1880 // -- rcx : function name
1655 // -- rsp[0] : return address 1881 // -- rsp[0] : return address
1656 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 1882 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
1657 // -- ... 1883 // -- ...
1658 // -- rsp[(argc + 1) * 8] : receiver 1884 // -- rsp[(argc + 1) * 8] : receiver
1659 // ----------------------------------- 1885 // -----------------------------------
1660 1886
1661 // If object is not a string, bail out to regular call. 1887 // If object is not a string, bail out to regular call.
1662 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); 1888 if (!object->IsString() || cell != NULL) return heap()->undefined_value();
1663 1889
1664 const int argc = arguments().immediate(); 1890 const int argc = arguments().immediate();
1665 1891
1666 Label miss; 1892 Label miss;
1667 Label name_miss; 1893 Label name_miss;
1668 Label index_out_of_range; 1894 Label index_out_of_range;
1669 Label* index_out_of_range_label = &index_out_of_range; 1895 Label* index_out_of_range_label = &index_out_of_range;
1670 1896
1671 if (kind_ == Code::CALL_IC && 1897 if (kind_ == Code::CALL_IC &&
1672 (CallICBase::StringStubState::decode(extra_ic_state_) == 1898 (CallICBase::StringStubState::decode(extra_state_) ==
1673 DEFAULT_STRING_STUB)) { 1899 DEFAULT_STRING_STUB)) {
1674 index_out_of_range_label = &miss; 1900 index_out_of_range_label = &miss;
1675 } 1901 }
1676 1902
1677 GenerateNameCheck(name, &name_miss); 1903 GenerateNameCheck(Handle<String>(name), &name_miss);
1678 1904
1679 // Check that the maps starting from the prototype haven't changed. 1905 // Check that the maps starting from the prototype haven't changed.
1680 GenerateDirectLoadGlobalFunctionPrototype(masm(), 1906 GenerateDirectLoadGlobalFunctionPrototype(masm(),
1681 Context::STRING_FUNCTION_INDEX, 1907 Context::STRING_FUNCTION_INDEX,
1682 rax, 1908 rax,
1683 &miss); 1909 &miss);
1684 ASSERT(object != holder); 1910 ASSERT(object != holder);
1685 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, 1911 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
1686 rbx, rdx, rdi, name, &miss); 1912 rbx, rdx, rdi, name, &miss);
1687 1913
(...skipping 25 matching lines...) Expand all
1713 if (index_out_of_range.is_linked()) { 1939 if (index_out_of_range.is_linked()) {
1714 __ bind(&index_out_of_range); 1940 __ bind(&index_out_of_range);
1715 __ LoadRoot(rax, Heap::kNanValueRootIndex); 1941 __ LoadRoot(rax, Heap::kNanValueRootIndex);
1716 __ ret((argc + 1) * kPointerSize); 1942 __ ret((argc + 1) * kPointerSize);
1717 } 1943 }
1718 1944
1719 __ bind(&miss); 1945 __ bind(&miss);
1720 // Restore function name in rcx. 1946 // Restore function name in rcx.
1721 __ Move(rcx, Handle<String>(name)); 1947 __ Move(rcx, Handle<String>(name));
1722 __ bind(&name_miss); 1948 __ bind(&name_miss);
1723 MaybeObject* maybe_result = GenerateMissBranch(); 1949 MaybeObject* maybe_result = TryGenerateMissBranch();
1724 if (maybe_result->IsFailure()) return maybe_result; 1950 if (maybe_result->IsFailure()) return maybe_result;
1725 1951
1726 // Return the generated code. 1952 // Return the generated code.
1727 return GetCode(function); 1953 return TryGetCode(function);
1728 } 1954 }
1729 1955
1730 1956
1731 MaybeObject* CallStubCompiler::CompileStringCharAtCall( 1957 MaybeObject* CallStubCompiler::CompileStringCharAtCall(
1732 Object* object, 1958 Object* object,
1733 JSObject* holder, 1959 JSObject* holder,
1734 JSGlobalPropertyCell* cell, 1960 JSGlobalPropertyCell* cell,
1735 JSFunction* function, 1961 JSFunction* function,
1736 String* name) { 1962 String* name) {
1737 // ----------- S t a t e ------------- 1963 // ----------- S t a t e -------------
1738 // -- rcx : function name 1964 // -- rcx : function name
1739 // -- rsp[0] : return address 1965 // -- rsp[0] : return address
1740 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 1966 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
1741 // -- ... 1967 // -- ...
1742 // -- rsp[(argc + 1) * 8] : receiver 1968 // -- rsp[(argc + 1) * 8] : receiver
1743 // ----------------------------------- 1969 // -----------------------------------
1744 1970
1745 // If object is not a string, bail out to regular call. 1971 // If object is not a string, bail out to regular call.
1746 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); 1972 if (!object->IsString() || cell != NULL) return heap()->undefined_value();
1747 1973
1748 const int argc = arguments().immediate(); 1974 const int argc = arguments().immediate();
1749 1975
1750 Label miss; 1976 Label miss;
1751 Label name_miss; 1977 Label name_miss;
1752 Label index_out_of_range; 1978 Label index_out_of_range;
1753 Label* index_out_of_range_label = &index_out_of_range; 1979 Label* index_out_of_range_label = &index_out_of_range;
1754 1980
1755 if (kind_ == Code::CALL_IC && 1981 if (kind_ == Code::CALL_IC &&
1756 (CallICBase::StringStubState::decode(extra_ic_state_) == 1982 (CallICBase::StringStubState::decode(extra_state_) ==
1757 DEFAULT_STRING_STUB)) { 1983 DEFAULT_STRING_STUB)) {
1758 index_out_of_range_label = &miss; 1984 index_out_of_range_label = &miss;
1759 } 1985 }
1760 1986
1761 GenerateNameCheck(name, &name_miss); 1987 GenerateNameCheck(Handle<String>(name), &name_miss);
1762 1988
1763 // Check that the maps starting from the prototype haven't changed. 1989 // Check that the maps starting from the prototype haven't changed.
1764 GenerateDirectLoadGlobalFunctionPrototype(masm(), 1990 GenerateDirectLoadGlobalFunctionPrototype(masm(),
1765 Context::STRING_FUNCTION_INDEX, 1991 Context::STRING_FUNCTION_INDEX,
1766 rax, 1992 rax,
1767 &miss); 1993 &miss);
1768 ASSERT(object != holder); 1994 ASSERT(object != holder);
1769 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, 1995 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
1770 rbx, rdx, rdi, name, &miss); 1996 rbx, rdx, rdi, name, &miss);
1771 1997
(...skipping 27 matching lines...) Expand all
1799 if (index_out_of_range.is_linked()) { 2025 if (index_out_of_range.is_linked()) {
1800 __ bind(&index_out_of_range); 2026 __ bind(&index_out_of_range);
1801 __ LoadRoot(rax, Heap::kEmptyStringRootIndex); 2027 __ LoadRoot(rax, Heap::kEmptyStringRootIndex);
1802 __ ret((argc + 1) * kPointerSize); 2028 __ ret((argc + 1) * kPointerSize);
1803 } 2029 }
1804 2030
1805 __ bind(&miss); 2031 __ bind(&miss);
1806 // Restore function name in rcx. 2032 // Restore function name in rcx.
1807 __ Move(rcx, Handle<String>(name)); 2033 __ Move(rcx, Handle<String>(name));
1808 __ bind(&name_miss); 2034 __ bind(&name_miss);
1809 MaybeObject* maybe_result = GenerateMissBranch(); 2035 MaybeObject* maybe_result = TryGenerateMissBranch();
1810 if (maybe_result->IsFailure()) return maybe_result; 2036 if (maybe_result->IsFailure()) return maybe_result;
1811 2037
1812 // Return the generated code. 2038 // Return the generated code.
1813 return GetCode(function); 2039 return TryGetCode(function);
1814 } 2040 }
1815 2041
1816 2042
1817 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( 2043 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall(
1818 Object* object, 2044 Object* object,
1819 JSObject* holder, 2045 JSObject* holder,
1820 JSGlobalPropertyCell* cell, 2046 JSGlobalPropertyCell* cell,
1821 JSFunction* function, 2047 JSFunction* function,
1822 String* name) { 2048 String* name) {
1823 // ----------- S t a t e ------------- 2049 // ----------- S t a t e -------------
1824 // -- rcx : function name 2050 // -- rcx : function name
1825 // -- rsp[0] : return address 2051 // -- rsp[0] : return address
1826 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 2052 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
1827 // -- ... 2053 // -- ...
1828 // -- rsp[(argc + 1) * 8] : receiver 2054 // -- rsp[(argc + 1) * 8] : receiver
1829 // ----------------------------------- 2055 // -----------------------------------
1830 2056
1831 const int argc = arguments().immediate(); 2057 const int argc = arguments().immediate();
1832 2058
1833 // If the object is not a JSObject or we got an unexpected number of 2059 // If the object is not a JSObject or we got an unexpected number of
1834 // arguments, bail out to the regular call. 2060 // arguments, bail out to the regular call.
1835 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); 2061 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value();
1836 2062
1837 Label miss; 2063 Label miss;
1838 GenerateNameCheck(name, &miss); 2064 GenerateNameCheck(Handle<String>(name), &miss);
1839 2065
1840 if (cell == NULL) { 2066 if (cell == NULL) {
1841 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); 2067 __ movq(rdx, Operand(rsp, 2 * kPointerSize));
1842 2068
1843 __ JumpIfSmi(rdx, &miss); 2069 __ JumpIfSmi(rdx, &miss);
1844 2070
1845 CheckPrototypes(JSObject::cast(object), rdx, holder, rbx, rax, rdi, name, 2071 CheckPrototypes(JSObject::cast(object), rdx, holder, rbx, rax, rdi, name,
1846 &miss); 2072 &miss);
1847 } else { 2073 } else {
1848 ASSERT(cell->value() == function); 2074 ASSERT(cell->value() == function);
(...skipping 15 matching lines...) Expand all
1864 StringCharFromCodeGenerator char_from_code_generator(code, rax); 2090 StringCharFromCodeGenerator char_from_code_generator(code, rax);
1865 char_from_code_generator.GenerateFast(masm()); 2091 char_from_code_generator.GenerateFast(masm());
1866 __ ret(2 * kPointerSize); 2092 __ ret(2 * kPointerSize);
1867 2093
1868 StubRuntimeCallHelper call_helper; 2094 StubRuntimeCallHelper call_helper;
1869 char_from_code_generator.GenerateSlow(masm(), call_helper); 2095 char_from_code_generator.GenerateSlow(masm(), call_helper);
1870 2096
1871 // Tail call the full function. We do not have to patch the receiver 2097 // Tail call the full function. We do not have to patch the receiver
1872 // because the function makes no use of it. 2098 // because the function makes no use of it.
1873 __ bind(&slow); 2099 __ bind(&slow);
1874 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) 2100 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
1875 ? CALL_AS_FUNCTION 2101 ? CALL_AS_FUNCTION
1876 : CALL_AS_METHOD; 2102 : CALL_AS_METHOD;
1877 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, 2103 __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
1878 NullCallWrapper(), call_kind); 2104 NullCallWrapper(), call_kind);
1879 2105
1880 __ bind(&miss); 2106 __ bind(&miss);
1881 // rcx: function name. 2107 // rcx: function name.
1882 MaybeObject* maybe_result = GenerateMissBranch(); 2108 MaybeObject* maybe_result = TryGenerateMissBranch();
1883 if (maybe_result->IsFailure()) return maybe_result; 2109 if (maybe_result->IsFailure()) return maybe_result;
1884 2110
1885 // Return the generated code. 2111 // Return the generated code.
1886 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); 2112 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name);
1887 } 2113 }
1888 2114
1889 2115
1890 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, 2116 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object,
1891 JSObject* holder, 2117 JSObject* holder,
1892 JSGlobalPropertyCell* cell, 2118 JSGlobalPropertyCell* cell,
1893 JSFunction* function, 2119 JSFunction* function,
1894 String* name) { 2120 String* name) {
1895 // TODO(872): implement this. 2121 // TODO(872): implement this.
1896 return heap()->undefined_value(); 2122 return heap()->undefined_value();
(...skipping 13 matching lines...) Expand all
1910 // -- rsp[(argc + 1) * 8] : receiver 2136 // -- rsp[(argc + 1) * 8] : receiver
1911 // ----------------------------------- 2137 // -----------------------------------
1912 2138
1913 const int argc = arguments().immediate(); 2139 const int argc = arguments().immediate();
1914 2140
1915 // If the object is not a JSObject or we got an unexpected number of 2141 // If the object is not a JSObject or we got an unexpected number of
1916 // arguments, bail out to the regular call. 2142 // arguments, bail out to the regular call.
1917 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); 2143 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value();
1918 2144
1919 Label miss; 2145 Label miss;
1920 GenerateNameCheck(name, &miss); 2146 GenerateNameCheck(Handle<String>(name), &miss);
1921 2147
1922 if (cell == NULL) { 2148 if (cell == NULL) {
1923 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); 2149 __ movq(rdx, Operand(rsp, 2 * kPointerSize));
1924 2150
1925 __ JumpIfSmi(rdx, &miss); 2151 __ JumpIfSmi(rdx, &miss);
1926 2152
1927 CheckPrototypes(JSObject::cast(object), rdx, holder, rbx, rax, rdi, name, 2153 CheckPrototypes(JSObject::cast(object), rdx, holder, rbx, rax, rdi, name,
1928 &miss); 2154 &miss);
1929 } else { 2155 } else {
1930 ASSERT(cell->value() == function); 2156 ASSERT(cell->value() == function);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1981 // number. We still have the sign mask in rdi. 2207 // number. We still have the sign mask in rdi.
1982 __ bind(&negative_sign); 2208 __ bind(&negative_sign);
1983 __ xor_(rbx, rdi); 2209 __ xor_(rbx, rdi);
1984 __ AllocateHeapNumber(rax, rdx, &slow); 2210 __ AllocateHeapNumber(rax, rdx, &slow);
1985 __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rbx); 2211 __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rbx);
1986 __ ret(2 * kPointerSize); 2212 __ ret(2 * kPointerSize);
1987 2213
1988 // Tail call the full function. We do not have to patch the receiver 2214 // Tail call the full function. We do not have to patch the receiver
1989 // because the function makes no use of it. 2215 // because the function makes no use of it.
1990 __ bind(&slow); 2216 __ bind(&slow);
1991 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) 2217 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
1992 ? CALL_AS_FUNCTION 2218 ? CALL_AS_FUNCTION
1993 : CALL_AS_METHOD; 2219 : CALL_AS_METHOD;
1994 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, 2220 __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
1995 NullCallWrapper(), call_kind); 2221 NullCallWrapper(), call_kind);
1996 2222
1997 __ bind(&miss); 2223 __ bind(&miss);
1998 // rcx: function name. 2224 // rcx: function name.
1999 MaybeObject* maybe_result = GenerateMissBranch(); 2225 MaybeObject* maybe_result = TryGenerateMissBranch();
2000 if (maybe_result->IsFailure()) return maybe_result; 2226 if (maybe_result->IsFailure()) return maybe_result;
2001 2227
2002 // Return the generated code. 2228 // Return the generated code.
2003 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); 2229 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name);
2004 } 2230 }
2005 2231
2006 2232
2007 MaybeObject* CallStubCompiler::CompileFastApiCall( 2233 MaybeObject* CallStubCompiler::CompileFastApiCall(
2008 const CallOptimization& optimization, 2234 const CallOptimization& optimization,
2009 Object* object, 2235 Object* object,
2010 JSObject* holder, 2236 JSObject* holder,
2011 JSGlobalPropertyCell* cell, 2237 JSGlobalPropertyCell* cell,
2012 JSFunction* function, 2238 JSFunction* function,
2013 String* name) { 2239 String* name) {
2014 ASSERT(optimization.is_simple_api_call()); 2240 ASSERT(optimization.is_simple_api_call());
2015 // Bail out if object is a global object as we don't want to 2241 // Bail out if object is a global object as we don't want to
2016 // repatch it to global receiver. 2242 // repatch it to global receiver.
2017 if (object->IsGlobalObject()) return heap()->undefined_value(); 2243 if (object->IsGlobalObject()) return heap()->undefined_value();
2018 if (cell != NULL) return heap()->undefined_value(); 2244 if (cell != NULL) return heap()->undefined_value();
2019 if (!object->IsJSObject()) return heap()->undefined_value(); 2245 if (!object->IsJSObject()) return heap()->undefined_value();
2020 int depth = optimization.GetPrototypeDepthOfExpectedType( 2246 int depth = optimization.GetPrototypeDepthOfExpectedType(
2021 JSObject::cast(object), holder); 2247 JSObject::cast(object), holder);
2022 if (depth == kInvalidProtoDepth) return heap()->undefined_value(); 2248 if (depth == kInvalidProtoDepth) return heap()->undefined_value();
2023 2249
2024 Label miss, miss_before_stack_reserved; 2250 Label miss, miss_before_stack_reserved;
2025 2251
2026 GenerateNameCheck(name, &miss_before_stack_reserved); 2252 GenerateNameCheck(Handle<String>(name), &miss_before_stack_reserved);
2027 2253
2028 // Get the receiver from the stack. 2254 // Get the receiver from the stack.
2029 const int argc = arguments().immediate(); 2255 const int argc = arguments().immediate();
2030 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 2256 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
2031 2257
2032 // Check that the receiver isn't a smi. 2258 // Check that the receiver isn't a smi.
2033 __ JumpIfSmi(rdx, &miss_before_stack_reserved); 2259 __ JumpIfSmi(rdx, &miss_before_stack_reserved);
2034 2260
2035 Counters* counters = isolate()->counters(); 2261 Counters* counters = isolate()->counters();
2036 __ IncrementCounter(counters->call_const(), 1); 2262 __ IncrementCounter(counters->call_const(), 1);
(...skipping 11 matching lines...) Expand all
2048 __ movq(rax, Operand(rsp, 3 * kPointerSize)); 2274 __ movq(rax, Operand(rsp, 3 * kPointerSize));
2049 __ movq(Operand(rsp, 0 * kPointerSize), rax); 2275 __ movq(Operand(rsp, 0 * kPointerSize), rax);
2050 2276
2051 MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc); 2277 MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc);
2052 if (result->IsFailure()) return result; 2278 if (result->IsFailure()) return result;
2053 2279
2054 __ bind(&miss); 2280 __ bind(&miss);
2055 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); 2281 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
2056 2282
2057 __ bind(&miss_before_stack_reserved); 2283 __ bind(&miss_before_stack_reserved);
2058 MaybeObject* maybe_result = GenerateMissBranch(); 2284 MaybeObject* maybe_result = TryGenerateMissBranch();
2059 if (maybe_result->IsFailure()) return maybe_result; 2285 if (maybe_result->IsFailure()) return maybe_result;
2060 2286
2061 // Return the generated code. 2287 // Return the generated code.
2062 return GetCode(function); 2288 return TryGetCode(function);
2063 } 2289 }
2064 2290
2065 2291
2066 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, 2292 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object,
2067 JSObject* holder, 2293 JSObject* holder,
2068 JSFunction* function, 2294 JSFunction* function,
2069 String* name, 2295 String* name,
2070 CheckType check) { 2296 CheckType check) {
2071 // ----------- S t a t e ------------- 2297 // ----------- S t a t e -------------
2072 // rcx : function name 2298 // rcx : function name
2073 // rsp[0] : return address 2299 // rsp[0] : return address
2074 // rsp[8] : argument argc 2300 // rsp[8] : argument argc
2075 // rsp[16] : argument argc - 1 2301 // rsp[16] : argument argc - 1
2076 // ... 2302 // ...
2077 // rsp[argc * 8] : argument 1 2303 // rsp[argc * 8] : argument 1
2078 // rsp[(argc + 1) * 8] : argument 0 = receiver 2304 // rsp[(argc + 1) * 8] : argument 0 = receiver
2079 // ----------------------------------- 2305 // -----------------------------------
2080 2306
2081 if (HasCustomCallGenerator(function)) { 2307 if (HasCustomCallGenerator(function)) {
2082 MaybeObject* maybe_result = CompileCustomCall( 2308 MaybeObject* maybe_result = CompileCustomCall(
2083 object, holder, NULL, function, name); 2309 object, holder, NULL, function, name);
2084 Object* result; 2310 Object* result;
2085 if (!maybe_result->ToObject(&result)) return maybe_result; 2311 if (!maybe_result->ToObject(&result)) return maybe_result;
2086 // undefined means bail out to regular compiler. 2312 // undefined means bail out to regular compiler.
2087 if (!result->IsUndefined()) return result; 2313 if (!result->IsUndefined()) return result;
2088 } 2314 }
2089 2315
2090 Label miss; 2316 Label miss;
2091 2317
2092 GenerateNameCheck(name, &miss); 2318 GenerateNameCheck(Handle<String>(name), &miss);
2093 2319
2094 // Get the receiver from the stack. 2320 // Get the receiver from the stack.
2095 const int argc = arguments().immediate(); 2321 const int argc = arguments().immediate();
2096 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 2322 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
2097 2323
2098 // Check that the receiver isn't a smi. 2324 // Check that the receiver isn't a smi.
2099 if (check != NUMBER_CHECK) { 2325 if (check != NUMBER_CHECK) {
2100 __ JumpIfSmi(rdx, &miss); 2326 __ JumpIfSmi(rdx, &miss);
2101 } 2327 }
2102 2328
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
2179 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, 2405 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
2180 rbx, rdx, rdi, name, &miss); 2406 rbx, rdx, rdi, name, &miss);
2181 } 2407 }
2182 break; 2408 break;
2183 } 2409 }
2184 2410
2185 default: 2411 default:
2186 UNREACHABLE(); 2412 UNREACHABLE();
2187 } 2413 }
2188 2414
2189 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) 2415 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2190 ? CALL_AS_FUNCTION 2416 ? CALL_AS_FUNCTION
2191 : CALL_AS_METHOD; 2417 : CALL_AS_METHOD;
2192 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, 2418 __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
2193 NullCallWrapper(), call_kind); 2419 NullCallWrapper(), call_kind);
2194 2420
2195 // Handle call cache miss. 2421 // Handle call cache miss.
2196 __ bind(&miss); 2422 __ bind(&miss);
2197 MaybeObject* maybe_result = GenerateMissBranch(); 2423 MaybeObject* maybe_result = TryGenerateMissBranch();
2198 if (maybe_result->IsFailure()) return maybe_result; 2424 if (maybe_result->IsFailure()) return maybe_result;
2199 2425
2200 // Return the generated code. 2426 // Return the generated code.
2201 return GetCode(function); 2427 return TryGetCode(function);
2202 } 2428 }
2203 2429
2204 2430
2205 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, 2431 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object,
2206 JSObject* holder, 2432 JSObject* holder,
2207 String* name) { 2433 String* name) {
2208 // ----------- S t a t e ------------- 2434 // ----------- S t a t e -------------
2209 // rcx : function name 2435 // rcx : function name
2210 // rsp[0] : return address 2436 // rsp[0] : return address
2211 // rsp[8] : argument argc 2437 // rsp[8] : argument argc
2212 // rsp[16] : argument argc - 1 2438 // rsp[16] : argument argc - 1
2213 // ... 2439 // ...
2214 // rsp[argc * 8] : argument 1 2440 // rsp[argc * 8] : argument 1
2215 // rsp[(argc + 1) * 8] : argument 0 = receiver 2441 // rsp[(argc + 1) * 8] : argument 0 = receiver
2216 // ----------------------------------- 2442 // -----------------------------------
2217 Label miss; 2443 Label miss;
2218 2444
2219 GenerateNameCheck(name, &miss); 2445 GenerateNameCheck(Handle<String>(name), &miss);
2220 2446
2221 // Get the number of arguments. 2447 // Get the number of arguments.
2222 const int argc = arguments().immediate(); 2448 const int argc = arguments().immediate();
2223 2449
2224 LookupResult lookup; 2450 LookupResult lookup(isolate());
2225 LookupPostInterceptor(holder, name, &lookup); 2451 LookupPostInterceptor(holder, name, &lookup);
2226 2452
2227 // Get the receiver from the stack. 2453 // Get the receiver from the stack.
2228 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 2454 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
2229 2455
2230 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_ic_state_); 2456 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_);
2231 MaybeObject* result = compiler.Compile(masm(), 2457 MaybeObject* result = compiler.Compile(masm(),
2232 object, 2458 object,
2233 holder, 2459 holder,
2234 name, 2460 name,
2235 &lookup, 2461 &lookup,
2236 rdx, 2462 rdx,
2237 rbx, 2463 rbx,
2238 rdi, 2464 rdi,
2239 rax, 2465 rax,
2240 &miss); 2466 &miss);
2241 if (result->IsFailure()) return result; 2467 if (result->IsFailure()) return result;
2242 2468
2243 // Restore receiver. 2469 // Restore receiver.
2244 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 2470 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
2245 2471
2246 // Check that the function really is a function. 2472 // Check that the function really is a function.
2247 __ JumpIfSmi(rax, &miss); 2473 __ JumpIfSmi(rax, &miss);
2248 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); 2474 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx);
2249 __ j(not_equal, &miss); 2475 __ j(not_equal, &miss);
2250 2476
2251 // Patch the receiver on the stack with the global proxy if 2477 // Patch the receiver on the stack with the global proxy if
2252 // necessary. 2478 // necessary.
2253 if (object->IsGlobalObject()) { 2479 if (object->IsGlobalObject()) {
2254 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 2480 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
2255 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 2481 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
2256 } 2482 }
2257 2483
2258 // Invoke the function. 2484 // Invoke the function.
2259 __ movq(rdi, rax); 2485 __ movq(rdi, rax);
2260 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) 2486 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2261 ? CALL_AS_FUNCTION 2487 ? CALL_AS_FUNCTION
2262 : CALL_AS_METHOD; 2488 : CALL_AS_METHOD;
2263 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, 2489 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
2264 NullCallWrapper(), call_kind); 2490 NullCallWrapper(), call_kind);
2265 2491
2266 // Handle load cache miss. 2492 // Handle load cache miss.
2267 __ bind(&miss); 2493 __ bind(&miss);
2268 MaybeObject* maybe_result = GenerateMissBranch(); 2494 MaybeObject* maybe_result = TryGenerateMissBranch();
2269 if (maybe_result->IsFailure()) return maybe_result; 2495 if (maybe_result->IsFailure()) return maybe_result;
2270 2496
2271 // Return the generated code. 2497 // Return the generated code.
2272 return GetCode(INTERCEPTOR, name); 2498 return TryGetCode(INTERCEPTOR, name);
2273 } 2499 }
2274 2500
2275 2501
2276 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, 2502 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object,
2277 GlobalObject* holder, 2503 GlobalObject* holder,
2278 JSGlobalPropertyCell* cell, 2504 JSGlobalPropertyCell* cell,
2279 JSFunction* function, 2505 JSFunction* function,
2280 String* name) { 2506 String* name) {
2281 // ----------- S t a t e ------------- 2507 // ----------- S t a t e -------------
2282 // rcx : function name 2508 // rcx : function name
2283 // rsp[0] : return address 2509 // rsp[0] : return address
2284 // rsp[8] : argument argc 2510 // rsp[8] : argument argc
2285 // rsp[16] : argument argc - 1 2511 // rsp[16] : argument argc - 1
2286 // ... 2512 // ...
2287 // rsp[argc * 8] : argument 1 2513 // rsp[argc * 8] : argument 1
2288 // rsp[(argc + 1) * 8] : argument 0 = receiver 2514 // rsp[(argc + 1) * 8] : argument 0 = receiver
2289 // ----------------------------------- 2515 // -----------------------------------
2290 2516
2291 if (HasCustomCallGenerator(function)) { 2517 if (HasCustomCallGenerator(function)) {
2292 MaybeObject* maybe_result = CompileCustomCall( 2518 MaybeObject* maybe_result = CompileCustomCall(
2293 object, holder, cell, function, name); 2519 object, holder, cell, function, name);
2294 Object* result; 2520 Object* result;
2295 if (!maybe_result->ToObject(&result)) return maybe_result; 2521 if (!maybe_result->ToObject(&result)) return maybe_result;
2296 // undefined means bail out to regular compiler. 2522 // undefined means bail out to regular compiler.
2297 if (!result->IsUndefined()) return result; 2523 if (!result->IsUndefined()) return result;
2298 } 2524 }
2299 2525
2300 Label miss; 2526 Label miss;
2301 2527
2302 GenerateNameCheck(name, &miss); 2528 GenerateNameCheck(Handle<String>(name), &miss);
2303 2529
2304 // Get the number of arguments. 2530 // Get the number of arguments.
2305 const int argc = arguments().immediate(); 2531 const int argc = arguments().immediate();
2306 2532
2307 GenerateGlobalReceiverCheck(object, holder, name, &miss); 2533 GenerateGlobalReceiverCheck(object, holder, name, &miss);
2308 2534
2309 GenerateLoadFunctionFromCell(cell, function, &miss); 2535 GenerateLoadFunctionFromCell(cell, function, &miss);
2310 2536
2311 // Patch the receiver on the stack with the global proxy. 2537 // Patch the receiver on the stack with the global proxy.
2312 if (object->IsGlobalObject()) { 2538 if (object->IsGlobalObject()) {
2313 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 2539 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
2314 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 2540 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
2315 } 2541 }
2316 2542
2317 // Setup the context (function already in rdi). 2543 // Setup the context (function already in rdi).
2318 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 2544 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
2319 2545
2320 // Jump to the cached code (tail call). 2546 // Jump to the cached code (tail call).
2321 Counters* counters = isolate()->counters(); 2547 Counters* counters = isolate()->counters();
2322 __ IncrementCounter(counters->call_global_inline(), 1); 2548 __ IncrementCounter(counters->call_global_inline(), 1);
2323 ASSERT(function->is_compiled());
2324 ParameterCount expected(function->shared()->formal_parameter_count()); 2549 ParameterCount expected(function->shared()->formal_parameter_count());
2325 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) 2550 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2326 ? CALL_AS_FUNCTION 2551 ? CALL_AS_FUNCTION
2327 : CALL_AS_METHOD; 2552 : CALL_AS_METHOD;
2328 if (V8::UseCrankshaft()) { 2553 // We call indirectly through the code field in the function to
2329 // TODO(kasperl): For now, we always call indirectly through the 2554 // allow recompilation to take effect without changing any of the
2330 // code field in the function to allow recompilation to take effect 2555 // call sites.
2331 // without changing any of the call sites. 2556 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
2332 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 2557 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION,
2333 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION, 2558 NullCallWrapper(), call_kind);
2334 NullCallWrapper(), call_kind); 2559
2335 } else {
2336 Handle<Code> code(function->code());
2337 __ InvokeCode(code, expected, arguments(),
2338 RelocInfo::CODE_TARGET, JUMP_FUNCTION,
2339 NullCallWrapper(), call_kind);
2340 }
2341 // Handle call cache miss. 2560 // Handle call cache miss.
2342 __ bind(&miss); 2561 __ bind(&miss);
2343 __ IncrementCounter(counters->call_global_inline_miss(), 1); 2562 __ IncrementCounter(counters->call_global_inline_miss(), 1);
2344 MaybeObject* maybe_result = GenerateMissBranch(); 2563 MaybeObject* maybe_result = TryGenerateMissBranch();
2345 if (maybe_result->IsFailure()) return maybe_result; 2564 if (maybe_result->IsFailure()) return maybe_result;
2346 2565
2347 // Return the generated code. 2566 // Return the generated code.
2348 return GetCode(NORMAL, name); 2567 return TryGetCode(NORMAL, name);
2349 } 2568 }
2350 2569
2351 2570
2352 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, 2571 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
2353 int index, 2572 int index,
2354 Map* transition, 2573 Handle<Map> transition,
2355 String* name) { 2574 Handle<String> name) {
2356 // ----------- S t a t e ------------- 2575 // ----------- S t a t e -------------
2357 // -- rax : value 2576 // -- rax : value
2358 // -- rcx : name 2577 // -- rcx : name
2359 // -- rdx : receiver 2578 // -- rdx : receiver
2360 // -- rsp[0] : return address 2579 // -- rsp[0] : return address
2361 // ----------------------------------- 2580 // -----------------------------------
2362 Label miss; 2581 Label miss;
2363 2582
2364 // Generate store field code. Preserves receiver and name on jump to miss. 2583 // Generate store field code. Preserves receiver and name on jump to miss.
2365 GenerateStoreField(masm(), 2584 GenerateStoreField(masm(), object, index, transition, rdx, rcx, rbx, &miss);
2366 object,
2367 index,
2368 transition,
2369 rdx, rcx, rbx,
2370 &miss);
2371 2585
2372 // Handle store cache miss. 2586 // Handle store cache miss.
2373 __ bind(&miss); 2587 __ bind(&miss);
2374 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); 2588 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
2375 __ Jump(ic, RelocInfo::CODE_TARGET); 2589 __ Jump(ic, RelocInfo::CODE_TARGET);
2376 2590
2377 // Return the generated code. 2591 // Return the generated code.
2378 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 2592 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
2379 } 2593 }
2380 2594
2381 2595
2382 MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object, 2596 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2383 AccessorInfo* callback, 2597 Handle<JSObject> object,
2384 String* name) { 2598 Handle<AccessorInfo> callback,
2599 Handle<String> name) {
2385 // ----------- S t a t e ------------- 2600 // ----------- S t a t e -------------
2386 // -- rax : value 2601 // -- rax : value
2387 // -- rcx : name 2602 // -- rcx : name
2388 // -- rdx : receiver 2603 // -- rdx : receiver
2389 // -- rsp[0] : return address 2604 // -- rsp[0] : return address
2390 // ----------------------------------- 2605 // -----------------------------------
2391 Label miss; 2606 Label miss;
2392 2607
2393 // Check that the object isn't a smi. 2608 // Check that the object isn't a smi.
2394 __ JumpIfSmi(rdx, &miss); 2609 __ JumpIfSmi(rdx, &miss);
2395 2610
2396 // Check that the map of the object hasn't changed. 2611 // Check that the map of the object hasn't changed.
2397 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), 2612 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset),
2398 Handle<Map>(object->map())); 2613 Handle<Map>(object->map()));
2399 __ j(not_equal, &miss); 2614 __ j(not_equal, &miss);
2400 2615
2401 // Perform global security token check if needed. 2616 // Perform global security token check if needed.
2402 if (object->IsJSGlobalProxy()) { 2617 if (object->IsJSGlobalProxy()) {
2403 __ CheckAccessGlobalProxy(rdx, rbx, &miss); 2618 __ CheckAccessGlobalProxy(rdx, rbx, &miss);
2404 } 2619 }
2405 2620
2406 // Stub never generated for non-global objects that require access 2621 // Stub never generated for non-global objects that require access
2407 // checks. 2622 // checks.
2408 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 2623 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
2409 2624
2410 __ pop(rbx); // remove the return address 2625 __ pop(rbx); // remove the return address
2411 __ push(rdx); // receiver 2626 __ push(rdx); // receiver
2412 __ Push(Handle<AccessorInfo>(callback)); // callback info 2627 __ Push(callback); // callback info
2413 __ push(rcx); // name 2628 __ push(rcx); // name
2414 __ push(rax); // value 2629 __ push(rax); // value
2415 __ push(rbx); // restore return address 2630 __ push(rbx); // restore return address
2416 2631
2417 // Do tail-call to the runtime system. 2632 // Do tail-call to the runtime system.
2418 ExternalReference store_callback_property = 2633 ExternalReference store_callback_property =
2419 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 2634 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
2420 __ TailCallExternalReference(store_callback_property, 4, 1); 2635 __ TailCallExternalReference(store_callback_property, 4, 1);
2421 2636
2422 // Handle store cache miss. 2637 // Handle store cache miss.
2423 __ bind(&miss); 2638 __ bind(&miss);
2424 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); 2639 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
2425 __ Jump(ic, RelocInfo::CODE_TARGET); 2640 __ Jump(ic, RelocInfo::CODE_TARGET);
2426 2641
2427 // Return the generated code. 2642 // Return the generated code.
2428 return GetCode(CALLBACKS, name); 2643 return GetCode(CALLBACKS, name);
2429 } 2644 }
2430 2645
2431 2646
2432 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, 2647 Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
2433 String* name) { 2648 Handle<JSObject> receiver,
2649 Handle<String> name) {
2434 // ----------- S t a t e ------------- 2650 // ----------- S t a t e -------------
2435 // -- rax : value 2651 // -- rax : value
2436 // -- rcx : name 2652 // -- rcx : name
2437 // -- rdx : receiver 2653 // -- rdx : receiver
2438 // -- rsp[0] : return address 2654 // -- rsp[0] : return address
2439 // ----------------------------------- 2655 // -----------------------------------
2440 Label miss; 2656 Label miss;
2441 2657
2442 // Check that the object isn't a smi. 2658 // Check that the object isn't a smi.
2443 __ JumpIfSmi(rdx, &miss); 2659 __ JumpIfSmi(rdx, &miss);
(...skipping 27 matching lines...) Expand all
2471 // Handle store cache miss. 2687 // Handle store cache miss.
2472 __ bind(&miss); 2688 __ bind(&miss);
2473 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); 2689 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
2474 __ Jump(ic, RelocInfo::CODE_TARGET); 2690 __ Jump(ic, RelocInfo::CODE_TARGET);
2475 2691
2476 // Return the generated code. 2692 // Return the generated code.
2477 return GetCode(INTERCEPTOR, name); 2693 return GetCode(INTERCEPTOR, name);
2478 } 2694 }
2479 2695
2480 2696
2481 MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object, 2697 Handle<Code> StoreStubCompiler::CompileStoreGlobal(
2482 JSGlobalPropertyCell* cell, 2698 Handle<GlobalObject> object,
2483 String* name) { 2699 Handle<JSGlobalPropertyCell> cell,
2700 Handle<String> name) {
2484 // ----------- S t a t e ------------- 2701 // ----------- S t a t e -------------
2485 // -- rax : value 2702 // -- rax : value
2486 // -- rcx : name 2703 // -- rcx : name
2487 // -- rdx : receiver 2704 // -- rdx : receiver
2488 // -- rsp[0] : return address 2705 // -- rsp[0] : return address
2489 // ----------------------------------- 2706 // -----------------------------------
2490 Label miss; 2707 Label miss;
2491 2708
2492 // Check that the map of the global has not changed. 2709 // Check that the map of the global has not changed.
2493 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), 2710 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset),
2494 Handle<Map>(object->map())); 2711 Handle<Map>(object->map()));
2495 __ j(not_equal, &miss); 2712 __ j(not_equal, &miss);
2496 2713
2497 // Compute the cell operand to use. 2714 // Compute the cell operand to use.
2498 __ Move(rbx, Handle<JSGlobalPropertyCell>(cell)); 2715 __ Move(rbx, cell);
2499 Operand cell_operand = FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset); 2716 Operand cell_operand = FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset);
2500 2717
2501 // Check that the value in the cell is not the hole. If it is, this 2718 // Check that the value in the cell is not the hole. If it is, this
2502 // cell could have been deleted and reintroducing the global needs 2719 // cell could have been deleted and reintroducing the global needs
2503 // to update the property details in the property dictionary of the 2720 // to update the property details in the property dictionary of the
2504 // global object. We bail out to the runtime system to do that. 2721 // global object. We bail out to the runtime system to do that.
2505 __ CompareRoot(cell_operand, Heap::kTheHoleValueRootIndex); 2722 __ CompareRoot(cell_operand, Heap::kTheHoleValueRootIndex);
2506 __ j(equal, &miss); 2723 __ j(equal, &miss);
2507 2724
2508 // Store the value in the cell. 2725 // Store the value in the cell.
(...skipping 23 matching lines...) Expand all
2532 __ bind(&miss); 2749 __ bind(&miss);
2533 __ IncrementCounter(counters->named_store_global_inline_miss(), 1); 2750 __ IncrementCounter(counters->named_store_global_inline_miss(), 1);
2534 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); 2751 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
2535 __ Jump(ic, RelocInfo::CODE_TARGET); 2752 __ Jump(ic, RelocInfo::CODE_TARGET);
2536 2753
2537 // Return the generated code. 2754 // Return the generated code.
2538 return GetCode(NORMAL, name); 2755 return GetCode(NORMAL, name);
2539 } 2756 }
2540 2757
2541 2758
2542 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, 2759 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object,
2543 int index, 2760 int index,
2544 Map* transition, 2761 Handle<Map> transition,
2545 String* name) { 2762 Handle<String> name) {
2546 // ----------- S t a t e ------------- 2763 // ----------- S t a t e -------------
2547 // -- rax : value 2764 // -- rax : value
2548 // -- rcx : key 2765 // -- rcx : key
2549 // -- rdx : receiver 2766 // -- rdx : receiver
2550 // -- rsp[0] : return address 2767 // -- rsp[0] : return address
2551 // ----------------------------------- 2768 // -----------------------------------
2552 Label miss; 2769 Label miss;
2553 2770
2554 Counters* counters = isolate()->counters(); 2771 Counters* counters = isolate()->counters();
2555 __ IncrementCounter(counters->keyed_store_field(), 1); 2772 __ IncrementCounter(counters->keyed_store_field(), 1);
2556 2773
2557 // Check that the name has not changed. 2774 // Check that the name has not changed.
2558 __ Cmp(rcx, Handle<String>(name)); 2775 __ Cmp(rcx, name);
2559 __ j(not_equal, &miss); 2776 __ j(not_equal, &miss);
2560 2777
2561 // Generate store field code. Preserves receiver and name on jump to miss. 2778 // Generate store field code. Preserves receiver and name on jump to miss.
2562 GenerateStoreField(masm(), 2779 GenerateStoreField(masm(), object, index, transition, rdx, rcx, rbx, &miss);
2563 object,
2564 index,
2565 transition,
2566 rdx, rcx, rbx,
2567 &miss);
2568 2780
2569 // Handle store cache miss. 2781 // Handle store cache miss.
2570 __ bind(&miss); 2782 __ bind(&miss);
2571 __ DecrementCounter(counters->keyed_store_field(), 1); 2783 __ DecrementCounter(counters->keyed_store_field(), 1);
2572 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2784 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2573 __ Jump(ic, RelocInfo::CODE_TARGET); 2785 __ Jump(ic, RelocInfo::CODE_TARGET);
2574 2786
2575 // Return the generated code. 2787 // Return the generated code.
2576 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 2788 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name);
2577 } 2789 }
2578 2790
2579 2791
2580 MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(Map* receiver_map) { 2792 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
2793 Handle<Map> receiver_map) {
2581 // ----------- S t a t e ------------- 2794 // ----------- S t a t e -------------
2582 // -- rax : value 2795 // -- rax : value
2583 // -- rcx : key 2796 // -- rcx : key
2584 // -- rdx : receiver 2797 // -- rdx : receiver
2585 // -- rsp[0] : return address 2798 // -- rsp[0] : return address
2586 // ----------------------------------- 2799 // -----------------------------------
2587 Code* stub; 2800
2588 ElementsKind elements_kind = receiver_map->elements_kind(); 2801 ElementsKind elements_kind = receiver_map->elements_kind();
2589 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 2802 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
2590 MaybeObject* maybe_stub = 2803 Handle<Code> stub =
2591 KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode(); 2804 KeyedStoreElementStub(is_js_array, elements_kind).GetCode();
2592 if (!maybe_stub->To(&stub)) return maybe_stub; 2805
2593 __ DispatchMap(rdx, 2806 __ DispatchMap(rdx, receiver_map, stub, DO_SMI_CHECK);
2594 Handle<Map>(receiver_map),
2595 Handle<Code>(stub),
2596 DO_SMI_CHECK);
2597 2807
2598 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2808 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2599 __ jmp(ic, RelocInfo::CODE_TARGET); 2809 __ jmp(ic, RelocInfo::CODE_TARGET);
2600 2810
2601 // Return the generated code. 2811 // Return the generated code.
2602 return GetCode(NORMAL, NULL); 2812 return GetCode(NORMAL, factory()->empty_string());
2603 } 2813 }
2604 2814
2605 2815
2606 MaybeObject* KeyedStoreStubCompiler::CompileStorePolymorphic( 2816 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
2607 MapList* receiver_maps, 2817 MapHandleList* receiver_maps,
2608 CodeList* handler_stubs, 2818 CodeHandleList* handler_stubs,
2609 MapList* transitioned_maps) { 2819 MapHandleList* transitioned_maps) {
2610 // ----------- S t a t e ------------- 2820 // ----------- S t a t e -------------
2611 // -- rax : value 2821 // -- rax : value
2612 // -- rcx : key 2822 // -- rcx : key
2613 // -- rdx : receiver 2823 // -- rdx : receiver
2614 // -- rsp[0] : return address 2824 // -- rsp[0] : return address
2615 // ----------------------------------- 2825 // -----------------------------------
2616 Label miss; 2826 Label miss;
2617 __ JumpIfSmi(rdx, &miss, Label::kNear); 2827 __ JumpIfSmi(rdx, &miss, Label::kNear);
2618 2828
2619 __ movq(rdi, FieldOperand(rdx, HeapObject::kMapOffset)); 2829 __ movq(rdi, FieldOperand(rdx, HeapObject::kMapOffset));
2620 int receiver_count = receiver_maps->length(); 2830 int receiver_count = receiver_maps->length();
2621 for (int i = 0; i < receiver_count; ++i) { 2831 for (int i = 0; i < receiver_count; ++i) {
2622 // Check map and tail call if there's a match 2832 // Check map and tail call if there's a match
2623 Handle<Map> map(receiver_maps->at(i)); 2833 __ Cmp(rdi, receiver_maps->at(i));
2624 __ Cmp(rdi, map); 2834 if (transitioned_maps->at(i).is_null()) {
2625 if (transitioned_maps->at(i) == NULL) { 2835 __ j(equal, handler_stubs->at(i), RelocInfo::CODE_TARGET);
2626 __ j(equal, Handle<Code>(handler_stubs->at(i)), RelocInfo::CODE_TARGET);
2627 } else { 2836 } else {
2628 Label next_map; 2837 Label next_map;
2629 __ j(not_equal, &next_map, Label::kNear); 2838 __ j(not_equal, &next_map, Label::kNear);
2630 __ movq(rbx, 2839 __ movq(rbx, transitioned_maps->at(i), RelocInfo::EMBEDDED_OBJECT);
2631 Handle<Map>(transitioned_maps->at(i)), 2840 __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET);
2632 RelocInfo::EMBEDDED_OBJECT);
2633 __ jmp(Handle<Code>(handler_stubs->at(i)), RelocInfo::CODE_TARGET);
2634 __ bind(&next_map); 2841 __ bind(&next_map);
2635 } 2842 }
2636 } 2843 }
2637 2844
2638 __ bind(&miss); 2845 __ bind(&miss);
2639 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2846 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2640 __ jmp(ic, RelocInfo::CODE_TARGET); 2847 __ jmp(ic, RelocInfo::CODE_TARGET);
2641 2848
2642 // Return the generated code. 2849 // Return the generated code.
2643 return GetCode(NORMAL, NULL, MEGAMORPHIC); 2850 return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
2644 } 2851 }
2645 2852
2646 2853
2647 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, 2854 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<String> name,
2648 JSObject* object, 2855 Handle<JSObject> object,
2649 JSObject* last) { 2856 Handle<JSObject> last) {
2650 // ----------- S t a t e ------------- 2857 // ----------- S t a t e -------------
2651 // -- rax : receiver 2858 // -- rax : receiver
2652 // -- rcx : name 2859 // -- rcx : name
2653 // -- rsp[0] : return address 2860 // -- rsp[0] : return address
2654 // ----------------------------------- 2861 // -----------------------------------
2655 Label miss; 2862 Label miss;
2656 2863
2657 // Check that receiver is not a smi. 2864 // Check that receiver is not a smi.
2658 __ JumpIfSmi(rax, &miss); 2865 __ JumpIfSmi(rax, &miss);
2659 2866
2660 // Check the maps of the full prototype chain. Also check that 2867 // Check the maps of the full prototype chain. Also check that
2661 // global property cells up to (but not including) the last object 2868 // global property cells up to (but not including) the last object
2662 // in the prototype chain are empty. 2869 // in the prototype chain are empty.
2663 CheckPrototypes(object, rax, last, rbx, rdx, rdi, name, &miss); 2870 CheckPrototypes(object, rax, last, rbx, rdx, rdi, name, &miss);
2664 2871
2665 // If the last object in the prototype chain is a global object, 2872 // If the last object in the prototype chain is a global object,
2666 // check that the global property cell is empty. 2873 // check that the global property cell is empty.
2667 if (last->IsGlobalObject()) { 2874 if (last->IsGlobalObject()) {
2668 MaybeObject* cell = GenerateCheckPropertyCell(masm(), 2875 GenerateCheckPropertyCell(
2669 GlobalObject::cast(last), 2876 masm(), Handle<GlobalObject>::cast(last), name, rdx, &miss);
2670 name,
2671 rdx,
2672 &miss);
2673 if (cell->IsFailure()) {
2674 miss.Unuse();
2675 return cell;
2676 }
2677 } 2877 }
2678 2878
2679 // Return undefined if maps of the full prototype chain are still the 2879 // Return undefined if maps of the full prototype chain are still the
2680 // same and no global property with this name contains a value. 2880 // same and no global property with this name contains a value.
2681 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 2881 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
2682 __ ret(0); 2882 __ ret(0);
2683 2883
2684 __ bind(&miss); 2884 __ bind(&miss);
2685 GenerateLoadMiss(masm(), Code::LOAD_IC); 2885 GenerateLoadMiss(masm(), Code::LOAD_IC);
2686 2886
2687 // Return the generated code. 2887 // Return the generated code.
2688 return GetCode(NONEXISTENT, heap()->empty_string()); 2888 return GetCode(NONEXISTENT, factory()->empty_string());
2689 } 2889 }
2690 2890
2691 2891
2692 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object, 2892 Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object,
2693 JSObject* holder, 2893 Handle<JSObject> holder,
2694 int index, 2894 int index,
2695 String* name) { 2895 Handle<String> name) {
2696 // ----------- S t a t e ------------- 2896 // ----------- S t a t e -------------
2697 // -- rax : receiver 2897 // -- rax : receiver
2698 // -- rcx : name 2898 // -- rcx : name
2699 // -- rsp[0] : return address 2899 // -- rsp[0] : return address
2700 // ----------------------------------- 2900 // -----------------------------------
2701 Label miss; 2901 Label miss;
2702 2902
2703 GenerateLoadField(object, holder, rax, rbx, rdx, rdi, index, name, &miss); 2903 GenerateLoadField(object, holder, rax, rbx, rdx, rdi, index, name, &miss);
2704 __ bind(&miss); 2904 __ bind(&miss);
2705 GenerateLoadMiss(masm(), Code::LOAD_IC); 2905 GenerateLoadMiss(masm(), Code::LOAD_IC);
(...skipping 18 matching lines...) Expand all
2724 rdi, callback, name, &miss); 2924 rdi, callback, name, &miss);
2725 if (result->IsFailure()) { 2925 if (result->IsFailure()) {
2726 miss.Unuse(); 2926 miss.Unuse();
2727 return result; 2927 return result;
2728 } 2928 }
2729 2929
2730 __ bind(&miss); 2930 __ bind(&miss);
2731 GenerateLoadMiss(masm(), Code::LOAD_IC); 2931 GenerateLoadMiss(masm(), Code::LOAD_IC);
2732 2932
2733 // Return the generated code. 2933 // Return the generated code.
2734 return GetCode(CALLBACKS, name); 2934 return TryGetCode(CALLBACKS, name);
2735 } 2935 }
2736 2936
2737 2937
2738 MaybeObject* LoadStubCompiler::CompileLoadConstant(JSObject* object, 2938 Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object,
2739 JSObject* holder, 2939 Handle<JSObject> holder,
2740 Object* value, 2940 Handle<Object> value,
2741 String* name) { 2941 Handle<String> name) {
2742 // ----------- S t a t e ------------- 2942 // ----------- S t a t e -------------
2743 // -- rax : receiver 2943 // -- rax : receiver
2744 // -- rcx : name 2944 // -- rcx : name
2745 // -- rsp[0] : return address 2945 // -- rsp[0] : return address
2746 // ----------------------------------- 2946 // -----------------------------------
2747 Label miss; 2947 Label miss;
2748 2948
2749 GenerateLoadConstant(object, holder, rax, rbx, rdx, rdi, value, name, &miss); 2949 GenerateLoadConstant(object, holder, rax, rbx, rdx, rdi, value, name, &miss);
2750 __ bind(&miss); 2950 __ bind(&miss);
2751 GenerateLoadMiss(masm(), Code::LOAD_IC); 2951 GenerateLoadMiss(masm(), Code::LOAD_IC);
2752 2952
2753 // Return the generated code. 2953 // Return the generated code.
2754 return GetCode(CONSTANT_FUNCTION, name); 2954 return GetCode(CONSTANT_FUNCTION, name);
2755 } 2955 }
2756 2956
2757 2957
2758 MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, 2958 MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
2759 JSObject* holder, 2959 JSObject* holder,
2760 String* name) { 2960 String* name) {
2761 // ----------- S t a t e ------------- 2961 // ----------- S t a t e -------------
2762 // -- rax : receiver 2962 // -- rax : receiver
2763 // -- rcx : name 2963 // -- rcx : name
2764 // -- rsp[0] : return address 2964 // -- rsp[0] : return address
2765 // ----------------------------------- 2965 // -----------------------------------
2766 Label miss; 2966 Label miss;
2767 2967
2768 LookupResult lookup; 2968 LookupResult lookup(isolate());
2769 LookupPostInterceptor(holder, name, &lookup); 2969 LookupPostInterceptor(holder, name, &lookup);
2770 2970
2771 // TODO(368): Compile in the whole chain: all the interceptors in 2971 // TODO(368): Compile in the whole chain: all the interceptors in
2772 // prototypes and ultimate answer. 2972 // prototypes and ultimate answer.
2773 GenerateLoadInterceptor(receiver, 2973 GenerateLoadInterceptor(receiver,
2774 holder, 2974 holder,
2775 &lookup, 2975 &lookup,
2776 rax, 2976 rax,
2777 rcx, 2977 rcx,
2778 rdx, 2978 rdx,
2779 rbx, 2979 rbx,
2780 rdi, 2980 rdi,
2781 name, 2981 name,
2782 &miss); 2982 &miss);
2783 2983
2784 __ bind(&miss); 2984 __ bind(&miss);
2785 GenerateLoadMiss(masm(), Code::LOAD_IC); 2985 GenerateLoadMiss(masm(), Code::LOAD_IC);
2786 2986
2787 // Return the generated code. 2987 // Return the generated code.
2788 return GetCode(INTERCEPTOR, name); 2988 return TryGetCode(INTERCEPTOR, name);
2789 } 2989 }
2790 2990
2791 2991
2792 MaybeObject* LoadStubCompiler::CompileLoadGlobal(JSObject* object, 2992 Handle<Code> LoadStubCompiler::CompileLoadGlobal(
2793 GlobalObject* holder, 2993 Handle<JSObject> object,
2794 JSGlobalPropertyCell* cell, 2994 Handle<GlobalObject> holder,
2795 String* name, 2995 Handle<JSGlobalPropertyCell> cell,
2796 bool is_dont_delete) { 2996 Handle<String> name,
2997 bool is_dont_delete) {
2797 // ----------- S t a t e ------------- 2998 // ----------- S t a t e -------------
2798 // -- rax : receiver 2999 // -- rax : receiver
2799 // -- rcx : name 3000 // -- rcx : name
2800 // -- rsp[0] : return address 3001 // -- rsp[0] : return address
2801 // ----------------------------------- 3002 // -----------------------------------
2802 Label miss; 3003 Label miss;
2803 3004
2804 // If the object is the holder then we know that it's a global 3005 // If the object is the holder then we know that it's a global
2805 // object which can only happen for contextual loads. In this case, 3006 // object which can only happen for contextual loads. In this case,
2806 // the receiver cannot be a smi. 3007 // the receiver cannot be a smi.
2807 if (object != holder) { 3008 if (!object.is_identical_to(holder)) {
2808 __ JumpIfSmi(rax, &miss); 3009 __ JumpIfSmi(rax, &miss);
2809 } 3010 }
2810 3011
2811 // Check that the maps haven't changed. 3012 // Check that the maps haven't changed.
2812 CheckPrototypes(object, rax, holder, rbx, rdx, rdi, name, &miss); 3013 CheckPrototypes(object, rax, holder, rbx, rdx, rdi, name, &miss);
2813 3014
2814 // Get the value from the cell. 3015 // Get the value from the cell.
2815 __ Move(rbx, Handle<JSGlobalPropertyCell>(cell)); 3016 __ Move(rbx, cell);
2816 __ movq(rbx, FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset)); 3017 __ movq(rbx, FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset));
2817 3018
2818 // Check for deleted property if property can actually be deleted. 3019 // Check for deleted property if property can actually be deleted.
2819 if (!is_dont_delete) { 3020 if (!is_dont_delete) {
2820 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); 3021 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex);
2821 __ j(equal, &miss); 3022 __ j(equal, &miss);
2822 } else if (FLAG_debug_code) { 3023 } else if (FLAG_debug_code) {
2823 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); 3024 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex);
2824 __ Check(not_equal, "DontDelete cells can't contain the hole"); 3025 __ Check(not_equal, "DontDelete cells can't contain the hole");
2825 } 3026 }
2826 3027
2827 Counters* counters = isolate()->counters(); 3028 Counters* counters = isolate()->counters();
2828 __ IncrementCounter(counters->named_load_global_stub(), 1); 3029 __ IncrementCounter(counters->named_load_global_stub(), 1);
2829 __ movq(rax, rbx); 3030 __ movq(rax, rbx);
2830 __ ret(0); 3031 __ ret(0);
2831 3032
2832 __ bind(&miss); 3033 __ bind(&miss);
2833 __ IncrementCounter(counters->named_load_global_stub_miss(), 1); 3034 __ IncrementCounter(counters->named_load_global_stub_miss(), 1);
2834 GenerateLoadMiss(masm(), Code::LOAD_IC); 3035 GenerateLoadMiss(masm(), Code::LOAD_IC);
2835 3036
2836 // Return the generated code. 3037 // Return the generated code.
2837 return GetCode(NORMAL, name); 3038 return GetCode(NORMAL, name);
2838 } 3039 }
2839 3040
2840 3041
2841 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, 3042 Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name,
2842 JSObject* receiver, 3043 Handle<JSObject> receiver,
2843 JSObject* holder, 3044 Handle<JSObject> holder,
2844 int index) { 3045 int index) {
2845 // ----------- S t a t e ------------- 3046 // ----------- S t a t e -------------
2846 // -- rax : key 3047 // -- rax : key
2847 // -- rdx : receiver 3048 // -- rdx : receiver
2848 // -- rsp[0] : return address 3049 // -- rsp[0] : return address
2849 // ----------------------------------- 3050 // -----------------------------------
2850 Label miss; 3051 Label miss;
2851 3052
2852 Counters* counters = isolate()->counters(); 3053 Counters* counters = isolate()->counters();
2853 __ IncrementCounter(counters->keyed_load_field(), 1); 3054 __ IncrementCounter(counters->keyed_load_field(), 1);
2854 3055
2855 // Check that the name has not changed. 3056 // Check that the name has not changed.
2856 __ Cmp(rax, Handle<String>(name)); 3057 __ Cmp(rax, name);
2857 __ j(not_equal, &miss); 3058 __ j(not_equal, &miss);
2858 3059
2859 GenerateLoadField(receiver, holder, rdx, rbx, rcx, rdi, index, name, &miss); 3060 GenerateLoadField(receiver, holder, rdx, rbx, rcx, rdi, index, name, &miss);
2860 3061
2861 __ bind(&miss); 3062 __ bind(&miss);
2862 __ DecrementCounter(counters->keyed_load_field(), 1); 3063 __ DecrementCounter(counters->keyed_load_field(), 1);
2863 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3064 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
2864 3065
2865 // Return the generated code. 3066 // Return the generated code.
2866 return GetCode(FIELD, name); 3067 return GetCode(FIELD, name);
(...skipping 25 matching lines...) Expand all
2892 miss.Unuse(); 3093 miss.Unuse();
2893 return result; 3094 return result;
2894 } 3095 }
2895 3096
2896 __ bind(&miss); 3097 __ bind(&miss);
2897 3098
2898 __ DecrementCounter(counters->keyed_load_callback(), 1); 3099 __ DecrementCounter(counters->keyed_load_callback(), 1);
2899 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3100 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
2900 3101
2901 // Return the generated code. 3102 // Return the generated code.
2902 return GetCode(CALLBACKS, name); 3103 return TryGetCode(CALLBACKS, name);
2903 } 3104 }
2904 3105
2905 3106
2906 MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name, 3107 Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant(
2907 JSObject* receiver, 3108 Handle<String> name,
2908 JSObject* holder, 3109 Handle<JSObject> receiver,
2909 Object* value) { 3110 Handle<JSObject> holder,
3111 Handle<Object> value) {
2910 // ----------- S t a t e ------------- 3112 // ----------- S t a t e -------------
2911 // -- rax : key 3113 // -- rax : key
2912 // -- rdx : receiver 3114 // -- rdx : receiver
2913 // -- rsp[0] : return address 3115 // -- rsp[0] : return address
2914 // ----------------------------------- 3116 // -----------------------------------
2915 Label miss; 3117 Label miss;
2916 3118
2917 Counters* counters = isolate()->counters(); 3119 Counters* counters = isolate()->counters();
2918 __ IncrementCounter(counters->keyed_load_constant_function(), 1); 3120 __ IncrementCounter(counters->keyed_load_constant_function(), 1);
2919 3121
(...skipping 22 matching lines...) Expand all
2942 // ----------------------------------- 3144 // -----------------------------------
2943 Label miss; 3145 Label miss;
2944 3146
2945 Counters* counters = isolate()->counters(); 3147 Counters* counters = isolate()->counters();
2946 __ IncrementCounter(counters->keyed_load_interceptor(), 1); 3148 __ IncrementCounter(counters->keyed_load_interceptor(), 1);
2947 3149
2948 // Check that the name has not changed. 3150 // Check that the name has not changed.
2949 __ Cmp(rax, Handle<String>(name)); 3151 __ Cmp(rax, Handle<String>(name));
2950 __ j(not_equal, &miss); 3152 __ j(not_equal, &miss);
2951 3153
2952 LookupResult lookup; 3154 LookupResult lookup(isolate());
2953 LookupPostInterceptor(holder, name, &lookup); 3155 LookupPostInterceptor(holder, name, &lookup);
2954 GenerateLoadInterceptor(receiver, 3156 GenerateLoadInterceptor(receiver,
2955 holder, 3157 holder,
2956 &lookup, 3158 &lookup,
2957 rdx, 3159 rdx,
2958 rax, 3160 rax,
2959 rcx, 3161 rcx,
2960 rbx, 3162 rbx,
2961 rdi, 3163 rdi,
2962 name, 3164 name,
2963 &miss); 3165 &miss);
2964 __ bind(&miss); 3166 __ bind(&miss);
2965 __ DecrementCounter(counters->keyed_load_interceptor(), 1); 3167 __ DecrementCounter(counters->keyed_load_interceptor(), 1);
2966 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3168 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
2967 3169
2968 // Return the generated code. 3170 // Return the generated code.
2969 return GetCode(INTERCEPTOR, name); 3171 return TryGetCode(INTERCEPTOR, name);
2970 } 3172 }
2971 3173
2972 3174
2973 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { 3175 Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength(
3176 Handle<String> name) {
2974 // ----------- S t a t e ------------- 3177 // ----------- S t a t e -------------
2975 // -- rax : key 3178 // -- rax : key
2976 // -- rdx : receiver 3179 // -- rdx : receiver
2977 // -- rsp[0] : return address 3180 // -- rsp[0] : return address
2978 // ----------------------------------- 3181 // -----------------------------------
2979 Label miss; 3182 Label miss;
2980 3183
2981 Counters* counters = isolate()->counters(); 3184 Counters* counters = isolate()->counters();
2982 __ IncrementCounter(counters->keyed_load_array_length(), 1); 3185 __ IncrementCounter(counters->keyed_load_array_length(), 1);
2983 3186
2984 // Check that the name has not changed. 3187 // Check that the name has not changed.
2985 __ Cmp(rax, Handle<String>(name)); 3188 __ Cmp(rax, name);
2986 __ j(not_equal, &miss); 3189 __ j(not_equal, &miss);
2987 3190
2988 GenerateLoadArrayLength(masm(), rdx, rcx, &miss); 3191 GenerateLoadArrayLength(masm(), rdx, rcx, &miss);
2989 __ bind(&miss); 3192 __ bind(&miss);
2990 __ DecrementCounter(counters->keyed_load_array_length(), 1); 3193 __ DecrementCounter(counters->keyed_load_array_length(), 1);
2991 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3194 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
2992 3195
2993 // Return the generated code. 3196 // Return the generated code.
2994 return GetCode(CALLBACKS, name); 3197 return GetCode(CALLBACKS, name);
2995 } 3198 }
2996 3199
2997 3200
2998 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { 3201 Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength(
3202 Handle<String> name) {
2999 // ----------- S t a t e ------------- 3203 // ----------- S t a t e -------------
3000 // -- rax : key 3204 // -- rax : key
3001 // -- rdx : receiver 3205 // -- rdx : receiver
3002 // -- rsp[0] : return address 3206 // -- rsp[0] : return address
3003 // ----------------------------------- 3207 // -----------------------------------
3004 Label miss; 3208 Label miss;
3005 3209
3006 Counters* counters = isolate()->counters(); 3210 Counters* counters = isolate()->counters();
3007 __ IncrementCounter(counters->keyed_load_string_length(), 1); 3211 __ IncrementCounter(counters->keyed_load_string_length(), 1);
3008 3212
3009 // Check that the name has not changed. 3213 // Check that the name has not changed.
3010 __ Cmp(rax, Handle<String>(name)); 3214 __ Cmp(rax, name);
3011 __ j(not_equal, &miss); 3215 __ j(not_equal, &miss);
3012 3216
3013 GenerateLoadStringLength(masm(), rdx, rcx, rbx, &miss, true); 3217 GenerateLoadStringLength(masm(), rdx, rcx, rbx, &miss, true);
3014 __ bind(&miss); 3218 __ bind(&miss);
3015 __ DecrementCounter(counters->keyed_load_string_length(), 1); 3219 __ DecrementCounter(counters->keyed_load_string_length(), 1);
3016 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3220 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3017 3221
3018 // Return the generated code. 3222 // Return the generated code.
3019 return GetCode(CALLBACKS, name); 3223 return GetCode(CALLBACKS, name);
3020 } 3224 }
3021 3225
3022 3226
3023 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { 3227 Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype(
3228 Handle<String> name) {
3024 // ----------- S t a t e ------------- 3229 // ----------- S t a t e -------------
3025 // -- rax : key 3230 // -- rax : key
3026 // -- rdx : receiver 3231 // -- rdx : receiver
3027 // -- rsp[0] : return address 3232 // -- rsp[0] : return address
3028 // ----------------------------------- 3233 // -----------------------------------
3029 Label miss; 3234 Label miss;
3030 3235
3031 Counters* counters = isolate()->counters(); 3236 Counters* counters = isolate()->counters();
3032 __ IncrementCounter(counters->keyed_load_function_prototype(), 1); 3237 __ IncrementCounter(counters->keyed_load_function_prototype(), 1);
3033 3238
3034 // Check that the name has not changed. 3239 // Check that the name has not changed.
3035 __ Cmp(rax, Handle<String>(name)); 3240 __ Cmp(rax, name);
3036 __ j(not_equal, &miss); 3241 __ j(not_equal, &miss);
3037 3242
3038 GenerateLoadFunctionPrototype(masm(), rdx, rcx, rbx, &miss); 3243 GenerateLoadFunctionPrototype(masm(), rdx, rcx, rbx, &miss);
3039 __ bind(&miss); 3244 __ bind(&miss);
3040 __ DecrementCounter(counters->keyed_load_function_prototype(), 1); 3245 __ DecrementCounter(counters->keyed_load_function_prototype(), 1);
3041 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3246 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3042 3247
3043 // Return the generated code. 3248 // Return the generated code.
3044 return GetCode(CALLBACKS, name); 3249 return GetCode(CALLBACKS, name);
3045 } 3250 }
3046 3251
3047 3252
3048 MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) { 3253 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
3254 Handle<Map> receiver_map) {
3049 // ----------- S t a t e ------------- 3255 // ----------- S t a t e -------------
3050 // -- rax : key 3256 // -- rax : key
3051 // -- rdx : receiver 3257 // -- rdx : receiver
3052 // -- rsp[0] : return address 3258 // -- rsp[0] : return address
3053 // ----------------------------------- 3259 // -----------------------------------
3054 Code* stub;
3055 ElementsKind elements_kind = receiver_map->elements_kind(); 3260 ElementsKind elements_kind = receiver_map->elements_kind();
3056 MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode(); 3261 Handle<Code> stub = KeyedLoadElementStub(elements_kind).GetCode();
3057 if (!maybe_stub->To(&stub)) return maybe_stub; 3262
3058 __ DispatchMap(rdx, 3263 __ DispatchMap(rdx, receiver_map, stub, DO_SMI_CHECK);
3059 Handle<Map>(receiver_map),
3060 Handle<Code>(stub),
3061 DO_SMI_CHECK);
3062 3264
3063 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); 3265 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss();
3064 __ jmp(ic, RelocInfo::CODE_TARGET); 3266 __ jmp(ic, RelocInfo::CODE_TARGET);
3065 3267
3066 // Return the generated code. 3268 // Return the generated code.
3067 return GetCode(NORMAL, NULL); 3269 return GetCode(NORMAL, factory()->empty_string());
3068 } 3270 }
3069 3271
3070 3272
3071 MaybeObject* KeyedLoadStubCompiler::CompileLoadPolymorphic( 3273 Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic(
3072 MapList* receiver_maps, 3274 MapHandleList* receiver_maps,
3073 CodeList* handler_ics) { 3275 CodeHandleList* handler_ics) {
3074 // ----------- S t a t e ------------- 3276 // ----------- S t a t e -------------
3075 // -- rax : key 3277 // -- rax : key
3076 // -- rdx : receiver 3278 // -- rdx : receiver
3077 // -- rsp[0] : return address 3279 // -- rsp[0] : return address
3078 // ----------------------------------- 3280 // -----------------------------------
3079 Label miss; 3281 Label miss;
3080 __ JumpIfSmi(rdx, &miss); 3282 __ JumpIfSmi(rdx, &miss);
3081 3283
3082 Register map_reg = rbx; 3284 Register map_reg = rbx;
3083 __ movq(map_reg, FieldOperand(rdx, HeapObject::kMapOffset)); 3285 __ movq(map_reg, FieldOperand(rdx, HeapObject::kMapOffset));
3084 int receiver_count = receiver_maps->length(); 3286 int receiver_count = receiver_maps->length();
3085 for (int current = 0; current < receiver_count; ++current) { 3287 for (int current = 0; current < receiver_count; ++current) {
3086 // Check map and tail call if there's a match 3288 // Check map and tail call if there's a match
3087 Handle<Map> map(receiver_maps->at(current)); 3289 __ Cmp(map_reg, receiver_maps->at(current));
3088 __ Cmp(map_reg, map); 3290 __ j(equal, handler_ics->at(current), RelocInfo::CODE_TARGET);
3089 __ j(equal,
3090 Handle<Code>(handler_ics->at(current)),
3091 RelocInfo::CODE_TARGET);
3092 } 3291 }
3093 3292
3094 __ bind(&miss); 3293 __ bind(&miss);
3095 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3294 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3096 3295
3097 // Return the generated code. 3296 // Return the generated code.
3098 return GetCode(NORMAL, NULL, MEGAMORPHIC); 3297 return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC);
3099 } 3298 }
3100 3299
3101 3300
3102 // Specialized stub for constructing objects from functions which only have only 3301 // Specialized stub for constructing objects from functions which only have only
3103 // simple assignments of the form this.x = ...; in their body. 3302 // simple assignments of the form this.x = ...; in their body.
3104 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { 3303 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) {
3105 // ----------- S t a t e ------------- 3304 // ----------- S t a t e -------------
3106 // -- rax : argc 3305 // -- rax : argc
3107 // -- rdi : constructor 3306 // -- rdi : constructor
3108 // -- rsp[0] : return address 3307 // -- rsp[0] : return address
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after
3804 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); 4003 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
3805 __ jmp(ic_miss, RelocInfo::CODE_TARGET); 4004 __ jmp(ic_miss, RelocInfo::CODE_TARGET);
3806 } 4005 }
3807 4006
3808 4007
3809 #undef __ 4008 #undef __
3810 4009
3811 } } // namespace v8::internal 4010 } } // namespace v8::internal
3812 4011
3813 #endif // V8_TARGET_ARCH_X64 4012 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/regexp-macro-assembler-x64.cc ('k') | test/cctest/cctest.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698