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

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

Issue 8332003: Handlify CallStubCompiler::CompileCallField. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rename some functions on ARM. 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
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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 __ pop(offset); 100 __ pop(offset);
101 } 101 }
102 } 102 }
103 103
104 104
105 // Helper function used to check that the dictionary doesn't contain 105 // Helper function used to check that the dictionary doesn't contain
106 // the property. This function may return false negatives, so miss_label 106 // the property. This function may return false negatives, so miss_label
107 // must always call a backup property check that is complete. 107 // must always call a backup property check that is complete.
108 // This function is safe to call if the receiver has fast properties. 108 // This function is safe to call if the receiver has fast properties.
109 // Name must be a symbol and receiver must be a heap object. 109 // Name must be a symbol and receiver must be a heap object.
110 static MaybeObject* GenerateDictionaryNegativeLookup(MacroAssembler* masm, 110 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
111 Label* miss_label, 111 Label* miss_label,
112 Register receiver, 112 Register receiver,
113 String* name, 113 Handle<String> name,
114 Register r0, 114 Register r0,
115 Register r1) { 115 Register r1) {
116 ASSERT(name->IsSymbol()); 116 ASSERT(name->IsSymbol());
117 Counters* counters = masm->isolate()->counters(); 117 Counters* counters = masm->isolate()->counters();
118 __ IncrementCounter(counters->negative_lookups(), 1); 118 __ IncrementCounter(counters->negative_lookups(), 1);
119 __ IncrementCounter(counters->negative_lookups_miss(), 1);
120
121 __ mov(r0, FieldOperand(receiver, HeapObject::kMapOffset));
122
123 const int kInterceptorOrAccessCheckNeededMask =
124 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
125
126 // Bail out if the receiver has a named interceptor or requires access checks.
127 __ test_b(FieldOperand(r0, Map::kBitFieldOffset),
128 kInterceptorOrAccessCheckNeededMask);
129 __ j(not_zero, miss_label);
130
131 // Check that receiver is a JSObject.
132 __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE);
133 __ j(below, miss_label);
134
135 // Load properties array.
136 Register properties = r0;
137 __ mov(properties, FieldOperand(receiver, JSObject::kPropertiesOffset));
138
139 // Check that the properties array is a dictionary.
140 __ cmp(FieldOperand(properties, HeapObject::kMapOffset),
141 Immediate(masm->isolate()->factory()->hash_table_map()));
142 __ j(not_equal, miss_label);
143
144 Label done;
145 StringDictionaryLookupStub::GenerateNegativeLookup(masm,
146 miss_label,
147 &done,
148 properties,
149 name,
150 r1);
151 __ bind(&done);
152 __ DecrementCounter(counters->negative_lookups_miss(), 1);
153 }
154
155
156 // TODO(kmillikin): Eliminate this function when the stub cache is fully
157 // handlified.
158 static MaybeObject* TryGenerateDictionaryNegativeLookup(MacroAssembler* masm,
159 Label* miss_label,
160 Register receiver,
161 String* name,
162 Register r0,
163 Register r1) {
164 ASSERT(name->IsSymbol());
165 Counters* counters = masm->isolate()->counters();
166 __ IncrementCounter(counters->negative_lookups(), 1);
119 __ IncrementCounter(counters->negative_lookups_miss(), 1); 167 __ IncrementCounter(counters->negative_lookups_miss(), 1);
120 168
121 __ mov(r0, FieldOperand(receiver, HeapObject::kMapOffset)); 169 __ mov(r0, FieldOperand(receiver, HeapObject::kMapOffset));
122 170
123 const int kInterceptorOrAccessCheckNeededMask = 171 const int kInterceptorOrAccessCheckNeededMask =
124 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); 172 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
125 173
126 // Bail out if the receiver has a named interceptor or requires access checks. 174 // Bail out if the receiver has a named interceptor or requires access checks.
127 __ test_b(FieldOperand(r0, Map::kBitFieldOffset), 175 __ test_b(FieldOperand(r0, Map::kBitFieldOffset),
128 kInterceptorOrAccessCheckNeededMask); 176 kInterceptorOrAccessCheckNeededMask);
129 __ j(not_zero, miss_label); 177 __ j(not_zero, miss_label);
130 178
131 // Check that receiver is a JSObject. 179 // Check that receiver is a JSObject.
132 __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE); 180 __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE);
133 __ j(below, miss_label); 181 __ j(below, miss_label);
134 182
135 // Load properties array. 183 // Load properties array.
136 Register properties = r0; 184 Register properties = r0;
137 __ mov(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); 185 __ mov(properties, FieldOperand(receiver, JSObject::kPropertiesOffset));
138 186
139 // Check that the properties array is a dictionary. 187 // Check that the properties array is a dictionary.
140 __ cmp(FieldOperand(properties, HeapObject::kMapOffset), 188 __ cmp(FieldOperand(properties, HeapObject::kMapOffset),
141 Immediate(masm->isolate()->factory()->hash_table_map())); 189 Immediate(masm->isolate()->factory()->hash_table_map()));
142 __ j(not_equal, miss_label); 190 __ j(not_equal, miss_label);
143 191
144 Label done; 192 Label done;
145 MaybeObject* result = 193 MaybeObject* result =
146 StringDictionaryLookupStub::GenerateNegativeLookup(masm, 194 StringDictionaryLookupStub::TryGenerateNegativeLookup(masm,
147 miss_label, 195 miss_label,
148 &done, 196 &done,
149 properties, 197 properties,
150 name, 198 name,
151 r1); 199 r1);
152 if (result->IsFailure()) return result; 200 if (result->IsFailure()) return result;
153 201
154 __ bind(&done); 202 __ bind(&done);
155 __ DecrementCounter(counters->negative_lookups_miss(), 1); 203 __ DecrementCounter(counters->negative_lookups_miss(), 1);
156 204
157 return result; 205 return result;
158 } 206 }
159 207
160 208
161 void StubCache::GenerateProbe(MacroAssembler* masm, 209 void StubCache::GenerateProbe(MacroAssembler* masm,
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); 366 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
319 __ mov(eax, scratch1); 367 __ mov(eax, scratch1);
320 __ ret(0); 368 __ ret(0);
321 } 369 }
322 370
323 371
324 // Load a fast property out of a holder object (src). In-object properties 372 // Load a fast property out of a holder object (src). In-object properties
325 // are loaded directly otherwise the property is loaded from the properties 373 // are loaded directly otherwise the property is loaded from the properties
326 // fixed array. 374 // fixed array.
327 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, 375 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
328 Register dst, Register src, 376 Register dst,
329 JSObject* holder, int index) { 377 Register src,
378 Handle<JSObject> holder,
379 int index) {
330 // Adjust for the number of properties stored in the holder. 380 // Adjust for the number of properties stored in the holder.
331 index -= holder->map()->inobject_properties(); 381 index -= holder->map()->inobject_properties();
332 if (index < 0) { 382 if (index < 0) {
333 // Get the property straight out of the holder. 383 // Get the property straight out of the holder.
334 int offset = holder->map()->instance_size() + (index * kPointerSize); 384 int offset = holder->map()->instance_size() + (index * kPointerSize);
335 __ mov(dst, FieldOperand(src, offset)); 385 __ mov(dst, FieldOperand(src, offset));
336 } else { 386 } else {
337 // Calculate the offset into the properties array. 387 // Calculate the offset into the properties array.
338 int offset = index * kPointerSize + FixedArray::kHeaderSize; 388 int offset = index * kPointerSize + FixedArray::kHeaderSize;
339 __ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset)); 389 __ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset));
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 } 861 }
812 862
813 // Return the value (register eax). 863 // Return the value (register eax).
814 __ ret(0); 864 __ ret(0);
815 } 865 }
816 866
817 867
818 // Generate code to check that a global property cell is empty. Create 868 // Generate code to check that a global property cell is empty. Create
819 // the property cell at compilation time if no cell exists for the 869 // the property cell at compilation time if no cell exists for the
820 // property. 870 // property.
821 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCell( 871 static void GenerateCheckPropertyCell(MacroAssembler* masm,
872 Handle<GlobalObject> global,
873 Handle<String> name,
874 Register scratch,
875 Label* miss) {
876 Handle<JSGlobalPropertyCell> cell =
877 GlobalObject::EnsurePropertyCell(global, name);
878 ASSERT(cell->value()->IsTheHole());
879 Handle<Oddball> the_hole = masm->isolate()->factory()->the_hole_value();
880 if (Serializer::enabled()) {
881 __ mov(scratch, Immediate(cell));
882 __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset),
883 Immediate(the_hole));
884 } else {
885 __ cmp(Operand::Cell(cell), Immediate(the_hole));
886 }
887 __ j(not_equal, miss);
888 }
889
890
891 // TODO(kmillikin): Eliminate this function when the stub cache is fully
892 // handlified.
893 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCell(
822 MacroAssembler* masm, 894 MacroAssembler* masm,
823 GlobalObject* global, 895 GlobalObject* global,
824 String* name, 896 String* name,
825 Register scratch, 897 Register scratch,
826 Label* miss) { 898 Label* miss) {
827 Object* probe; 899 Object* probe;
828 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); 900 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name);
829 if (!maybe_probe->ToObject(&probe)) return maybe_probe; 901 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
830 } 902 }
831 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); 903 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe);
832 ASSERT(cell->value()->IsTheHole()); 904 ASSERT(cell->value()->IsTheHole());
833 if (Serializer::enabled()) { 905 if (Serializer::enabled()) {
834 __ mov(scratch, Immediate(Handle<Object>(cell))); 906 __ mov(scratch, Immediate(Handle<Object>(cell)));
835 __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), 907 __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset),
836 Immediate(masm->isolate()->factory()->the_hole_value())); 908 Immediate(masm->isolate()->factory()->the_hole_value()));
837 } else { 909 } else {
838 __ cmp(Operand::Cell(Handle<JSGlobalPropertyCell>(cell)), 910 __ cmp(Operand::Cell(Handle<JSGlobalPropertyCell>(cell)),
839 Immediate(masm->isolate()->factory()->the_hole_value())); 911 Immediate(masm->isolate()->factory()->the_hole_value()));
840 } 912 }
841 __ j(not_equal, miss); 913 __ j(not_equal, miss);
842 return cell; 914 return cell;
843 } 915 }
844 916
845 917
846 // Calls GenerateCheckPropertyCell for each global object in the prototype chain 918 // Calls GenerateCheckPropertyCell for each global object in the prototype chain
847 // from object to (but not including) holder. 919 // from object to (but not including) holder.
848 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCells( 920 static void GenerateCheckPropertyCells(MacroAssembler* masm,
921 Handle<JSObject> object,
922 Handle<JSObject> holder,
923 Handle<String> name,
924 Register scratch,
925 Label* miss) {
926 Handle<JSObject> current = object;
927 while (!current.is_identical_to(holder)) {
928 if (current->IsGlobalObject()) {
929 GenerateCheckPropertyCell(masm,
930 Handle<GlobalObject>::cast(current),
931 name,
932 scratch,
933 miss);
934 }
935 current = Handle<JSObject>(JSObject::cast(current->GetPrototype()));
936 }
937 }
938
939
940 // TODO(kmillikin): Eliminate this function when the stub cache is fully
941 // handlified.
942 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCells(
849 MacroAssembler* masm, 943 MacroAssembler* masm,
850 JSObject* object, 944 JSObject* object,
851 JSObject* holder, 945 JSObject* holder,
852 String* name, 946 String* name,
853 Register scratch, 947 Register scratch,
854 Label* miss) { 948 Label* miss) {
855 JSObject* current = object; 949 JSObject* current = object;
856 while (current != holder) { 950 while (current != holder) {
857 if (current->IsGlobalObject()) { 951 if (current->IsGlobalObject()) {
858 // Returns a cell or a failure. 952 // Returns a cell or a failure.
859 MaybeObject* result = GenerateCheckPropertyCell( 953 MaybeObject* result = TryGenerateCheckPropertyCell(
860 masm, 954 masm,
861 GlobalObject::cast(current), 955 GlobalObject::cast(current),
862 name, 956 name,
863 scratch, 957 scratch,
864 miss); 958 miss);
865 if (result->IsFailure()) return result; 959 if (result->IsFailure()) return result;
866 } 960 }
867 ASSERT(current->IsJSObject()); 961 ASSERT(current->IsJSObject());
868 current = JSObject::cast(current->GetPrototype()); 962 current = JSObject::cast(current->GetPrototype());
869 } 963 }
870 return NULL; 964 return NULL;
871 } 965 }
872 966
873 967
874 #undef __ 968 #undef __
875 #define __ ACCESS_MASM(masm()) 969 #define __ ACCESS_MASM(masm())
876 970
877 971
972 Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
973 Register object_reg,
974 Handle<JSObject> holder,
975 Register holder_reg,
976 Register scratch1,
977 Register scratch2,
978 Handle<String> name,
979 int save_at_depth,
980 Label* miss) {
981 // Make sure there's no overlap between holder and object registers.
982 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
983 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
984 && !scratch2.is(scratch1));
985
986 // Keep track of the current object in register reg.
987 Register reg = object_reg;
988 Handle<JSObject> current = object;
989 int depth = 0;
990
991 if (save_at_depth == depth) {
992 __ mov(Operand(esp, kPointerSize), reg);
993 }
994
995 // Traverse the prototype chain and check the maps in the prototype chain for
996 // fast and global objects or do negative lookup for normal objects.
997 while (!current.is_identical_to(holder)) {
998 ++depth;
999
1000 // Only global objects and objects that do not require access
1001 // checks are allowed in stubs.
1002 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded());
1003
1004 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype()));
1005 if (!current->HasFastProperties() &&
1006 !current->IsJSGlobalObject() &&
1007 !current->IsJSGlobalProxy()) {
1008 if (!name->IsSymbol()) {
1009 name = factory()->LookupSymbol(name);
1010 }
1011 ASSERT(current->property_dictionary()->FindEntry(*name) ==
1012 StringDictionary::kNotFound);
1013
1014 GenerateDictionaryNegativeLookup(masm(), miss, reg, name,
1015 scratch1, scratch2);
1016
1017 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
1018 reg = holder_reg; // From now on the object will be in holder_reg.
1019 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
1020 } else {
1021 bool in_new_space = heap()->InNewSpace(*prototype);
1022 Handle<Map> current_map(current->map());
1023 if (in_new_space) {
1024 // Save the map in scratch1 for later.
1025 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
1026 __ cmp(scratch1, Immediate(current_map));
1027 } else {
1028 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
1029 Immediate(current_map));
1030 }
1031 // Branch on the result of the map check.
1032 __ j(not_equal, miss);
1033 // Check access rights to the global object. This has to happen after
1034 // the map check so that we know that the object is actually a global
1035 // object.
1036 if (current->IsJSGlobalProxy()) {
1037 __ CheckAccessGlobalProxy(reg, scratch2, miss);
1038 }
1039 reg = holder_reg; // From now on the object will be in holder_reg.
1040
1041 if (in_new_space) {
1042 // The prototype is in new space; we cannot store a reference to it
1043 // in the code. Load it from the map.
1044 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
1045 } else {
1046 // The prototype is in old space; load it directly.
1047 __ mov(reg, prototype);
1048 }
1049 }
1050
1051 if (save_at_depth == depth) {
1052 __ mov(Operand(esp, kPointerSize), reg);
1053 }
1054
1055 // Go to the next object in the prototype chain.
1056 current = prototype;
1057 }
1058 ASSERT(current.is_identical_to(holder));
1059
1060 // Log the check depth.
1061 LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
1062
1063 // Check the holder map.
1064 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
1065 Immediate(Handle<Map>(holder->map())));
1066 __ j(not_equal, miss);
1067
1068 // Perform security check for access to the global object.
1069 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
1070 if (holder->IsJSGlobalProxy()) {
1071 __ CheckAccessGlobalProxy(reg, scratch1, miss);
1072 }
1073
1074 // If we've skipped any global objects, it's not enough to verify that
1075 // their maps haven't changed. We also need to check that the property
1076 // cell for the property is still empty.
1077 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss);
1078
1079 // Return the register containing the holder.
1080 return reg;
1081 }
1082
1083
1084 // TODO(kmillikin): Eliminate this function when the stub cache is fully
1085 // handlified.
878 Register StubCompiler::CheckPrototypes(JSObject* object, 1086 Register StubCompiler::CheckPrototypes(JSObject* object,
879 Register object_reg, 1087 Register object_reg,
880 JSObject* holder, 1088 JSObject* holder,
881 Register holder_reg, 1089 Register holder_reg,
882 Register scratch1, 1090 Register scratch1,
883 Register scratch2, 1091 Register scratch2,
884 String* name, 1092 String* name,
885 int save_at_depth, 1093 int save_at_depth,
886 Label* miss) { 1094 Label* miss) {
887 // Make sure there's no overlap between holder and object registers. 1095 // Make sure there's no overlap between holder and object registers.
(...skipping 29 matching lines...) Expand all
917 Object* lookup_result = NULL; // Initialization to please compiler. 1125 Object* lookup_result = NULL; // Initialization to please compiler.
918 if (!maybe_lookup_result->ToObject(&lookup_result)) { 1126 if (!maybe_lookup_result->ToObject(&lookup_result)) {
919 set_failure(Failure::cast(maybe_lookup_result)); 1127 set_failure(Failure::cast(maybe_lookup_result));
920 return reg; 1128 return reg;
921 } 1129 }
922 name = String::cast(lookup_result); 1130 name = String::cast(lookup_result);
923 } 1131 }
924 ASSERT(current->property_dictionary()->FindEntry(name) == 1132 ASSERT(current->property_dictionary()->FindEntry(name) ==
925 StringDictionary::kNotFound); 1133 StringDictionary::kNotFound);
926 1134
927 MaybeObject* negative_lookup = GenerateDictionaryNegativeLookup(masm(), 1135 MaybeObject* negative_lookup =
928 miss, 1136 TryGenerateDictionaryNegativeLookup(masm(), miss, reg, name,
929 reg, 1137 scratch1, scratch2);
930 name,
931 scratch1,
932 scratch2);
933 if (negative_lookup->IsFailure()) { 1138 if (negative_lookup->IsFailure()) {
934 set_failure(Failure::cast(negative_lookup)); 1139 set_failure(Failure::cast(negative_lookup));
935 return reg; 1140 return reg;
936 } 1141 }
937 1142
938 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 1143 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
939 reg = holder_reg; // from now the object is in holder_reg 1144 reg = holder_reg; // from now the object is in holder_reg
940 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 1145 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
941 } else if (heap()->InNewSpace(prototype)) { 1146 } else if (heap()->InNewSpace(prototype)) {
942 // Get the map of the current object. 1147 // Get the map of the current object.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 1194
990 // Check the holder map. 1195 // Check the holder map.
991 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 1196 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
992 Immediate(Handle<Map>(holder->map()))); 1197 Immediate(Handle<Map>(holder->map())));
993 __ j(not_equal, miss); 1198 __ j(not_equal, miss);
994 1199
995 // Perform security check for access to the global object. 1200 // Perform security check for access to the global object.
996 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 1201 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
997 if (holder->IsJSGlobalProxy()) { 1202 if (holder->IsJSGlobalProxy()) {
998 __ CheckAccessGlobalProxy(reg, scratch1, miss); 1203 __ CheckAccessGlobalProxy(reg, scratch1, miss);
999 }; 1204 }
1000 1205
1001 // If we've skipped any global objects, it's not enough to verify 1206 // If we've skipped any global objects, it's not enough to verify
1002 // that their maps haven't changed. We also need to check that the 1207 // that their maps haven't changed. We also need to check that the
1003 // property cell for the property is still empty. 1208 // property cell for the property is still empty.
1004 MaybeObject* result = GenerateCheckPropertyCells(masm(), 1209 MaybeObject* result = TryGenerateCheckPropertyCells(masm(),
1005 object, 1210 object,
1006 holder, 1211 holder,
1007 name, 1212 name,
1008 scratch1, 1213 scratch1,
1009 miss); 1214 miss);
1010 if (result->IsFailure()) set_failure(Failure::cast(result)); 1215 if (result->IsFailure()) set_failure(Failure::cast(result));
1011 1216
1012 // Return the register containing the holder. 1217 // Return the register containing the holder.
1013 return reg; 1218 return reg;
1014 } 1219 }
1015 1220
1016 1221
1017 void StubCompiler::GenerateLoadField(JSObject* object, 1222 void StubCompiler::GenerateLoadField(JSObject* object,
1018 JSObject* holder, 1223 JSObject* holder,
1019 Register receiver, 1224 Register receiver,
1020 Register scratch1, 1225 Register scratch1,
1021 Register scratch2, 1226 Register scratch2,
1022 Register scratch3, 1227 Register scratch3,
1023 int index, 1228 int index,
1024 String* name, 1229 String* name,
1025 Label* miss) { 1230 Label* miss) {
1026 // Check that the receiver isn't a smi. 1231 // Check that the receiver isn't a smi.
1027 __ JumpIfSmi(receiver, miss); 1232 __ JumpIfSmi(receiver, miss);
1028 1233
1029 // Check the prototype chain. 1234 // Check the prototype chain.
1030 Register reg = 1235 Register reg =
1031 CheckPrototypes(object, receiver, holder, 1236 CheckPrototypes(object, receiver, holder,
1032 scratch1, scratch2, scratch3, name, miss); 1237 scratch1, scratch2, scratch3, name, miss);
1033 1238
1034 // Get the value from the properties. 1239 // Get the value from the properties.
1035 GenerateFastPropertyLoad(masm(), eax, reg, holder, index); 1240 GenerateFastPropertyLoad(masm(), eax, reg, Handle<JSObject>(holder), index);
1036 __ ret(0); 1241 __ ret(0);
1037 } 1242 }
1038 1243
1039 1244
1040 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, 1245 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object,
1041 JSObject* holder, 1246 JSObject* holder,
1042 Register receiver, 1247 Register receiver,
1043 Register name_reg, 1248 Register name_reg,
1044 Register scratch1, 1249 Register scratch1,
1045 Register scratch2, 1250 Register scratch2,
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1214 scratch2, 1419 scratch2,
1215 scratch3, 1420 scratch3,
1216 name, 1421 name,
1217 miss); 1422 miss);
1218 } 1423 }
1219 1424
1220 if (lookup->type() == FIELD) { 1425 if (lookup->type() == FIELD) {
1221 // We found FIELD property in prototype chain of interceptor's holder. 1426 // We found FIELD property in prototype chain of interceptor's holder.
1222 // Retrieve a field from field's holder. 1427 // Retrieve a field from field's holder.
1223 GenerateFastPropertyLoad(masm(), eax, holder_reg, 1428 GenerateFastPropertyLoad(masm(), eax, holder_reg,
1224 lookup->holder(), lookup->GetFieldIndex()); 1429 Handle<JSObject>(lookup->holder()),
1430 lookup->GetFieldIndex());
1225 __ ret(0); 1431 __ ret(0);
1226 } else { 1432 } else {
1227 // We found CALLBACKS property in prototype chain of interceptor's 1433 // We found CALLBACKS property in prototype chain of interceptor's
1228 // holder. 1434 // holder.
1229 ASSERT(lookup->type() == CALLBACKS); 1435 ASSERT(lookup->type() == CALLBACKS);
1230 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); 1436 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo());
1231 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); 1437 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject());
1232 ASSERT(callback != NULL); 1438 ASSERT(callback != NULL);
1233 ASSERT(callback->getter() != NULL); 1439 ASSERT(callback->getter() != NULL);
1234 1440
(...skipping 26 matching lines...) Expand all
1261 __ push(scratch2); // restore old return address 1467 __ push(scratch2); // restore old return address
1262 1468
1263 ExternalReference ref = 1469 ExternalReference ref =
1264 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), 1470 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad),
1265 isolate()); 1471 isolate());
1266 __ TailCallExternalReference(ref, 5, 1); 1472 __ TailCallExternalReference(ref, 5, 1);
1267 } 1473 }
1268 } 1474 }
1269 1475
1270 1476
1271 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { 1477 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) {
1272 if (kind_ == Code::KEYED_CALL_IC) { 1478 if (kind_ == Code::KEYED_CALL_IC) {
1273 __ cmp(ecx, Immediate(Handle<String>(name))); 1479 __ cmp(ecx, Immediate(name));
1274 __ j(not_equal, miss); 1480 __ j(not_equal, miss);
1275 } 1481 }
1276 } 1482 }
1277 1483
1278 1484
1279 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, 1485 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object,
1280 JSObject* holder, 1486 JSObject* holder,
1281 String* name, 1487 String* name,
1282 Label* miss) { 1488 Label* miss) {
1283 ASSERT(holder->IsGlobalObject()); 1489 ASSERT(holder->IsGlobalObject());
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1326 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset), 1532 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset),
1327 Immediate(Handle<SharedFunctionInfo>(function->shared()))); 1533 Immediate(Handle<SharedFunctionInfo>(function->shared())));
1328 __ j(not_equal, miss); 1534 __ j(not_equal, miss);
1329 } else { 1535 } else {
1330 __ cmp(edi, Immediate(Handle<JSFunction>(function))); 1536 __ cmp(edi, Immediate(Handle<JSFunction>(function)));
1331 __ j(not_equal, miss); 1537 __ j(not_equal, miss);
1332 } 1538 }
1333 } 1539 }
1334 1540
1335 1541
1336 MaybeObject* CallStubCompiler::GenerateMissBranch() { 1542 void CallStubCompiler::GenerateMissBranch() {
1543 Handle<Code> code =
1544 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(),
1545 kind_,
1546 extra_state_);
1547 __ jmp(code, RelocInfo::CODE_TARGET);
1548 }
1549
1550
1551 // TODO(kmillikin): Eliminate this function when the stub cache is fully
1552 // handlified.
1553 MaybeObject* CallStubCompiler::TryGenerateMissBranch() {
1337 MaybeObject* maybe_obj = 1554 MaybeObject* maybe_obj =
1338 isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(), 1555 isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(),
1339 kind_, 1556 kind_,
1340 extra_state_); 1557 extra_state_);
1341 Object* obj; 1558 Object* obj;
1342 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1559 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1343 __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); 1560 __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET);
1344 return obj; 1561 return obj;
1345 } 1562 }
1346 1563
1347 1564
1348 MUST_USE_RESULT MaybeObject* CallStubCompiler::CompileCallField( 1565 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
1349 JSObject* object, 1566 Handle<JSObject> holder,
1350 JSObject* holder, 1567 int index,
1351 int index, 1568 Handle<String> name) {
1352 String* name) {
1353 // ----------- S t a t e ------------- 1569 // ----------- S t a t e -------------
1354 // -- ecx : name 1570 // -- ecx : name
1355 // -- esp[0] : return address 1571 // -- esp[0] : return address
1356 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1572 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1357 // -- ... 1573 // -- ...
1358 // -- esp[(argc + 1) * 4] : receiver 1574 // -- esp[(argc + 1) * 4] : receiver
1359 // ----------------------------------- 1575 // -----------------------------------
1360 Label miss; 1576 Label miss;
1361 1577
1362 GenerateNameCheck(name, &miss); 1578 GenerateNameCheck(name, &miss);
(...skipping 25 matching lines...) Expand all
1388 1604
1389 // Invoke the function. 1605 // Invoke the function.
1390 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 1606 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
1391 ? CALL_AS_FUNCTION 1607 ? CALL_AS_FUNCTION
1392 : CALL_AS_METHOD; 1608 : CALL_AS_METHOD;
1393 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION, 1609 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION,
1394 NullCallWrapper(), call_kind); 1610 NullCallWrapper(), call_kind);
1395 1611
1396 // Handle call cache miss. 1612 // Handle call cache miss.
1397 __ bind(&miss); 1613 __ bind(&miss);
1398 MaybeObject* maybe_result = GenerateMissBranch(); 1614 GenerateMissBranch();
1399 if (maybe_result->IsFailure()) return maybe_result;
1400 1615
1401 // Return the generated code. 1616 // Return the generated code.
1402 return GetCode(FIELD, name); 1617 return GetCode(FIELD, name);
1403 } 1618 }
1404 1619
1405 1620
1406 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, 1621 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object,
1407 JSObject* holder, 1622 JSObject* holder,
1408 JSGlobalPropertyCell* cell, 1623 JSGlobalPropertyCell* cell,
1409 JSFunction* function, 1624 JSFunction* function,
1410 String* name) { 1625 String* name) {
1411 // ----------- S t a t e ------------- 1626 // ----------- S t a t e -------------
1412 // -- ecx : name 1627 // -- ecx : name
1413 // -- esp[0] : return address 1628 // -- esp[0] : return address
1414 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1629 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1415 // -- ... 1630 // -- ...
1416 // -- esp[(argc + 1) * 4] : receiver 1631 // -- esp[(argc + 1) * 4] : receiver
1417 // ----------------------------------- 1632 // -----------------------------------
1418 1633
1419 // If object is not an array, bail out to regular call. 1634 // If object is not an array, bail out to regular call.
1420 if (!object->IsJSArray() || cell != NULL) { 1635 if (!object->IsJSArray() || cell != NULL) {
1421 return isolate()->heap()->undefined_value(); 1636 return isolate()->heap()->undefined_value();
1422 } 1637 }
1423 1638
1424 Label miss; 1639 Label miss;
1425 1640
1426 GenerateNameCheck(name, &miss); 1641 GenerateNameCheck(Handle<String>(name), &miss);
1427 1642
1428 // Get the receiver from the stack. 1643 // Get the receiver from the stack.
1429 const int argc = arguments().immediate(); 1644 const int argc = arguments().immediate();
1430 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1645 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1431 1646
1432 // Check that the receiver isn't a smi. 1647 // Check that the receiver isn't a smi.
1433 __ JumpIfSmi(edx, &miss); 1648 __ JumpIfSmi(edx, &miss);
1434 1649
1435 CheckPrototypes(JSObject::cast(object), edx, 1650 CheckPrototypes(JSObject::cast(object), edx,
1436 holder, ebx, 1651 holder, ebx,
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1573 } 1788 }
1574 1789
1575 __ bind(&call_builtin); 1790 __ bind(&call_builtin);
1576 __ TailCallExternalReference( 1791 __ TailCallExternalReference(
1577 ExternalReference(Builtins::c_ArrayPush, isolate()), 1792 ExternalReference(Builtins::c_ArrayPush, isolate()),
1578 argc + 1, 1793 argc + 1,
1579 1); 1794 1);
1580 } 1795 }
1581 1796
1582 __ bind(&miss); 1797 __ bind(&miss);
1583 MaybeObject* maybe_result = GenerateMissBranch(); 1798 MaybeObject* maybe_result = TryGenerateMissBranch();
1584 if (maybe_result->IsFailure()) return maybe_result; 1799 if (maybe_result->IsFailure()) return maybe_result;
1585 1800
1586 // Return the generated code. 1801 // Return the generated code.
1587 return GetCode(function); 1802 return TryGetCode(function);
1588 } 1803 }
1589 1804
1590 1805
1591 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, 1806 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object,
1592 JSObject* holder, 1807 JSObject* holder,
1593 JSGlobalPropertyCell* cell, 1808 JSGlobalPropertyCell* cell,
1594 JSFunction* function, 1809 JSFunction* function,
1595 String* name) { 1810 String* name) {
1596 // ----------- S t a t e ------------- 1811 // ----------- S t a t e -------------
1597 // -- ecx : name 1812 // -- ecx : name
1598 // -- esp[0] : return address 1813 // -- esp[0] : return address
1599 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1814 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1600 // -- ... 1815 // -- ...
1601 // -- esp[(argc + 1) * 4] : receiver 1816 // -- esp[(argc + 1) * 4] : receiver
1602 // ----------------------------------- 1817 // -----------------------------------
1603 1818
1604 // If object is not an array, bail out to regular call. 1819 // If object is not an array, bail out to regular call.
1605 if (!object->IsJSArray() || cell != NULL) { 1820 if (!object->IsJSArray() || cell != NULL) {
1606 return heap()->undefined_value(); 1821 return heap()->undefined_value();
1607 } 1822 }
1608 1823
1609 Label miss, return_undefined, call_builtin; 1824 Label miss, return_undefined, call_builtin;
1610 1825
1611 GenerateNameCheck(name, &miss); 1826 GenerateNameCheck(Handle<String>(name), &miss);
1612 1827
1613 // Get the receiver from the stack. 1828 // Get the receiver from the stack.
1614 const int argc = arguments().immediate(); 1829 const int argc = arguments().immediate();
1615 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1830 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1616 1831
1617 // Check that the receiver isn't a smi. 1832 // Check that the receiver isn't a smi.
1618 __ JumpIfSmi(edx, &miss); 1833 __ JumpIfSmi(edx, &miss);
1619 CheckPrototypes(JSObject::cast(object), edx, 1834 CheckPrototypes(JSObject::cast(object), edx,
1620 holder, ebx, 1835 holder, ebx,
1621 eax, edi, name, &miss); 1836 eax, edi, name, &miss);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1656 __ mov(eax, Immediate(factory()->undefined_value())); 1871 __ mov(eax, Immediate(factory()->undefined_value()));
1657 __ ret((argc + 1) * kPointerSize); 1872 __ ret((argc + 1) * kPointerSize);
1658 1873
1659 __ bind(&call_builtin); 1874 __ bind(&call_builtin);
1660 __ TailCallExternalReference( 1875 __ TailCallExternalReference(
1661 ExternalReference(Builtins::c_ArrayPop, isolate()), 1876 ExternalReference(Builtins::c_ArrayPop, isolate()),
1662 argc + 1, 1877 argc + 1,
1663 1); 1878 1);
1664 1879
1665 __ bind(&miss); 1880 __ bind(&miss);
1666 MaybeObject* maybe_result = GenerateMissBranch(); 1881 MaybeObject* maybe_result = TryGenerateMissBranch();
1667 if (maybe_result->IsFailure()) return maybe_result; 1882 if (maybe_result->IsFailure()) return maybe_result;
1668 1883
1669 // Return the generated code. 1884 // Return the generated code.
1670 return GetCode(function); 1885 return TryGetCode(function);
1671 } 1886 }
1672 1887
1673 1888
1674 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( 1889 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall(
1675 Object* object, 1890 Object* object,
1676 JSObject* holder, 1891 JSObject* holder,
1677 JSGlobalPropertyCell* cell, 1892 JSGlobalPropertyCell* cell,
1678 JSFunction* function, 1893 JSFunction* function,
1679 String* name) { 1894 String* name) {
1680 // ----------- S t a t e ------------- 1895 // ----------- S t a t e -------------
(...skipping 15 matching lines...) Expand all
1696 Label name_miss; 1911 Label name_miss;
1697 Label index_out_of_range; 1912 Label index_out_of_range;
1698 Label* index_out_of_range_label = &index_out_of_range; 1913 Label* index_out_of_range_label = &index_out_of_range;
1699 1914
1700 if (kind_ == Code::CALL_IC && 1915 if (kind_ == Code::CALL_IC &&
1701 (CallICBase::StringStubState::decode(extra_state_) == 1916 (CallICBase::StringStubState::decode(extra_state_) ==
1702 DEFAULT_STRING_STUB)) { 1917 DEFAULT_STRING_STUB)) {
1703 index_out_of_range_label = &miss; 1918 index_out_of_range_label = &miss;
1704 } 1919 }
1705 1920
1706 GenerateNameCheck(name, &name_miss); 1921 GenerateNameCheck(Handle<String>(name), &name_miss);
1707 1922
1708 // Check that the maps starting from the prototype haven't changed. 1923 // Check that the maps starting from the prototype haven't changed.
1709 GenerateDirectLoadGlobalFunctionPrototype(masm(), 1924 GenerateDirectLoadGlobalFunctionPrototype(masm(),
1710 Context::STRING_FUNCTION_INDEX, 1925 Context::STRING_FUNCTION_INDEX,
1711 eax, 1926 eax,
1712 &miss); 1927 &miss);
1713 ASSERT(object != holder); 1928 ASSERT(object != holder);
1714 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, 1929 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder,
1715 ebx, edx, edi, name, &miss); 1930 ebx, edx, edi, name, &miss);
1716 1931
(...skipping 25 matching lines...) Expand all
1742 if (index_out_of_range.is_linked()) { 1957 if (index_out_of_range.is_linked()) {
1743 __ bind(&index_out_of_range); 1958 __ bind(&index_out_of_range);
1744 __ Set(eax, Immediate(factory()->nan_value())); 1959 __ Set(eax, Immediate(factory()->nan_value()));
1745 __ ret((argc + 1) * kPointerSize); 1960 __ ret((argc + 1) * kPointerSize);
1746 } 1961 }
1747 1962
1748 __ bind(&miss); 1963 __ bind(&miss);
1749 // Restore function name in ecx. 1964 // Restore function name in ecx.
1750 __ Set(ecx, Immediate(Handle<String>(name))); 1965 __ Set(ecx, Immediate(Handle<String>(name)));
1751 __ bind(&name_miss); 1966 __ bind(&name_miss);
1752 MaybeObject* maybe_result = GenerateMissBranch(); 1967 MaybeObject* maybe_result = TryGenerateMissBranch();
1753 if (maybe_result->IsFailure()) return maybe_result; 1968 if (maybe_result->IsFailure()) return maybe_result;
1754 1969
1755 // Return the generated code. 1970 // Return the generated code.
1756 return GetCode(function); 1971 return TryGetCode(function);
1757 } 1972 }
1758 1973
1759 1974
1760 MaybeObject* CallStubCompiler::CompileStringCharAtCall( 1975 MaybeObject* CallStubCompiler::CompileStringCharAtCall(
1761 Object* object, 1976 Object* object,
1762 JSObject* holder, 1977 JSObject* holder,
1763 JSGlobalPropertyCell* cell, 1978 JSGlobalPropertyCell* cell,
1764 JSFunction* function, 1979 JSFunction* function,
1765 String* name) { 1980 String* name) {
1766 // ----------- S t a t e ------------- 1981 // ----------- S t a t e -------------
(...skipping 15 matching lines...) Expand all
1782 Label name_miss; 1997 Label name_miss;
1783 Label index_out_of_range; 1998 Label index_out_of_range;
1784 Label* index_out_of_range_label = &index_out_of_range; 1999 Label* index_out_of_range_label = &index_out_of_range;
1785 2000
1786 if (kind_ == Code::CALL_IC && 2001 if (kind_ == Code::CALL_IC &&
1787 (CallICBase::StringStubState::decode(extra_state_) == 2002 (CallICBase::StringStubState::decode(extra_state_) ==
1788 DEFAULT_STRING_STUB)) { 2003 DEFAULT_STRING_STUB)) {
1789 index_out_of_range_label = &miss; 2004 index_out_of_range_label = &miss;
1790 } 2005 }
1791 2006
1792 GenerateNameCheck(name, &name_miss); 2007 GenerateNameCheck(Handle<String>(name), &name_miss);
1793 2008
1794 // Check that the maps starting from the prototype haven't changed. 2009 // Check that the maps starting from the prototype haven't changed.
1795 GenerateDirectLoadGlobalFunctionPrototype(masm(), 2010 GenerateDirectLoadGlobalFunctionPrototype(masm(),
1796 Context::STRING_FUNCTION_INDEX, 2011 Context::STRING_FUNCTION_INDEX,
1797 eax, 2012 eax,
1798 &miss); 2013 &miss);
1799 ASSERT(object != holder); 2014 ASSERT(object != holder);
1800 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, 2015 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder,
1801 ebx, edx, edi, name, &miss); 2016 ebx, edx, edi, name, &miss);
1802 2017
(...skipping 27 matching lines...) Expand all
1830 if (index_out_of_range.is_linked()) { 2045 if (index_out_of_range.is_linked()) {
1831 __ bind(&index_out_of_range); 2046 __ bind(&index_out_of_range);
1832 __ Set(eax, Immediate(factory()->empty_string())); 2047 __ Set(eax, Immediate(factory()->empty_string()));
1833 __ ret((argc + 1) * kPointerSize); 2048 __ ret((argc + 1) * kPointerSize);
1834 } 2049 }
1835 2050
1836 __ bind(&miss); 2051 __ bind(&miss);
1837 // Restore function name in ecx. 2052 // Restore function name in ecx.
1838 __ Set(ecx, Immediate(Handle<String>(name))); 2053 __ Set(ecx, Immediate(Handle<String>(name)));
1839 __ bind(&name_miss); 2054 __ bind(&name_miss);
1840 MaybeObject* maybe_result = GenerateMissBranch(); 2055 MaybeObject* maybe_result = TryGenerateMissBranch();
1841 if (maybe_result->IsFailure()) return maybe_result; 2056 if (maybe_result->IsFailure()) return maybe_result;
1842 2057
1843 // Return the generated code. 2058 // Return the generated code.
1844 return GetCode(function); 2059 return TryGetCode(function);
1845 } 2060 }
1846 2061
1847 2062
1848 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( 2063 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall(
1849 Object* object, 2064 Object* object,
1850 JSObject* holder, 2065 JSObject* holder,
1851 JSGlobalPropertyCell* cell, 2066 JSGlobalPropertyCell* cell,
1852 JSFunction* function, 2067 JSFunction* function,
1853 String* name) { 2068 String* name) {
1854 // ----------- S t a t e ------------- 2069 // ----------- S t a t e -------------
1855 // -- ecx : function name 2070 // -- ecx : function name
1856 // -- esp[0] : return address 2071 // -- esp[0] : return address
1857 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 2072 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1858 // -- ... 2073 // -- ...
1859 // -- esp[(argc + 1) * 4] : receiver 2074 // -- esp[(argc + 1) * 4] : receiver
1860 // ----------------------------------- 2075 // -----------------------------------
1861 2076
1862 const int argc = arguments().immediate(); 2077 const int argc = arguments().immediate();
1863 2078
1864 // If the object is not a JSObject or we got an unexpected number of 2079 // If the object is not a JSObject or we got an unexpected number of
1865 // arguments, bail out to the regular call. 2080 // arguments, bail out to the regular call.
1866 if (!object->IsJSObject() || argc != 1) { 2081 if (!object->IsJSObject() || argc != 1) {
1867 return isolate()->heap()->undefined_value(); 2082 return isolate()->heap()->undefined_value();
1868 } 2083 }
1869 2084
1870 Label miss; 2085 Label miss;
1871 GenerateNameCheck(name, &miss); 2086 GenerateNameCheck(Handle<String>(name), &miss);
1872 2087
1873 if (cell == NULL) { 2088 if (cell == NULL) {
1874 __ mov(edx, Operand(esp, 2 * kPointerSize)); 2089 __ mov(edx, Operand(esp, 2 * kPointerSize));
1875 2090
1876 STATIC_ASSERT(kSmiTag == 0); 2091 STATIC_ASSERT(kSmiTag == 0);
1877 __ JumpIfSmi(edx, &miss); 2092 __ JumpIfSmi(edx, &miss);
1878 2093
1879 CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name, 2094 CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name,
1880 &miss); 2095 &miss);
1881 } else { 2096 } else {
(...skipping 25 matching lines...) Expand all
1907 // because the function makes no use of it. 2122 // because the function makes no use of it.
1908 __ bind(&slow); 2123 __ bind(&slow);
1909 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2124 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
1910 ? CALL_AS_FUNCTION 2125 ? CALL_AS_FUNCTION
1911 : CALL_AS_METHOD; 2126 : CALL_AS_METHOD;
1912 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, 2127 __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
1913 NullCallWrapper(), call_kind); 2128 NullCallWrapper(), call_kind);
1914 2129
1915 __ bind(&miss); 2130 __ bind(&miss);
1916 // ecx: function name. 2131 // ecx: function name.
1917 MaybeObject* maybe_result = GenerateMissBranch(); 2132 MaybeObject* maybe_result = TryGenerateMissBranch();
1918 if (maybe_result->IsFailure()) return maybe_result; 2133 if (maybe_result->IsFailure()) return maybe_result;
1919 2134
1920 // Return the generated code. 2135 // Return the generated code.
1921 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); 2136 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name);
1922 } 2137 }
1923 2138
1924 2139
1925 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, 2140 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object,
1926 JSObject* holder, 2141 JSObject* holder,
1927 JSGlobalPropertyCell* cell, 2142 JSGlobalPropertyCell* cell,
1928 JSFunction* function, 2143 JSFunction* function,
1929 String* name) { 2144 String* name) {
1930 // ----------- S t a t e ------------- 2145 // ----------- S t a t e -------------
1931 // -- ecx : name 2146 // -- ecx : name
(...skipping 11 matching lines...) Expand all
1943 2158
1944 const int argc = arguments().immediate(); 2159 const int argc = arguments().immediate();
1945 2160
1946 // If the object is not a JSObject or we got an unexpected number of 2161 // If the object is not a JSObject or we got an unexpected number of
1947 // arguments, bail out to the regular call. 2162 // arguments, bail out to the regular call.
1948 if (!object->IsJSObject() || argc != 1) { 2163 if (!object->IsJSObject() || argc != 1) {
1949 return isolate()->heap()->undefined_value(); 2164 return isolate()->heap()->undefined_value();
1950 } 2165 }
1951 2166
1952 Label miss; 2167 Label miss;
1953 GenerateNameCheck(name, &miss); 2168 GenerateNameCheck(Handle<String>(name), &miss);
1954 2169
1955 if (cell == NULL) { 2170 if (cell == NULL) {
1956 __ mov(edx, Operand(esp, 2 * kPointerSize)); 2171 __ mov(edx, Operand(esp, 2 * kPointerSize));
1957 2172
1958 STATIC_ASSERT(kSmiTag == 0); 2173 STATIC_ASSERT(kSmiTag == 0);
1959 __ JumpIfSmi(edx, &miss); 2174 __ JumpIfSmi(edx, &miss);
1960 2175
1961 CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name, 2176 CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name,
1962 &miss); 2177 &miss);
1963 } else { 2178 } else {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2036 __ ret(2 * kPointerSize); 2251 __ ret(2 * kPointerSize);
2037 2252
2038 // Tail call the full function. We do not have to patch the receiver 2253 // Tail call the full function. We do not have to patch the receiver
2039 // because the function makes no use of it. 2254 // because the function makes no use of it.
2040 __ bind(&slow); 2255 __ bind(&slow);
2041 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, 2256 __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
2042 NullCallWrapper(), CALL_AS_METHOD); 2257 NullCallWrapper(), CALL_AS_METHOD);
2043 2258
2044 __ bind(&miss); 2259 __ bind(&miss);
2045 // ecx: function name. 2260 // ecx: function name.
2046 MaybeObject* maybe_result = GenerateMissBranch(); 2261 MaybeObject* maybe_result = TryGenerateMissBranch();
2047 if (maybe_result->IsFailure()) return maybe_result; 2262 if (maybe_result->IsFailure()) return maybe_result;
2048 2263
2049 // Return the generated code. 2264 // Return the generated code.
2050 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); 2265 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name);
2051 } 2266 }
2052 2267
2053 2268
2054 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, 2269 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object,
2055 JSObject* holder, 2270 JSObject* holder,
2056 JSGlobalPropertyCell* cell, 2271 JSGlobalPropertyCell* cell,
2057 JSFunction* function, 2272 JSFunction* function,
2058 String* name) { 2273 String* name) {
2059 // ----------- S t a t e ------------- 2274 // ----------- S t a t e -------------
2060 // -- ecx : name 2275 // -- ecx : name
2061 // -- esp[0] : return address 2276 // -- esp[0] : return address
2062 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 2277 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2063 // -- ... 2278 // -- ...
2064 // -- esp[(argc + 1) * 4] : receiver 2279 // -- esp[(argc + 1) * 4] : receiver
2065 // ----------------------------------- 2280 // -----------------------------------
2066 2281
2067 const int argc = arguments().immediate(); 2282 const int argc = arguments().immediate();
2068 2283
2069 // If the object is not a JSObject or we got an unexpected number of 2284 // If the object is not a JSObject or we got an unexpected number of
2070 // arguments, bail out to the regular call. 2285 // arguments, bail out to the regular call.
2071 if (!object->IsJSObject() || argc != 1) { 2286 if (!object->IsJSObject() || argc != 1) {
2072 return isolate()->heap()->undefined_value(); 2287 return isolate()->heap()->undefined_value();
2073 } 2288 }
2074 2289
2075 Label miss; 2290 Label miss;
2076 GenerateNameCheck(name, &miss); 2291 GenerateNameCheck(Handle<String>(name), &miss);
2077 2292
2078 if (cell == NULL) { 2293 if (cell == NULL) {
2079 __ mov(edx, Operand(esp, 2 * kPointerSize)); 2294 __ mov(edx, Operand(esp, 2 * kPointerSize));
2080 2295
2081 STATIC_ASSERT(kSmiTag == 0); 2296 STATIC_ASSERT(kSmiTag == 0);
2082 __ JumpIfSmi(edx, &miss); 2297 __ JumpIfSmi(edx, &miss);
2083 2298
2084 CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name, 2299 CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name,
2085 &miss); 2300 &miss);
2086 } else { 2301 } else {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2140 __ ret(2 * kPointerSize); 2355 __ ret(2 * kPointerSize);
2141 2356
2142 // Tail call the full function. We do not have to patch the receiver 2357 // Tail call the full function. We do not have to patch the receiver
2143 // because the function makes no use of it. 2358 // because the function makes no use of it.
2144 __ bind(&slow); 2359 __ bind(&slow);
2145 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, 2360 __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
2146 NullCallWrapper(), CALL_AS_METHOD); 2361 NullCallWrapper(), CALL_AS_METHOD);
2147 2362
2148 __ bind(&miss); 2363 __ bind(&miss);
2149 // ecx: function name. 2364 // ecx: function name.
2150 MaybeObject* maybe_result = GenerateMissBranch(); 2365 MaybeObject* maybe_result = TryGenerateMissBranch();
2151 if (maybe_result->IsFailure()) return maybe_result; 2366 if (maybe_result->IsFailure()) return maybe_result;
2152 2367
2153 // Return the generated code. 2368 // Return the generated code.
2154 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); 2369 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name);
2155 } 2370 }
2156 2371
2157 2372
2158 MaybeObject* CallStubCompiler::CompileFastApiCall( 2373 MaybeObject* CallStubCompiler::CompileFastApiCall(
2159 const CallOptimization& optimization, 2374 const CallOptimization& optimization,
2160 Object* object, 2375 Object* object,
2161 JSObject* holder, 2376 JSObject* holder,
2162 JSGlobalPropertyCell* cell, 2377 JSGlobalPropertyCell* cell,
2163 JSFunction* function, 2378 JSFunction* function,
2164 String* name) { 2379 String* name) {
2165 ASSERT(optimization.is_simple_api_call()); 2380 ASSERT(optimization.is_simple_api_call());
2166 // Bail out if object is a global object as we don't want to 2381 // Bail out if object is a global object as we don't want to
2167 // repatch it to global receiver. 2382 // repatch it to global receiver.
2168 if (object->IsGlobalObject()) return heap()->undefined_value(); 2383 if (object->IsGlobalObject()) return heap()->undefined_value();
2169 if (cell != NULL) return heap()->undefined_value(); 2384 if (cell != NULL) return heap()->undefined_value();
2170 if (!object->IsJSObject()) return heap()->undefined_value(); 2385 if (!object->IsJSObject()) return heap()->undefined_value();
2171 int depth = optimization.GetPrototypeDepthOfExpectedType( 2386 int depth = optimization.GetPrototypeDepthOfExpectedType(
2172 JSObject::cast(object), holder); 2387 JSObject::cast(object), holder);
2173 if (depth == kInvalidProtoDepth) return heap()->undefined_value(); 2388 if (depth == kInvalidProtoDepth) return heap()->undefined_value();
2174 2389
2175 Label miss, miss_before_stack_reserved; 2390 Label miss, miss_before_stack_reserved;
2176 2391
2177 GenerateNameCheck(name, &miss_before_stack_reserved); 2392 GenerateNameCheck(Handle<String>(name), &miss_before_stack_reserved);
2178 2393
2179 // Get the receiver from the stack. 2394 // Get the receiver from the stack.
2180 const int argc = arguments().immediate(); 2395 const int argc = arguments().immediate();
2181 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2396 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2182 2397
2183 // Check that the receiver isn't a smi. 2398 // Check that the receiver isn't a smi.
2184 __ JumpIfSmi(edx, &miss_before_stack_reserved); 2399 __ JumpIfSmi(edx, &miss_before_stack_reserved);
2185 2400
2186 Counters* counters = isolate()->counters(); 2401 Counters* counters = isolate()->counters();
2187 __ IncrementCounter(counters->call_const(), 1); 2402 __ IncrementCounter(counters->call_const(), 1);
(...skipping 13 matching lines...) Expand all
2201 2416
2202 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains 2417 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains
2203 // duplicate of return address and will be overwritten. 2418 // duplicate of return address and will be overwritten.
2204 MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc); 2419 MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc);
2205 if (result->IsFailure()) return result; 2420 if (result->IsFailure()) return result;
2206 2421
2207 __ bind(&miss); 2422 __ bind(&miss);
2208 __ add(esp, Immediate(kFastApiCallArguments * kPointerSize)); 2423 __ add(esp, Immediate(kFastApiCallArguments * kPointerSize));
2209 2424
2210 __ bind(&miss_before_stack_reserved); 2425 __ bind(&miss_before_stack_reserved);
2211 MaybeObject* maybe_result = GenerateMissBranch(); 2426 MaybeObject* maybe_result = TryGenerateMissBranch();
2212 if (maybe_result->IsFailure()) return maybe_result; 2427 if (maybe_result->IsFailure()) return maybe_result;
2213 2428
2214 // Return the generated code. 2429 // Return the generated code.
2215 return GetCode(function); 2430 return TryGetCode(function);
2216 } 2431 }
2217 2432
2218 2433
2219 MaybeObject* CallStubCompiler::CompileCallConstant( 2434 MaybeObject* CallStubCompiler::CompileCallConstant(
2220 Object* object, 2435 Object* object,
2221 JSObject* holder, 2436 JSObject* holder,
2222 JSFunction* function, 2437 JSFunction* function,
2223 String* name, 2438 String* name,
2224 CheckType check) { 2439 CheckType check) {
2225 // ----------- S t a t e ------------- 2440 // ----------- S t a t e -------------
2226 // -- ecx : name 2441 // -- ecx : name
2227 // -- esp[0] : return address 2442 // -- esp[0] : return address
2228 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 2443 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2229 // -- ... 2444 // -- ...
2230 // -- esp[(argc + 1) * 4] : receiver 2445 // -- esp[(argc + 1) * 4] : receiver
2231 // ----------------------------------- 2446 // -----------------------------------
2232 2447
2233 if (HasCustomCallGenerator(function)) { 2448 if (HasCustomCallGenerator(function)) {
2234 MaybeObject* maybe_result = CompileCustomCall( 2449 MaybeObject* maybe_result = CompileCustomCall(
2235 object, holder, NULL, function, name); 2450 object, holder, NULL, function, name);
2236 Object* result; 2451 Object* result;
2237 if (!maybe_result->ToObject(&result)) return maybe_result; 2452 if (!maybe_result->ToObject(&result)) return maybe_result;
2238 // undefined means bail out to regular compiler. 2453 // undefined means bail out to regular compiler.
2239 if (!result->IsUndefined()) return result; 2454 if (!result->IsUndefined()) return result;
2240 } 2455 }
2241 2456
2242 Label miss; 2457 Label miss;
2243 2458
2244 GenerateNameCheck(name, &miss); 2459 GenerateNameCheck(Handle<String>(name), &miss);
2245 2460
2246 // Get the receiver from the stack. 2461 // Get the receiver from the stack.
2247 const int argc = arguments().immediate(); 2462 const int argc = arguments().immediate();
2248 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2463 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2249 2464
2250 // Check that the receiver isn't a smi. 2465 // Check that the receiver isn't a smi.
2251 if (check != NUMBER_CHECK) { 2466 if (check != NUMBER_CHECK) {
2252 __ JumpIfSmi(edx, &miss); 2467 __ JumpIfSmi(edx, &miss);
2253 } 2468 }
2254 2469
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
2338 } 2553 }
2339 2554
2340 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2555 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2341 ? CALL_AS_FUNCTION 2556 ? CALL_AS_FUNCTION
2342 : CALL_AS_METHOD; 2557 : CALL_AS_METHOD;
2343 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, 2558 __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
2344 NullCallWrapper(), call_kind); 2559 NullCallWrapper(), call_kind);
2345 2560
2346 // Handle call cache miss. 2561 // Handle call cache miss.
2347 __ bind(&miss); 2562 __ bind(&miss);
2348 MaybeObject* maybe_result = GenerateMissBranch(); 2563 MaybeObject* maybe_result = TryGenerateMissBranch();
2349 if (maybe_result->IsFailure()) return maybe_result; 2564 if (maybe_result->IsFailure()) return maybe_result;
2350 2565
2351 // Return the generated code. 2566 // Return the generated code.
2352 return GetCode(function); 2567 return TryGetCode(function);
2353 } 2568 }
2354 2569
2355 2570
2356 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, 2571 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object,
2357 JSObject* holder, 2572 JSObject* holder,
2358 String* name) { 2573 String* name) {
2359 // ----------- S t a t e ------------- 2574 // ----------- S t a t e -------------
2360 // -- ecx : name 2575 // -- ecx : name
2361 // -- esp[0] : return address 2576 // -- esp[0] : return address
2362 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 2577 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2363 // -- ... 2578 // -- ...
2364 // -- esp[(argc + 1) * 4] : receiver 2579 // -- esp[(argc + 1) * 4] : receiver
2365 // ----------------------------------- 2580 // -----------------------------------
2366 Label miss; 2581 Label miss;
2367 2582
2368 GenerateNameCheck(name, &miss); 2583 GenerateNameCheck(Handle<String>(name), &miss);
2369 2584
2370 // Get the number of arguments. 2585 // Get the number of arguments.
2371 const int argc = arguments().immediate(); 2586 const int argc = arguments().immediate();
2372 2587
2373 LookupResult lookup(isolate()); 2588 LookupResult lookup(isolate());
2374 LookupPostInterceptor(holder, name, &lookup); 2589 LookupPostInterceptor(holder, name, &lookup);
2375 2590
2376 // Get the receiver from the stack. 2591 // Get the receiver from the stack.
2377 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2592 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2378 2593
(...skipping 28 matching lines...) Expand all
2407 // Invoke the function. 2622 // Invoke the function.
2408 __ mov(edi, eax); 2623 __ mov(edi, eax);
2409 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2624 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2410 ? CALL_AS_FUNCTION 2625 ? CALL_AS_FUNCTION
2411 : CALL_AS_METHOD; 2626 : CALL_AS_METHOD;
2412 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION, 2627 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION,
2413 NullCallWrapper(), call_kind); 2628 NullCallWrapper(), call_kind);
2414 2629
2415 // Handle load cache miss. 2630 // Handle load cache miss.
2416 __ bind(&miss); 2631 __ bind(&miss);
2417 MaybeObject* maybe_result = GenerateMissBranch(); 2632 MaybeObject* maybe_result = TryGenerateMissBranch();
2418 if (maybe_result->IsFailure()) return maybe_result; 2633 if (maybe_result->IsFailure()) return maybe_result;
2419 2634
2420 // Return the generated code. 2635 // Return the generated code.
2421 return GetCode(INTERCEPTOR, name); 2636 return TryGetCode(INTERCEPTOR, name);
2422 } 2637 }
2423 2638
2424 2639
2425 MaybeObject* CallStubCompiler::CompileCallGlobal( 2640 MaybeObject* CallStubCompiler::CompileCallGlobal(
2426 JSObject* object, 2641 JSObject* object,
2427 GlobalObject* holder, 2642 GlobalObject* holder,
2428 JSGlobalPropertyCell* cell, 2643 JSGlobalPropertyCell* cell,
2429 JSFunction* function, 2644 JSFunction* function,
2430 String* name) { 2645 String* name) {
2431 // ----------- S t a t e ------------- 2646 // ----------- S t a t e -------------
2432 // -- ecx : name 2647 // -- ecx : name
2433 // -- esp[0] : return address 2648 // -- esp[0] : return address
2434 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 2649 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2435 // -- ... 2650 // -- ...
2436 // -- esp[(argc + 1) * 4] : receiver 2651 // -- esp[(argc + 1) * 4] : receiver
2437 // ----------------------------------- 2652 // -----------------------------------
2438 2653
2439 if (HasCustomCallGenerator(function)) { 2654 if (HasCustomCallGenerator(function)) {
2440 MaybeObject* maybe_result = CompileCustomCall( 2655 MaybeObject* maybe_result = CompileCustomCall(
2441 object, holder, cell, function, name); 2656 object, holder, cell, function, name);
2442 Object* result; 2657 Object* result;
2443 if (!maybe_result->ToObject(&result)) return maybe_result; 2658 if (!maybe_result->ToObject(&result)) return maybe_result;
2444 // undefined means bail out to regular compiler. 2659 // undefined means bail out to regular compiler.
2445 if (!result->IsUndefined()) return result; 2660 if (!result->IsUndefined()) return result;
2446 } 2661 }
2447 2662
2448 Label miss; 2663 Label miss;
2449 2664
2450 GenerateNameCheck(name, &miss); 2665 GenerateNameCheck(Handle<String>(name), &miss);
2451 2666
2452 // Get the number of arguments. 2667 // Get the number of arguments.
2453 const int argc = arguments().immediate(); 2668 const int argc = arguments().immediate();
2454 2669
2455 GenerateGlobalReceiverCheck(object, holder, name, &miss); 2670 GenerateGlobalReceiverCheck(object, holder, name, &miss);
2456 2671
2457 GenerateLoadFunctionFromCell(cell, function, &miss); 2672 GenerateLoadFunctionFromCell(cell, function, &miss);
2458 2673
2459 // Patch the receiver on the stack with the global proxy. 2674 // Patch the receiver on the stack with the global proxy.
2460 if (object->IsGlobalObject()) { 2675 if (object->IsGlobalObject()) {
(...skipping 14 matching lines...) Expand all
2475 // We call indirectly through the code field in the function to 2690 // We call indirectly through the code field in the function to
2476 // allow recompilation to take effect without changing any of the 2691 // allow recompilation to take effect without changing any of the
2477 // call sites. 2692 // call sites.
2478 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), 2693 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
2479 expected, arguments(), JUMP_FUNCTION, 2694 expected, arguments(), JUMP_FUNCTION,
2480 NullCallWrapper(), call_kind); 2695 NullCallWrapper(), call_kind);
2481 2696
2482 // Handle call cache miss. 2697 // Handle call cache miss.
2483 __ bind(&miss); 2698 __ bind(&miss);
2484 __ IncrementCounter(counters->call_global_inline_miss(), 1); 2699 __ IncrementCounter(counters->call_global_inline_miss(), 1);
2485 MaybeObject* maybe_result = GenerateMissBranch(); 2700 MaybeObject* maybe_result = TryGenerateMissBranch();
2486 if (maybe_result->IsFailure()) return maybe_result; 2701 if (maybe_result->IsFailure()) return maybe_result;
2487 2702
2488 // Return the generated code. 2703 // Return the generated code.
2489 return GetCode(NORMAL, name); 2704 return TryGetCode(NORMAL, name);
2490 } 2705 }
2491 2706
2492 2707
2493 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, 2708 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object,
2494 int index, 2709 int index,
2495 Map* transition, 2710 Map* transition,
2496 String* name) { 2711 String* name) {
2497 // ----------- S t a t e ------------- 2712 // ----------- S t a t e -------------
2498 // -- eax : value 2713 // -- eax : value
2499 // -- ecx : name 2714 // -- ecx : name
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
2797 ASSERT(last->IsGlobalObject() || last->HasFastProperties()); 3012 ASSERT(last->IsGlobalObject() || last->HasFastProperties());
2798 3013
2799 // Check the maps of the full prototype chain. Also check that 3014 // Check the maps of the full prototype chain. Also check that
2800 // global property cells up to (but not including) the last object 3015 // global property cells up to (but not including) the last object
2801 // in the prototype chain are empty. 3016 // in the prototype chain are empty.
2802 CheckPrototypes(object, eax, last, ebx, edx, edi, name, &miss); 3017 CheckPrototypes(object, eax, last, ebx, edx, edi, name, &miss);
2803 3018
2804 // If the last object in the prototype chain is a global object, 3019 // If the last object in the prototype chain is a global object,
2805 // check that the global property cell is empty. 3020 // check that the global property cell is empty.
2806 if (last->IsGlobalObject()) { 3021 if (last->IsGlobalObject()) {
2807 MaybeObject* cell = GenerateCheckPropertyCell(masm(), 3022 MaybeObject* cell = TryGenerateCheckPropertyCell(masm(),
2808 GlobalObject::cast(last), 3023 GlobalObject::cast(last),
2809 name, 3024 name,
2810 edx, 3025 edx,
2811 &miss); 3026 &miss);
2812 if (cell->IsFailure()) { 3027 if (cell->IsFailure()) {
2813 miss.Unuse(); 3028 miss.Unuse();
2814 return cell; 3029 return cell;
2815 } 3030 }
2816 } 3031 }
2817 3032
2818 // Return undefined if maps of the full prototype chain are still the 3033 // Return undefined if maps of the full prototype chain are still the
2819 // same and no global property with this name contains a value. 3034 // same and no global property with this name contains a value.
2820 __ mov(eax, isolate()->factory()->undefined_value()); 3035 __ mov(eax, isolate()->factory()->undefined_value());
2821 __ ret(0); 3036 __ ret(0);
(...skipping 1194 matching lines...) Expand 10 before | Expand all | Expand 10 after
4016 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); 4231 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
4017 __ jmp(ic_miss, RelocInfo::CODE_TARGET); 4232 __ jmp(ic_miss, RelocInfo::CODE_TARGET);
4018 } 4233 }
4019 4234
4020 4235
4021 #undef __ 4236 #undef __
4022 4237
4023 } } // namespace v8::internal 4238 } } // namespace v8::internal
4024 4239
4025 #endif // V8_TARGET_ARCH_IA32 4240 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698