OLD | NEW |
---|---|
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 Loading... | |
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, | |
ulan
2011/10/24 16:28:25
Indentation is broken.
| |
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 Loading... | |
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 Loading... | |
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 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
801 } | 851 } |
802 | 852 |
803 // Return the value (register rax). | 853 // Return the value (register rax). |
804 __ ret(0); | 854 __ ret(0); |
805 } | 855 } |
806 | 856 |
807 | 857 |
808 // Generate code to check that a global property cell is empty. Create | 858 // 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 | 859 // the property cell at compilation time if no cell exists for the |
810 // property. | 860 // property. |
811 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCell( | 861 static void GenerateCheckPropertyCell(MacroAssembler* masm, |
862 Handle<GlobalObject> global, | |
863 Handle<String> name, | |
864 Register scratch, | |
865 Label* miss) { | |
866 Handle<JSGlobalPropertyCell> cell = | |
867 GlobalObject::EnsurePropertyCell(global, name); | |
868 ASSERT(cell->value()->IsTheHole()); | |
869 __ Move(scratch, cell); | |
870 __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), | |
871 masm->isolate()->factory()->the_hole_value()); | |
872 __ j(not_equal, miss); | |
873 } | |
874 | |
875 | |
876 // TODO(kmillikin): Eliminate this function when the stub cache is fully | |
877 // handlified. | |
878 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCell( | |
812 MacroAssembler* masm, | 879 MacroAssembler* masm, |
813 GlobalObject* global, | 880 GlobalObject* global, |
814 String* name, | 881 String* name, |
815 Register scratch, | 882 Register scratch, |
816 Label* miss) { | 883 Label* miss) { |
817 Object* probe; | 884 Object* probe; |
818 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); | 885 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); |
819 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 886 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
820 } | 887 } |
821 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); | 888 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); |
822 ASSERT(cell->value()->IsTheHole()); | 889 ASSERT(cell->value()->IsTheHole()); |
823 __ Move(scratch, Handle<Object>(cell)); | 890 __ Move(scratch, Handle<Object>(cell)); |
824 __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), | 891 __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), |
825 masm->isolate()->factory()->the_hole_value()); | 892 masm->isolate()->factory()->the_hole_value()); |
826 __ j(not_equal, miss); | 893 __ j(not_equal, miss); |
827 return cell; | 894 return cell; |
828 } | 895 } |
829 | 896 |
830 | 897 |
898 // Calls GenerateCheckPropertyCell for each global object in the prototype chain | |
899 // from object to (but not including) holder. | |
900 static void GenerateCheckPropertyCells(MacroAssembler* masm, | |
901 Handle<JSObject> object, | |
902 Handle<JSObject> holder, | |
903 Handle<String> name, | |
904 Register scratch, | |
905 Label* miss) { | |
906 Handle<JSObject> current = object; | |
907 while (!current.is_identical_to(holder)) { | |
908 if (current->IsGlobalObject()) { | |
909 GenerateCheckPropertyCell(masm, | |
910 Handle<GlobalObject>::cast(current), | |
911 name, | |
912 scratch, | |
913 miss); | |
914 } | |
915 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); | |
916 } | |
917 } | |
918 | |
919 | |
920 // TODO(kmillikin): Eliminate this function when the stub cache is fully | |
921 // handlified. | |
922 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCells( | |
923 MacroAssembler* masm, | |
924 JSObject* object, | |
925 JSObject* holder, | |
926 String* name, | |
927 Register scratch, | |
928 Label* miss) { | |
929 JSObject* current = object; | |
930 while (current != holder) { | |
931 if (current->IsGlobalObject()) { | |
932 // Returns a cell or a failure. | |
933 MaybeObject* result = TryGenerateCheckPropertyCell( | |
934 masm, | |
935 GlobalObject::cast(current), | |
936 name, | |
937 scratch, | |
938 miss); | |
939 if (result->IsFailure()) return result; | |
940 } | |
941 ASSERT(current->IsJSObject()); | |
942 current = JSObject::cast(current->GetPrototype()); | |
943 } | |
944 return NULL; | |
945 } | |
946 | |
947 | |
831 #undef __ | 948 #undef __ |
832 #define __ ACCESS_MASM((masm())) | 949 #define __ ACCESS_MASM((masm())) |
833 | 950 |
834 | 951 |
952 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, | |
953 Register object_reg, | |
954 Handle<JSObject> holder, | |
955 Register holder_reg, | |
956 Register scratch1, | |
957 Register scratch2, | |
958 Handle<String> name, | |
959 int save_at_depth, | |
960 Label* miss) { | |
961 // Make sure there's no overlap between holder and object registers. | |
962 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | |
963 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | |
964 && !scratch2.is(scratch1)); | |
965 | |
966 // Keep track of the current object in register reg. On the first | |
967 // iteration, reg is an alias for object_reg, on later iterations, | |
968 // it is an alias for holder_reg. | |
969 Register reg = object_reg; | |
970 int depth = 0; | |
971 | |
972 if (save_at_depth == depth) { | |
973 __ movq(Operand(rsp, kPointerSize), object_reg); | |
974 } | |
975 | |
976 // Check the maps in the prototype chain. | |
977 // Traverse the prototype chain from the object and do map checks. | |
978 Handle<JSObject> current = object; | |
979 while (!current.is_identical_to(holder)) { | |
980 ++depth; | |
981 | |
982 // Only global objects and objects that do not require access | |
983 // checks are allowed in stubs. | |
984 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | |
985 | |
986 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); | |
987 if (!current->HasFastProperties() && | |
988 !current->IsJSGlobalObject() && | |
989 !current->IsJSGlobalProxy()) { | |
990 if (!name->IsSymbol()) { | |
991 name = factory()->LookupSymbol(name); | |
992 } | |
993 ASSERT(current->property_dictionary()->FindEntry(*name) == | |
994 StringDictionary::kNotFound); | |
995 | |
996 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, | |
997 scratch1, scratch2); | |
998 | |
999 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | |
1000 reg = holder_reg; // From now on the object will be in holder_reg. | |
1001 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); | |
1002 } else { | |
1003 bool in_new_space = heap()->InNewSpace(*prototype); | |
1004 Handle<Map> current_map(current->map()); | |
1005 if (in_new_space) { | |
1006 // Save the map in scratch1 for later. | |
1007 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | |
1008 __ Cmp(scratch1, current_map); | |
1009 } else { | |
1010 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), current_map); | |
1011 } | |
1012 // Branch on the result of the map check. | |
1013 __ j(not_equal, miss); | |
1014 // Check access rights to the global object. This has to happen after | |
1015 // the map check so that we know that the object is actually a global | |
1016 // object. | |
1017 if (current->IsJSGlobalProxy()) { | |
1018 __ CheckAccessGlobalProxy(reg, scratch2, miss); | |
1019 } | |
1020 reg = holder_reg; // From now on the object will be in holder_reg. | |
1021 | |
1022 if (in_new_space) { | |
1023 // The prototype is in new space; we cannot store a reference to it | |
1024 // in the code. Load it from the map. | |
1025 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); | |
1026 } else { | |
1027 // The prototype is in old space; load it directly. | |
1028 __ Move(reg, prototype); | |
1029 } | |
1030 } | |
1031 | |
1032 if (save_at_depth == depth) { | |
1033 __ movq(Operand(rsp, kPointerSize), reg); | |
1034 } | |
1035 | |
1036 // Go to the next object in the prototype chain. | |
1037 current = prototype; | |
1038 } | |
1039 ASSERT(current.is_identical_to(holder)); | |
1040 | |
1041 // Log the check depth. | |
1042 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); | |
1043 | |
1044 // Check the holder map. | |
1045 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), Handle<Map>(holder->map())); | |
1046 __ j(not_equal, miss); | |
1047 | |
1048 // Perform security check for access to the global object. | |
1049 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | |
1050 if (current->IsJSGlobalProxy()) { | |
1051 __ CheckAccessGlobalProxy(reg, scratch1, miss); | |
1052 } | |
1053 | |
1054 // If we've skipped any global objects, it's not enough to verify that | |
1055 // their maps haven't changed. We also need to check that the property | |
1056 // cell for the property is still empty. | |
1057 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); | |
1058 | |
1059 // Return the register containing the holder. | |
1060 return reg; | |
1061 } | |
1062 | |
1063 | |
835 Register StubCompiler::CheckPrototypes(JSObject* object, | 1064 Register StubCompiler::CheckPrototypes(JSObject* object, |
836 Register object_reg, | 1065 Register object_reg, |
837 JSObject* holder, | 1066 JSObject* holder, |
838 Register holder_reg, | 1067 Register holder_reg, |
839 Register scratch1, | 1068 Register scratch1, |
840 Register scratch2, | 1069 Register scratch2, |
841 String* name, | 1070 String* name, |
842 int save_at_depth, | 1071 int save_at_depth, |
843 Label* miss) { | 1072 Label* miss) { |
844 // Make sure there's no overlap between holder and object registers. | 1073 // Make sure there's no overlap between holder and object registers. |
(...skipping 30 matching lines...) Expand all Loading... | |
875 if (lookup_result->IsFailure()) { | 1104 if (lookup_result->IsFailure()) { |
876 set_failure(Failure::cast(lookup_result)); | 1105 set_failure(Failure::cast(lookup_result)); |
877 return reg; | 1106 return reg; |
878 } else { | 1107 } else { |
879 name = String::cast(lookup_result->ToObjectUnchecked()); | 1108 name = String::cast(lookup_result->ToObjectUnchecked()); |
880 } | 1109 } |
881 } | 1110 } |
882 ASSERT(current->property_dictionary()->FindEntry(name) == | 1111 ASSERT(current->property_dictionary()->FindEntry(name) == |
883 StringDictionary::kNotFound); | 1112 StringDictionary::kNotFound); |
884 | 1113 |
885 MaybeObject* negative_lookup = GenerateDictionaryNegativeLookup(masm(), | 1114 MaybeObject* negative_lookup = |
886 miss, | 1115 TryGenerateDictionaryNegativeLookup(masm(), |
887 reg, | 1116 miss, |
888 name, | 1117 reg, |
889 scratch1, | 1118 name, |
890 scratch2); | 1119 scratch1, |
1120 scratch2); | |
891 if (negative_lookup->IsFailure()) { | 1121 if (negative_lookup->IsFailure()) { |
892 set_failure(Failure::cast(negative_lookup)); | 1122 set_failure(Failure::cast(negative_lookup)); |
893 return reg; | 1123 return reg; |
894 } | 1124 } |
895 | 1125 |
896 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 1126 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
897 reg = holder_reg; // from now the object is in holder_reg | 1127 reg = holder_reg; // from now the object is in holder_reg |
898 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); | 1128 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); |
899 } else if (heap()->InNewSpace(prototype)) { | 1129 } else if (heap()->InNewSpace(prototype)) { |
900 // Get the map of the current object. | 1130 // Get the map of the current object. |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
953 // the holder register. | 1183 // the holder register. |
954 ASSERT(current == holder); | 1184 ASSERT(current == holder); |
955 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 1185 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); |
956 if (current->IsJSGlobalProxy()) { | 1186 if (current->IsJSGlobalProxy()) { |
957 __ CheckAccessGlobalProxy(reg, scratch1, miss); | 1187 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
958 } | 1188 } |
959 | 1189 |
960 // If we've skipped any global objects, it's not enough to verify | 1190 // 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 | 1191 // that their maps haven't changed. We also need to check that the |
962 // property cell for the property is still empty. | 1192 // property cell for the property is still empty. |
963 current = object; | 1193 MaybeObject* result = TryGenerateCheckPropertyCells(masm(), |
964 while (current != holder) { | 1194 object, |
965 if (current->IsGlobalObject()) { | 1195 holder, |
966 MaybeObject* cell = GenerateCheckPropertyCell(masm(), | 1196 name, |
967 GlobalObject::cast(current), | 1197 scratch1, |
968 name, | 1198 miss); |
969 scratch1, | 1199 if (result->IsFailure()) set_failure(Failure::cast(result)); |
ulan
2011/10/24 16:28:25
The result can be NULL. It works but looks suspici
| |
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 | 1200 |
979 // Return the register containing the holder. | 1201 // Return the register containing the holder. |
980 return reg; | 1202 return reg; |
981 } | 1203 } |
982 | 1204 |
983 | 1205 |
984 void StubCompiler::GenerateLoadField(JSObject* object, | 1206 void StubCompiler::GenerateLoadField(JSObject* object, |
985 JSObject* holder, | 1207 JSObject* holder, |
986 Register receiver, | 1208 Register receiver, |
987 Register scratch1, | 1209 Register scratch1, |
988 Register scratch2, | 1210 Register scratch2, |
989 Register scratch3, | 1211 Register scratch3, |
990 int index, | 1212 int index, |
991 String* name, | 1213 String* name, |
992 Label* miss) { | 1214 Label* miss) { |
993 // Check that the receiver isn't a smi. | 1215 // Check that the receiver isn't a smi. |
994 __ JumpIfSmi(receiver, miss); | 1216 __ JumpIfSmi(receiver, miss); |
995 | 1217 |
996 // Check the prototype chain. | 1218 // Check the prototype chain. |
997 Register reg = | 1219 Register reg = |
998 CheckPrototypes(object, receiver, holder, | 1220 CheckPrototypes(object, receiver, holder, |
999 scratch1, scratch2, scratch3, name, miss); | 1221 scratch1, scratch2, scratch3, name, miss); |
1000 | 1222 |
1001 // Get the value from the properties. | 1223 // Get the value from the properties. |
1002 GenerateFastPropertyLoad(masm(), rax, reg, holder, index); | 1224 GenerateFastPropertyLoad(masm(), rax, reg, Handle<JSObject>(holder), index); |
1003 __ ret(0); | 1225 __ ret(0); |
1004 } | 1226 } |
1005 | 1227 |
1006 | 1228 |
1007 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, | 1229 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, |
1008 JSObject* holder, | 1230 JSObject* holder, |
1009 Register receiver, | 1231 Register receiver, |
1010 Register name_reg, | 1232 Register name_reg, |
1011 Register scratch1, | 1233 Register scratch1, |
1012 Register scratch2, | 1234 Register scratch2, |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1191 scratch2, | 1413 scratch2, |
1192 scratch3, | 1414 scratch3, |
1193 name, | 1415 name, |
1194 miss); | 1416 miss); |
1195 } | 1417 } |
1196 | 1418 |
1197 if (lookup->type() == FIELD) { | 1419 if (lookup->type() == FIELD) { |
1198 // We found FIELD property in prototype chain of interceptor's holder. | 1420 // We found FIELD property in prototype chain of interceptor's holder. |
1199 // Retrieve a field from field's holder. | 1421 // Retrieve a field from field's holder. |
1200 GenerateFastPropertyLoad(masm(), rax, holder_reg, | 1422 GenerateFastPropertyLoad(masm(), rax, holder_reg, |
1201 lookup->holder(), lookup->GetFieldIndex()); | 1423 Handle<JSObject>(lookup->holder()), |
1424 lookup->GetFieldIndex()); | |
1202 __ ret(0); | 1425 __ ret(0); |
1203 } else { | 1426 } else { |
1204 // We found CALLBACKS property in prototype chain of interceptor's | 1427 // We found CALLBACKS property in prototype chain of interceptor's |
1205 // holder. | 1428 // holder. |
1206 ASSERT(lookup->type() == CALLBACKS); | 1429 ASSERT(lookup->type() == CALLBACKS); |
1207 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); | 1430 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); |
1208 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); | 1431 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); |
1209 ASSERT(callback != NULL); | 1432 ASSERT(callback != NULL); |
1210 ASSERT(callback->getter() != NULL); | 1433 ASSERT(callback->getter() != NULL); |
1211 | 1434 |
(...skipping 25 matching lines...) Expand all Loading... | |
1237 name_reg, interceptor_holder); | 1460 name_reg, interceptor_holder); |
1238 __ push(scratch2); // restore old return address | 1461 __ push(scratch2); // restore old return address |
1239 | 1462 |
1240 ExternalReference ref = ExternalReference( | 1463 ExternalReference ref = ExternalReference( |
1241 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate()); | 1464 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate()); |
1242 __ TailCallExternalReference(ref, 5, 1); | 1465 __ TailCallExternalReference(ref, 5, 1); |
1243 } | 1466 } |
1244 } | 1467 } |
1245 | 1468 |
1246 | 1469 |
1247 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { | 1470 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) { |
1248 if (kind_ == Code::KEYED_CALL_IC) { | 1471 if (kind_ == Code::KEYED_CALL_IC) { |
1249 __ Cmp(rcx, Handle<String>(name)); | 1472 __ Cmp(rcx, name); |
1250 __ j(not_equal, miss); | 1473 __ j(not_equal, miss); |
1251 } | 1474 } |
1252 } | 1475 } |
1253 | 1476 |
1254 | 1477 |
1255 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, | 1478 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, |
1256 JSObject* holder, | 1479 JSObject* holder, |
1257 String* name, | 1480 String* name, |
1258 Label* miss) { | 1481 Label* miss) { |
1259 ASSERT(holder->IsGlobalObject()); | 1482 ASSERT(holder->IsGlobalObject()); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1298 __ Move(rax, Handle<SharedFunctionInfo>(function->shared())); | 1521 __ Move(rax, Handle<SharedFunctionInfo>(function->shared())); |
1299 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax); | 1522 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax); |
1300 __ j(not_equal, miss); | 1523 __ j(not_equal, miss); |
1301 } else { | 1524 } else { |
1302 __ Cmp(rdi, Handle<JSFunction>(function)); | 1525 __ Cmp(rdi, Handle<JSFunction>(function)); |
1303 __ j(not_equal, miss); | 1526 __ j(not_equal, miss); |
1304 } | 1527 } |
1305 } | 1528 } |
1306 | 1529 |
1307 | 1530 |
1308 MaybeObject* CallStubCompiler::GenerateMissBranch() { | 1531 void CallStubCompiler::GenerateMissBranch() { |
1532 Handle<Code> code = | |
1533 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), | |
1534 kind_, | |
1535 extra_state_); | |
1536 __ Jump(code, RelocInfo::CODE_TARGET); | |
1537 } | |
1538 | |
1539 | |
1540 // TODO(kmillikin): Eliminate this function when the stub cache is fully | |
1541 // handlified. | |
1542 MaybeObject* CallStubCompiler::TryGenerateMissBranch() { | |
1309 MaybeObject* maybe_obj = | 1543 MaybeObject* maybe_obj = |
1310 isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(), | 1544 isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(), |
1311 kind_, | 1545 kind_, |
1312 extra_state_); | 1546 extra_state_); |
1313 Object* obj; | 1547 Object* obj; |
1314 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1548 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
1315 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); | 1549 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); |
1316 return obj; | 1550 return obj; |
1317 } | 1551 } |
1318 | 1552 |
1319 | 1553 |
1320 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object, | 1554 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, |
1321 JSObject* holder, | 1555 Handle<JSObject> holder, |
1322 int index, | 1556 int index, |
1323 String* name) { | 1557 Handle<String> name) { |
1324 // ----------- S t a t e ------------- | 1558 // ----------- S t a t e ------------- |
1325 // rcx : function name | 1559 // rcx : function name |
1326 // rsp[0] : return address | 1560 // rsp[0] : return address |
1327 // rsp[8] : argument argc | 1561 // rsp[8] : argument argc |
1328 // rsp[16] : argument argc - 1 | 1562 // rsp[16] : argument argc - 1 |
1329 // ... | 1563 // ... |
1330 // rsp[argc * 8] : argument 1 | 1564 // rsp[argc * 8] : argument 1 |
1331 // rsp[(argc + 1) * 8] : argument 0 = receiver | 1565 // rsp[(argc + 1) * 8] : argument 0 = receiver |
1332 // ----------------------------------- | 1566 // ----------------------------------- |
1333 Label miss; | 1567 Label miss; |
(...skipping 26 matching lines...) Expand all Loading... | |
1360 } | 1594 } |
1361 | 1595 |
1362 // Invoke the function. | 1596 // Invoke the function. |
1363 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 1597 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
1364 ? CALL_AS_FUNCTION | 1598 ? CALL_AS_FUNCTION |
1365 : CALL_AS_METHOD; | 1599 : CALL_AS_METHOD; |
1366 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, | 1600 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, |
1367 NullCallWrapper(), call_kind); | 1601 NullCallWrapper(), call_kind); |
1368 | 1602 |
1369 // Handle call cache miss. | 1603 // Handle call cache miss. |
1370 __ bind(&miss); | 1604 __ bind(&miss);GenerateMissBranch(); |
ulan
2011/10/24 16:28:25
New line between statements.
| |
1371 MaybeObject* maybe_result = GenerateMissBranch(); | |
1372 if (maybe_result->IsFailure()) return maybe_result; | |
1373 | 1605 |
1374 // Return the generated code. | 1606 // Return the generated code. |
1375 return GetCode(FIELD, name); | 1607 return GetCode(FIELD, name); |
1376 } | 1608 } |
1377 | 1609 |
1378 | 1610 |
1379 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, | 1611 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, |
1380 JSObject* holder, | 1612 JSObject* holder, |
1381 JSGlobalPropertyCell* cell, | 1613 JSGlobalPropertyCell* cell, |
1382 JSFunction* function, | 1614 JSFunction* function, |
1383 String* name) { | 1615 String* name) { |
1384 // ----------- S t a t e ------------- | 1616 // ----------- S t a t e ------------- |
1385 // -- rcx : name | 1617 // -- rcx : name |
1386 // -- rsp[0] : return address | 1618 // -- rsp[0] : return address |
1387 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1619 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1388 // -- ... | 1620 // -- ... |
1389 // -- rsp[(argc + 1) * 8] : receiver | 1621 // -- rsp[(argc + 1) * 8] : receiver |
1390 // ----------------------------------- | 1622 // ----------------------------------- |
1391 | 1623 |
1392 // If object is not an array, bail out to regular call. | 1624 // If object is not an array, bail out to regular call. |
1393 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); | 1625 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); |
1394 | 1626 |
1395 Label miss; | 1627 Label miss; |
1396 | 1628 |
1397 GenerateNameCheck(name, &miss); | 1629 GenerateNameCheck(Handle<String>(name), &miss); |
1398 | 1630 |
1399 // Get the receiver from the stack. | 1631 // Get the receiver from the stack. |
1400 const int argc = arguments().immediate(); | 1632 const int argc = arguments().immediate(); |
1401 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 1633 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
1402 | 1634 |
1403 // Check that the receiver isn't a smi. | 1635 // Check that the receiver isn't a smi. |
1404 __ JumpIfSmi(rdx, &miss); | 1636 __ JumpIfSmi(rdx, &miss); |
1405 | 1637 |
1406 CheckPrototypes(JSObject::cast(object), | 1638 CheckPrototypes(JSObject::cast(object), |
1407 rdx, | 1639 rdx, |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1546 } | 1778 } |
1547 | 1779 |
1548 __ bind(&call_builtin); | 1780 __ bind(&call_builtin); |
1549 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, | 1781 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, |
1550 isolate()), | 1782 isolate()), |
1551 argc + 1, | 1783 argc + 1, |
1552 1); | 1784 1); |
1553 } | 1785 } |
1554 | 1786 |
1555 __ bind(&miss); | 1787 __ bind(&miss); |
1556 MaybeObject* maybe_result = GenerateMissBranch(); | 1788 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1557 if (maybe_result->IsFailure()) return maybe_result; | 1789 if (maybe_result->IsFailure()) return maybe_result; |
1558 | 1790 |
1559 // Return the generated code. | 1791 // Return the generated code. |
1560 return GetCode(function); | 1792 return TryGetCode(function); |
1561 } | 1793 } |
1562 | 1794 |
1563 | 1795 |
1564 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, | 1796 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, |
1565 JSObject* holder, | 1797 JSObject* holder, |
1566 JSGlobalPropertyCell* cell, | 1798 JSGlobalPropertyCell* cell, |
1567 JSFunction* function, | 1799 JSFunction* function, |
1568 String* name) { | 1800 String* name) { |
1569 // ----------- S t a t e ------------- | 1801 // ----------- S t a t e ------------- |
1570 // -- rcx : name | 1802 // -- rcx : name |
1571 // -- rsp[0] : return address | 1803 // -- rsp[0] : return address |
1572 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1804 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1573 // -- ... | 1805 // -- ... |
1574 // -- rsp[(argc + 1) * 8] : receiver | 1806 // -- rsp[(argc + 1) * 8] : receiver |
1575 // ----------------------------------- | 1807 // ----------------------------------- |
1576 | 1808 |
1577 // If object is not an array, bail out to regular call. | 1809 // If object is not an array, bail out to regular call. |
1578 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); | 1810 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); |
1579 | 1811 |
1580 Label miss, return_undefined, call_builtin; | 1812 Label miss, return_undefined, call_builtin; |
1581 | 1813 |
1582 GenerateNameCheck(name, &miss); | 1814 GenerateNameCheck(Handle<String>(name), &miss); |
1583 | 1815 |
1584 // Get the receiver from the stack. | 1816 // Get the receiver from the stack. |
1585 const int argc = arguments().immediate(); | 1817 const int argc = arguments().immediate(); |
1586 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 1818 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
1587 | 1819 |
1588 // Check that the receiver isn't a smi. | 1820 // Check that the receiver isn't a smi. |
1589 __ JumpIfSmi(rdx, &miss); | 1821 __ JumpIfSmi(rdx, &miss); |
1590 | 1822 |
1591 CheckPrototypes(JSObject::cast(object), rdx, | 1823 CheckPrototypes(JSObject::cast(object), rdx, |
1592 holder, rbx, | 1824 holder, rbx, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1629 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); | 1861 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); |
1630 __ ret((argc + 1) * kPointerSize); | 1862 __ ret((argc + 1) * kPointerSize); |
1631 | 1863 |
1632 __ bind(&call_builtin); | 1864 __ bind(&call_builtin); |
1633 __ TailCallExternalReference( | 1865 __ TailCallExternalReference( |
1634 ExternalReference(Builtins::c_ArrayPop, isolate()), | 1866 ExternalReference(Builtins::c_ArrayPop, isolate()), |
1635 argc + 1, | 1867 argc + 1, |
1636 1); | 1868 1); |
1637 | 1869 |
1638 __ bind(&miss); | 1870 __ bind(&miss); |
1639 MaybeObject* maybe_result = GenerateMissBranch(); | 1871 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1640 if (maybe_result->IsFailure()) return maybe_result; | 1872 if (maybe_result->IsFailure()) return maybe_result; |
1641 | 1873 |
1642 // Return the generated code. | 1874 // Return the generated code. |
1643 return GetCode(function); | 1875 return TryGetCode(function); |
1644 } | 1876 } |
1645 | 1877 |
1646 | 1878 |
1647 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( | 1879 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( |
1648 Object* object, | 1880 Object* object, |
1649 JSObject* holder, | 1881 JSObject* holder, |
1650 JSGlobalPropertyCell* cell, | 1882 JSGlobalPropertyCell* cell, |
1651 JSFunction* function, | 1883 JSFunction* function, |
1652 String* name) { | 1884 String* name) { |
1653 // ----------- S t a t e ------------- | 1885 // ----------- S t a t e ------------- |
(...skipping 13 matching lines...) Expand all Loading... | |
1667 Label name_miss; | 1899 Label name_miss; |
1668 Label index_out_of_range; | 1900 Label index_out_of_range; |
1669 Label* index_out_of_range_label = &index_out_of_range; | 1901 Label* index_out_of_range_label = &index_out_of_range; |
1670 | 1902 |
1671 if (kind_ == Code::CALL_IC && | 1903 if (kind_ == Code::CALL_IC && |
1672 (CallICBase::StringStubState::decode(extra_state_) == | 1904 (CallICBase::StringStubState::decode(extra_state_) == |
1673 DEFAULT_STRING_STUB)) { | 1905 DEFAULT_STRING_STUB)) { |
1674 index_out_of_range_label = &miss; | 1906 index_out_of_range_label = &miss; |
1675 } | 1907 } |
1676 | 1908 |
1677 GenerateNameCheck(name, &name_miss); | 1909 GenerateNameCheck(Handle<String>(name), &name_miss); |
1678 | 1910 |
1679 // Check that the maps starting from the prototype haven't changed. | 1911 // Check that the maps starting from the prototype haven't changed. |
1680 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 1912 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
1681 Context::STRING_FUNCTION_INDEX, | 1913 Context::STRING_FUNCTION_INDEX, |
1682 rax, | 1914 rax, |
1683 &miss); | 1915 &miss); |
1684 ASSERT(object != holder); | 1916 ASSERT(object != holder); |
1685 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, | 1917 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, |
1686 rbx, rdx, rdi, name, &miss); | 1918 rbx, rdx, rdi, name, &miss); |
1687 | 1919 |
(...skipping 25 matching lines...) Expand all Loading... | |
1713 if (index_out_of_range.is_linked()) { | 1945 if (index_out_of_range.is_linked()) { |
1714 __ bind(&index_out_of_range); | 1946 __ bind(&index_out_of_range); |
1715 __ LoadRoot(rax, Heap::kNanValueRootIndex); | 1947 __ LoadRoot(rax, Heap::kNanValueRootIndex); |
1716 __ ret((argc + 1) * kPointerSize); | 1948 __ ret((argc + 1) * kPointerSize); |
1717 } | 1949 } |
1718 | 1950 |
1719 __ bind(&miss); | 1951 __ bind(&miss); |
1720 // Restore function name in rcx. | 1952 // Restore function name in rcx. |
1721 __ Move(rcx, Handle<String>(name)); | 1953 __ Move(rcx, Handle<String>(name)); |
1722 __ bind(&name_miss); | 1954 __ bind(&name_miss); |
1723 MaybeObject* maybe_result = GenerateMissBranch(); | 1955 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1724 if (maybe_result->IsFailure()) return maybe_result; | 1956 if (maybe_result->IsFailure()) return maybe_result; |
1725 | 1957 |
1726 // Return the generated code. | 1958 // Return the generated code. |
1727 return GetCode(function); | 1959 return TryGetCode(function); |
1728 } | 1960 } |
1729 | 1961 |
1730 | 1962 |
1731 MaybeObject* CallStubCompiler::CompileStringCharAtCall( | 1963 MaybeObject* CallStubCompiler::CompileStringCharAtCall( |
1732 Object* object, | 1964 Object* object, |
1733 JSObject* holder, | 1965 JSObject* holder, |
1734 JSGlobalPropertyCell* cell, | 1966 JSGlobalPropertyCell* cell, |
1735 JSFunction* function, | 1967 JSFunction* function, |
1736 String* name) { | 1968 String* name) { |
1737 // ----------- S t a t e ------------- | 1969 // ----------- S t a t e ------------- |
(...skipping 13 matching lines...) Expand all Loading... | |
1751 Label name_miss; | 1983 Label name_miss; |
1752 Label index_out_of_range; | 1984 Label index_out_of_range; |
1753 Label* index_out_of_range_label = &index_out_of_range; | 1985 Label* index_out_of_range_label = &index_out_of_range; |
1754 | 1986 |
1755 if (kind_ == Code::CALL_IC && | 1987 if (kind_ == Code::CALL_IC && |
1756 (CallICBase::StringStubState::decode(extra_state_) == | 1988 (CallICBase::StringStubState::decode(extra_state_) == |
1757 DEFAULT_STRING_STUB)) { | 1989 DEFAULT_STRING_STUB)) { |
1758 index_out_of_range_label = &miss; | 1990 index_out_of_range_label = &miss; |
1759 } | 1991 } |
1760 | 1992 |
1761 GenerateNameCheck(name, &name_miss); | 1993 GenerateNameCheck(Handle<String>(name), &name_miss); |
1762 | 1994 |
1763 // Check that the maps starting from the prototype haven't changed. | 1995 // Check that the maps starting from the prototype haven't changed. |
1764 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 1996 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
1765 Context::STRING_FUNCTION_INDEX, | 1997 Context::STRING_FUNCTION_INDEX, |
1766 rax, | 1998 rax, |
1767 &miss); | 1999 &miss); |
1768 ASSERT(object != holder); | 2000 ASSERT(object != holder); |
1769 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, | 2001 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, |
1770 rbx, rdx, rdi, name, &miss); | 2002 rbx, rdx, rdi, name, &miss); |
1771 | 2003 |
(...skipping 27 matching lines...) Expand all Loading... | |
1799 if (index_out_of_range.is_linked()) { | 2031 if (index_out_of_range.is_linked()) { |
1800 __ bind(&index_out_of_range); | 2032 __ bind(&index_out_of_range); |
1801 __ LoadRoot(rax, Heap::kEmptyStringRootIndex); | 2033 __ LoadRoot(rax, Heap::kEmptyStringRootIndex); |
1802 __ ret((argc + 1) * kPointerSize); | 2034 __ ret((argc + 1) * kPointerSize); |
1803 } | 2035 } |
1804 | 2036 |
1805 __ bind(&miss); | 2037 __ bind(&miss); |
1806 // Restore function name in rcx. | 2038 // Restore function name in rcx. |
1807 __ Move(rcx, Handle<String>(name)); | 2039 __ Move(rcx, Handle<String>(name)); |
1808 __ bind(&name_miss); | 2040 __ bind(&name_miss); |
1809 MaybeObject* maybe_result = GenerateMissBranch(); | 2041 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1810 if (maybe_result->IsFailure()) return maybe_result; | 2042 if (maybe_result->IsFailure()) return maybe_result; |
1811 | 2043 |
1812 // Return the generated code. | 2044 // Return the generated code. |
1813 return GetCode(function); | 2045 return TryGetCode(function); |
1814 } | 2046 } |
1815 | 2047 |
1816 | 2048 |
1817 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( | 2049 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( |
1818 Object* object, | 2050 Object* object, |
1819 JSObject* holder, | 2051 JSObject* holder, |
1820 JSGlobalPropertyCell* cell, | 2052 JSGlobalPropertyCell* cell, |
1821 JSFunction* function, | 2053 JSFunction* function, |
1822 String* name) { | 2054 String* name) { |
1823 // ----------- S t a t e ------------- | 2055 // ----------- S t a t e ------------- |
1824 // -- rcx : function name | 2056 // -- rcx : function name |
1825 // -- rsp[0] : return address | 2057 // -- rsp[0] : return address |
1826 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 2058 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1827 // -- ... | 2059 // -- ... |
1828 // -- rsp[(argc + 1) * 8] : receiver | 2060 // -- rsp[(argc + 1) * 8] : receiver |
1829 // ----------------------------------- | 2061 // ----------------------------------- |
1830 | 2062 |
1831 const int argc = arguments().immediate(); | 2063 const int argc = arguments().immediate(); |
1832 | 2064 |
1833 // If the object is not a JSObject or we got an unexpected number of | 2065 // If the object is not a JSObject or we got an unexpected number of |
1834 // arguments, bail out to the regular call. | 2066 // arguments, bail out to the regular call. |
1835 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 2067 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); |
1836 | 2068 |
1837 Label miss; | 2069 Label miss; |
1838 GenerateNameCheck(name, &miss); | 2070 GenerateNameCheck(Handle<String>(name), &miss); |
1839 | 2071 |
1840 if (cell == NULL) { | 2072 if (cell == NULL) { |
1841 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); | 2073 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); |
1842 | 2074 |
1843 __ JumpIfSmi(rdx, &miss); | 2075 __ JumpIfSmi(rdx, &miss); |
1844 | 2076 |
1845 CheckPrototypes(JSObject::cast(object), rdx, holder, rbx, rax, rdi, name, | 2077 CheckPrototypes(JSObject::cast(object), rdx, holder, rbx, rax, rdi, name, |
1846 &miss); | 2078 &miss); |
1847 } else { | 2079 } else { |
1848 ASSERT(cell->value() == function); | 2080 ASSERT(cell->value() == function); |
(...skipping 23 matching lines...) Expand all Loading... | |
1872 // because the function makes no use of it. | 2104 // because the function makes no use of it. |
1873 __ bind(&slow); | 2105 __ bind(&slow); |
1874 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2106 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
1875 ? CALL_AS_FUNCTION | 2107 ? CALL_AS_FUNCTION |
1876 : CALL_AS_METHOD; | 2108 : CALL_AS_METHOD; |
1877 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, | 2109 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, |
1878 NullCallWrapper(), call_kind); | 2110 NullCallWrapper(), call_kind); |
1879 | 2111 |
1880 __ bind(&miss); | 2112 __ bind(&miss); |
1881 // rcx: function name. | 2113 // rcx: function name. |
1882 MaybeObject* maybe_result = GenerateMissBranch(); | 2114 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1883 if (maybe_result->IsFailure()) return maybe_result; | 2115 if (maybe_result->IsFailure()) return maybe_result; |
1884 | 2116 |
1885 // Return the generated code. | 2117 // Return the generated code. |
1886 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2118 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); |
1887 } | 2119 } |
1888 | 2120 |
1889 | 2121 |
1890 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, | 2122 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, |
1891 JSObject* holder, | 2123 JSObject* holder, |
1892 JSGlobalPropertyCell* cell, | 2124 JSGlobalPropertyCell* cell, |
1893 JSFunction* function, | 2125 JSFunction* function, |
1894 String* name) { | 2126 String* name) { |
1895 // TODO(872): implement this. | 2127 // TODO(872): implement this. |
1896 return heap()->undefined_value(); | 2128 return heap()->undefined_value(); |
(...skipping 13 matching lines...) Expand all Loading... | |
1910 // -- rsp[(argc + 1) * 8] : receiver | 2142 // -- rsp[(argc + 1) * 8] : receiver |
1911 // ----------------------------------- | 2143 // ----------------------------------- |
1912 | 2144 |
1913 const int argc = arguments().immediate(); | 2145 const int argc = arguments().immediate(); |
1914 | 2146 |
1915 // If the object is not a JSObject or we got an unexpected number of | 2147 // If the object is not a JSObject or we got an unexpected number of |
1916 // arguments, bail out to the regular call. | 2148 // arguments, bail out to the regular call. |
1917 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 2149 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); |
1918 | 2150 |
1919 Label miss; | 2151 Label miss; |
1920 GenerateNameCheck(name, &miss); | 2152 GenerateNameCheck(Handle<String>(name), &miss); |
1921 | 2153 |
1922 if (cell == NULL) { | 2154 if (cell == NULL) { |
1923 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); | 2155 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); |
1924 | 2156 |
1925 __ JumpIfSmi(rdx, &miss); | 2157 __ JumpIfSmi(rdx, &miss); |
1926 | 2158 |
1927 CheckPrototypes(JSObject::cast(object), rdx, holder, rbx, rax, rdi, name, | 2159 CheckPrototypes(JSObject::cast(object), rdx, holder, rbx, rax, rdi, name, |
1928 &miss); | 2160 &miss); |
1929 } else { | 2161 } else { |
1930 ASSERT(cell->value() == function); | 2162 ASSERT(cell->value() == function); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1989 // because the function makes no use of it. | 2221 // because the function makes no use of it. |
1990 __ bind(&slow); | 2222 __ bind(&slow); |
1991 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2223 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
1992 ? CALL_AS_FUNCTION | 2224 ? CALL_AS_FUNCTION |
1993 : CALL_AS_METHOD; | 2225 : CALL_AS_METHOD; |
1994 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, | 2226 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, |
1995 NullCallWrapper(), call_kind); | 2227 NullCallWrapper(), call_kind); |
1996 | 2228 |
1997 __ bind(&miss); | 2229 __ bind(&miss); |
1998 // rcx: function name. | 2230 // rcx: function name. |
1999 MaybeObject* maybe_result = GenerateMissBranch(); | 2231 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2000 if (maybe_result->IsFailure()) return maybe_result; | 2232 if (maybe_result->IsFailure()) return maybe_result; |
2001 | 2233 |
2002 // Return the generated code. | 2234 // Return the generated code. |
2003 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2235 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); |
2004 } | 2236 } |
2005 | 2237 |
2006 | 2238 |
2007 MaybeObject* CallStubCompiler::CompileFastApiCall( | 2239 MaybeObject* CallStubCompiler::CompileFastApiCall( |
2008 const CallOptimization& optimization, | 2240 const CallOptimization& optimization, |
2009 Object* object, | 2241 Object* object, |
2010 JSObject* holder, | 2242 JSObject* holder, |
2011 JSGlobalPropertyCell* cell, | 2243 JSGlobalPropertyCell* cell, |
2012 JSFunction* function, | 2244 JSFunction* function, |
2013 String* name) { | 2245 String* name) { |
2014 ASSERT(optimization.is_simple_api_call()); | 2246 ASSERT(optimization.is_simple_api_call()); |
2015 // Bail out if object is a global object as we don't want to | 2247 // Bail out if object is a global object as we don't want to |
2016 // repatch it to global receiver. | 2248 // repatch it to global receiver. |
2017 if (object->IsGlobalObject()) return heap()->undefined_value(); | 2249 if (object->IsGlobalObject()) return heap()->undefined_value(); |
2018 if (cell != NULL) return heap()->undefined_value(); | 2250 if (cell != NULL) return heap()->undefined_value(); |
2019 if (!object->IsJSObject()) return heap()->undefined_value(); | 2251 if (!object->IsJSObject()) return heap()->undefined_value(); |
2020 int depth = optimization.GetPrototypeDepthOfExpectedType( | 2252 int depth = optimization.GetPrototypeDepthOfExpectedType( |
2021 JSObject::cast(object), holder); | 2253 JSObject::cast(object), holder); |
2022 if (depth == kInvalidProtoDepth) return heap()->undefined_value(); | 2254 if (depth == kInvalidProtoDepth) return heap()->undefined_value(); |
2023 | 2255 |
2024 Label miss, miss_before_stack_reserved; | 2256 Label miss, miss_before_stack_reserved; |
2025 | 2257 |
2026 GenerateNameCheck(name, &miss_before_stack_reserved); | 2258 GenerateNameCheck(Handle<String>(name), &miss_before_stack_reserved); |
2027 | 2259 |
2028 // Get the receiver from the stack. | 2260 // Get the receiver from the stack. |
2029 const int argc = arguments().immediate(); | 2261 const int argc = arguments().immediate(); |
2030 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 2262 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
2031 | 2263 |
2032 // Check that the receiver isn't a smi. | 2264 // Check that the receiver isn't a smi. |
2033 __ JumpIfSmi(rdx, &miss_before_stack_reserved); | 2265 __ JumpIfSmi(rdx, &miss_before_stack_reserved); |
2034 | 2266 |
2035 Counters* counters = isolate()->counters(); | 2267 Counters* counters = isolate()->counters(); |
2036 __ IncrementCounter(counters->call_const(), 1); | 2268 __ IncrementCounter(counters->call_const(), 1); |
(...skipping 11 matching lines...) Expand all Loading... | |
2048 __ movq(rax, Operand(rsp, 3 * kPointerSize)); | 2280 __ movq(rax, Operand(rsp, 3 * kPointerSize)); |
2049 __ movq(Operand(rsp, 0 * kPointerSize), rax); | 2281 __ movq(Operand(rsp, 0 * kPointerSize), rax); |
2050 | 2282 |
2051 MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc); | 2283 MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc); |
2052 if (result->IsFailure()) return result; | 2284 if (result->IsFailure()) return result; |
2053 | 2285 |
2054 __ bind(&miss); | 2286 __ bind(&miss); |
2055 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); | 2287 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); |
2056 | 2288 |
2057 __ bind(&miss_before_stack_reserved); | 2289 __ bind(&miss_before_stack_reserved); |
2058 MaybeObject* maybe_result = GenerateMissBranch(); | 2290 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2059 if (maybe_result->IsFailure()) return maybe_result; | 2291 if (maybe_result->IsFailure()) return maybe_result; |
2060 | 2292 |
2061 // Return the generated code. | 2293 // Return the generated code. |
2062 return GetCode(function); | 2294 return TryGetCode(function); |
2063 } | 2295 } |
2064 | 2296 |
2065 | 2297 |
2066 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, | 2298 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, |
2067 JSObject* holder, | 2299 JSObject* holder, |
2068 JSFunction* function, | 2300 JSFunction* function, |
2069 String* name, | 2301 String* name, |
2070 CheckType check) { | 2302 CheckType check) { |
2071 // ----------- S t a t e ------------- | 2303 // ----------- S t a t e ------------- |
2072 // rcx : function name | 2304 // rcx : function name |
2073 // rsp[0] : return address | 2305 // rsp[0] : return address |
2074 // rsp[8] : argument argc | 2306 // rsp[8] : argument argc |
2075 // rsp[16] : argument argc - 1 | 2307 // rsp[16] : argument argc - 1 |
2076 // ... | 2308 // ... |
2077 // rsp[argc * 8] : argument 1 | 2309 // rsp[argc * 8] : argument 1 |
2078 // rsp[(argc + 1) * 8] : argument 0 = receiver | 2310 // rsp[(argc + 1) * 8] : argument 0 = receiver |
2079 // ----------------------------------- | 2311 // ----------------------------------- |
2080 | 2312 |
2081 if (HasCustomCallGenerator(function)) { | 2313 if (HasCustomCallGenerator(function)) { |
2082 MaybeObject* maybe_result = CompileCustomCall( | 2314 MaybeObject* maybe_result = CompileCustomCall( |
2083 object, holder, NULL, function, name); | 2315 object, holder, NULL, function, name); |
2084 Object* result; | 2316 Object* result; |
2085 if (!maybe_result->ToObject(&result)) return maybe_result; | 2317 if (!maybe_result->ToObject(&result)) return maybe_result; |
2086 // undefined means bail out to regular compiler. | 2318 // undefined means bail out to regular compiler. |
2087 if (!result->IsUndefined()) return result; | 2319 if (!result->IsUndefined()) return result; |
2088 } | 2320 } |
2089 | 2321 |
2090 Label miss; | 2322 Label miss; |
2091 | 2323 |
2092 GenerateNameCheck(name, &miss); | 2324 GenerateNameCheck(Handle<String>(name), &miss); |
2093 | 2325 |
2094 // Get the receiver from the stack. | 2326 // Get the receiver from the stack. |
2095 const int argc = arguments().immediate(); | 2327 const int argc = arguments().immediate(); |
2096 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 2328 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
2097 | 2329 |
2098 // Check that the receiver isn't a smi. | 2330 // Check that the receiver isn't a smi. |
2099 if (check != NUMBER_CHECK) { | 2331 if (check != NUMBER_CHECK) { |
2100 __ JumpIfSmi(rdx, &miss); | 2332 __ JumpIfSmi(rdx, &miss); |
2101 } | 2333 } |
2102 | 2334 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2187 } | 2419 } |
2188 | 2420 |
2189 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2421 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
2190 ? CALL_AS_FUNCTION | 2422 ? CALL_AS_FUNCTION |
2191 : CALL_AS_METHOD; | 2423 : CALL_AS_METHOD; |
2192 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, | 2424 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, |
2193 NullCallWrapper(), call_kind); | 2425 NullCallWrapper(), call_kind); |
2194 | 2426 |
2195 // Handle call cache miss. | 2427 // Handle call cache miss. |
2196 __ bind(&miss); | 2428 __ bind(&miss); |
2197 MaybeObject* maybe_result = GenerateMissBranch(); | 2429 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2198 if (maybe_result->IsFailure()) return maybe_result; | 2430 if (maybe_result->IsFailure()) return maybe_result; |
2199 | 2431 |
2200 // Return the generated code. | 2432 // Return the generated code. |
2201 return GetCode(function); | 2433 return TryGetCode(function); |
2202 } | 2434 } |
2203 | 2435 |
2204 | 2436 |
2205 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, | 2437 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, |
2206 JSObject* holder, | 2438 JSObject* holder, |
2207 String* name) { | 2439 String* name) { |
2208 // ----------- S t a t e ------------- | 2440 // ----------- S t a t e ------------- |
2209 // rcx : function name | 2441 // rcx : function name |
2210 // rsp[0] : return address | 2442 // rsp[0] : return address |
2211 // rsp[8] : argument argc | 2443 // rsp[8] : argument argc |
2212 // rsp[16] : argument argc - 1 | 2444 // rsp[16] : argument argc - 1 |
2213 // ... | 2445 // ... |
2214 // rsp[argc * 8] : argument 1 | 2446 // rsp[argc * 8] : argument 1 |
2215 // rsp[(argc + 1) * 8] : argument 0 = receiver | 2447 // rsp[(argc + 1) * 8] : argument 0 = receiver |
2216 // ----------------------------------- | 2448 // ----------------------------------- |
2217 Label miss; | 2449 Label miss; |
2218 | 2450 |
2219 GenerateNameCheck(name, &miss); | 2451 GenerateNameCheck(Handle<String>(name), &miss); |
2220 | 2452 |
2221 // Get the number of arguments. | 2453 // Get the number of arguments. |
2222 const int argc = arguments().immediate(); | 2454 const int argc = arguments().immediate(); |
2223 | 2455 |
2224 LookupResult lookup(isolate()); | 2456 LookupResult lookup(isolate()); |
2225 LookupPostInterceptor(holder, name, &lookup); | 2457 LookupPostInterceptor(holder, name, &lookup); |
2226 | 2458 |
2227 // Get the receiver from the stack. | 2459 // Get the receiver from the stack. |
2228 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 2460 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
2229 | 2461 |
(...skipping 28 matching lines...) Expand all Loading... | |
2258 // Invoke the function. | 2490 // Invoke the function. |
2259 __ movq(rdi, rax); | 2491 __ movq(rdi, rax); |
2260 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2492 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
2261 ? CALL_AS_FUNCTION | 2493 ? CALL_AS_FUNCTION |
2262 : CALL_AS_METHOD; | 2494 : CALL_AS_METHOD; |
2263 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, | 2495 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, |
2264 NullCallWrapper(), call_kind); | 2496 NullCallWrapper(), call_kind); |
2265 | 2497 |
2266 // Handle load cache miss. | 2498 // Handle load cache miss. |
2267 __ bind(&miss); | 2499 __ bind(&miss); |
2268 MaybeObject* maybe_result = GenerateMissBranch(); | 2500 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2269 if (maybe_result->IsFailure()) return maybe_result; | 2501 if (maybe_result->IsFailure()) return maybe_result; |
2270 | 2502 |
2271 // Return the generated code. | 2503 // Return the generated code. |
2272 return GetCode(INTERCEPTOR, name); | 2504 return TryGetCode(INTERCEPTOR, name); |
2273 } | 2505 } |
2274 | 2506 |
2275 | 2507 |
2276 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, | 2508 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, |
2277 GlobalObject* holder, | 2509 GlobalObject* holder, |
2278 JSGlobalPropertyCell* cell, | 2510 JSGlobalPropertyCell* cell, |
2279 JSFunction* function, | 2511 JSFunction* function, |
2280 String* name) { | 2512 String* name) { |
2281 // ----------- S t a t e ------------- | 2513 // ----------- S t a t e ------------- |
2282 // rcx : function name | 2514 // rcx : function name |
2283 // rsp[0] : return address | 2515 // rsp[0] : return address |
2284 // rsp[8] : argument argc | 2516 // rsp[8] : argument argc |
2285 // rsp[16] : argument argc - 1 | 2517 // rsp[16] : argument argc - 1 |
2286 // ... | 2518 // ... |
2287 // rsp[argc * 8] : argument 1 | 2519 // rsp[argc * 8] : argument 1 |
2288 // rsp[(argc + 1) * 8] : argument 0 = receiver | 2520 // rsp[(argc + 1) * 8] : argument 0 = receiver |
2289 // ----------------------------------- | 2521 // ----------------------------------- |
2290 | 2522 |
2291 if (HasCustomCallGenerator(function)) { | 2523 if (HasCustomCallGenerator(function)) { |
2292 MaybeObject* maybe_result = CompileCustomCall( | 2524 MaybeObject* maybe_result = CompileCustomCall( |
2293 object, holder, cell, function, name); | 2525 object, holder, cell, function, name); |
2294 Object* result; | 2526 Object* result; |
2295 if (!maybe_result->ToObject(&result)) return maybe_result; | 2527 if (!maybe_result->ToObject(&result)) return maybe_result; |
2296 // undefined means bail out to regular compiler. | 2528 // undefined means bail out to regular compiler. |
2297 if (!result->IsUndefined()) return result; | 2529 if (!result->IsUndefined()) return result; |
2298 } | 2530 } |
2299 | 2531 |
2300 Label miss; | 2532 Label miss; |
2301 | 2533 |
2302 GenerateNameCheck(name, &miss); | 2534 GenerateNameCheck(Handle<String>(name), &miss); |
2303 | 2535 |
2304 // Get the number of arguments. | 2536 // Get the number of arguments. |
2305 const int argc = arguments().immediate(); | 2537 const int argc = arguments().immediate(); |
2306 | 2538 |
2307 GenerateGlobalReceiverCheck(object, holder, name, &miss); | 2539 GenerateGlobalReceiverCheck(object, holder, name, &miss); |
2308 | 2540 |
2309 GenerateLoadFunctionFromCell(cell, function, &miss); | 2541 GenerateLoadFunctionFromCell(cell, function, &miss); |
2310 | 2542 |
2311 // Patch the receiver on the stack with the global proxy. | 2543 // Patch the receiver on the stack with the global proxy. |
2312 if (object->IsGlobalObject()) { | 2544 if (object->IsGlobalObject()) { |
(...skipping 14 matching lines...) Expand all Loading... | |
2327 // We call indirectly through the code field in the function to | 2559 // We call indirectly through the code field in the function to |
2328 // allow recompilation to take effect without changing any of the | 2560 // allow recompilation to take effect without changing any of the |
2329 // call sites. | 2561 // call sites. |
2330 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); | 2562 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
2331 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION, | 2563 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION, |
2332 NullCallWrapper(), call_kind); | 2564 NullCallWrapper(), call_kind); |
2333 | 2565 |
2334 // Handle call cache miss. | 2566 // Handle call cache miss. |
2335 __ bind(&miss); | 2567 __ bind(&miss); |
2336 __ IncrementCounter(counters->call_global_inline_miss(), 1); | 2568 __ IncrementCounter(counters->call_global_inline_miss(), 1); |
2337 MaybeObject* maybe_result = GenerateMissBranch(); | 2569 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2338 if (maybe_result->IsFailure()) return maybe_result; | 2570 if (maybe_result->IsFailure()) return maybe_result; |
2339 | 2571 |
2340 // Return the generated code. | 2572 // Return the generated code. |
2341 return GetCode(NORMAL, name); | 2573 return TryGetCode(NORMAL, name); |
2342 } | 2574 } |
2343 | 2575 |
2344 | 2576 |
2345 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, | 2577 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, |
2346 int index, | 2578 int index, |
2347 Map* transition, | 2579 Map* transition, |
2348 String* name) { | 2580 String* name) { |
2349 // ----------- S t a t e ------------- | 2581 // ----------- S t a t e ------------- |
2350 // -- rax : value | 2582 // -- rax : value |
2351 // -- rcx : name | 2583 // -- rcx : name |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2651 __ JumpIfSmi(rax, &miss); | 2883 __ JumpIfSmi(rax, &miss); |
2652 | 2884 |
2653 // Check the maps of the full prototype chain. Also check that | 2885 // Check the maps of the full prototype chain. Also check that |
2654 // global property cells up to (but not including) the last object | 2886 // global property cells up to (but not including) the last object |
2655 // in the prototype chain are empty. | 2887 // in the prototype chain are empty. |
2656 CheckPrototypes(object, rax, last, rbx, rdx, rdi, name, &miss); | 2888 CheckPrototypes(object, rax, last, rbx, rdx, rdi, name, &miss); |
2657 | 2889 |
2658 // If the last object in the prototype chain is a global object, | 2890 // If the last object in the prototype chain is a global object, |
2659 // check that the global property cell is empty. | 2891 // check that the global property cell is empty. |
2660 if (last->IsGlobalObject()) { | 2892 if (last->IsGlobalObject()) { |
2661 MaybeObject* cell = GenerateCheckPropertyCell(masm(), | 2893 MaybeObject* cell = TryGenerateCheckPropertyCell(masm(), |
2662 GlobalObject::cast(last), | 2894 GlobalObject::cast(last), |
2663 name, | 2895 name, |
2664 rdx, | 2896 rdx, |
2665 &miss); | 2897 &miss); |
2666 if (cell->IsFailure()) { | 2898 if (cell->IsFailure()) { |
2667 miss.Unuse(); | 2899 miss.Unuse(); |
2668 return cell; | 2900 return cell; |
2669 } | 2901 } |
2670 } | 2902 } |
2671 | 2903 |
2672 // Return undefined if maps of the full prototype chain are still the | 2904 // Return undefined if maps of the full prototype chain are still the |
2673 // same and no global property with this name contains a value. | 2905 // same and no global property with this name contains a value. |
2674 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); | 2906 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); |
2675 __ ret(0); | 2907 __ ret(0); |
(...skipping 1121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3797 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 4029 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
3798 __ jmp(ic_miss, RelocInfo::CODE_TARGET); | 4030 __ jmp(ic_miss, RelocInfo::CODE_TARGET); |
3799 } | 4031 } |
3800 | 4032 |
3801 | 4033 |
3802 #undef __ | 4034 #undef __ |
3803 | 4035 |
3804 } } // namespace v8::internal | 4036 } } // namespace v8::internal |
3805 | 4037 |
3806 #endif // V8_TARGET_ARCH_X64 | 4038 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |