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

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

Issue 8404030: Version 3.7.1 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/mips/simulator-mips.cc ('k') | src/mirror-debugger.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 // Miss: fall through. 92 // Miss: fall through.
93 __ bind(&miss); 93 __ bind(&miss);
94 } 94 }
95 95
96 96
97 // Helper function used to check that the dictionary doesn't contain 97 // Helper function used to check that the dictionary doesn't contain
98 // the property. This function may return false negatives, so miss_label 98 // the property. This function may return false negatives, so miss_label
99 // must always call a backup property check that is complete. 99 // must always call a backup property check that is complete.
100 // This function is safe to call if the receiver has fast properties. 100 // This function is safe to call if the receiver has fast properties.
101 // Name must be a symbol and receiver must be a heap object. 101 // Name must be a symbol and receiver must be a heap object.
102 MUST_USE_RESULT static MaybeObject* GenerateDictionaryNegativeLookup( 102 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
103 Label* miss_label,
104 Register receiver,
105 Handle<String> name,
106 Register scratch0,
107 Register scratch1) {
108 ASSERT(name->IsSymbol());
109 Counters* counters = masm->isolate()->counters();
110 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
111 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
112
113 Label done;
114
115 const int kInterceptorOrAccessCheckNeededMask =
116 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
117
118 // Bail out if the receiver has a named interceptor or requires access checks.
119 Register map = scratch1;
120 __ lw(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
121 __ lbu(scratch0, FieldMemOperand(map, Map::kBitFieldOffset));
122 __ And(scratch0, scratch0, Operand(kInterceptorOrAccessCheckNeededMask));
123 __ Branch(miss_label, ne, scratch0, Operand(zero_reg));
124
125 // Check that receiver is a JSObject.
126 __ lbu(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset));
127 __ Branch(miss_label, lt, scratch0, Operand(FIRST_SPEC_OBJECT_TYPE));
128
129 // Load properties array.
130 Register properties = scratch0;
131 __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
132 // Check that the properties array is a dictionary.
133 __ lw(map, FieldMemOperand(properties, HeapObject::kMapOffset));
134 Register tmp = properties;
135 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex);
136 __ Branch(miss_label, ne, map, Operand(tmp));
137
138 // Restore the temporarily used register.
139 __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
140
141
142 StringDictionaryLookupStub::GenerateNegativeLookup(masm,
143 miss_label,
144 &done,
145 receiver,
146 properties,
147 name,
148 scratch1);
149 __ bind(&done);
150 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
151 }
152
153
154 // TODO(kmillikin): Eliminate this function when the stub cache is fully
155 // handlified.
156 MUST_USE_RESULT static MaybeObject* TryGenerateDictionaryNegativeLookup(
103 MacroAssembler* masm, 157 MacroAssembler* masm,
104 Label* miss_label, 158 Label* miss_label,
105 Register receiver, 159 Register receiver,
106 String* name, 160 String* name,
107 Register scratch0, 161 Register scratch0,
108 Register scratch1) { 162 Register scratch1) {
109 ASSERT(name->IsSymbol()); 163 ASSERT(name->IsSymbol());
110 Counters* counters = masm->isolate()->counters(); 164 Counters* counters = masm->isolate()->counters();
111 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); 165 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
112 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 166 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
(...skipping 20 matching lines...) Expand all
133 __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 187 __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
134 // Check that the properties array is a dictionary. 188 // Check that the properties array is a dictionary.
135 __ lw(map, FieldMemOperand(properties, HeapObject::kMapOffset)); 189 __ lw(map, FieldMemOperand(properties, HeapObject::kMapOffset));
136 Register tmp = properties; 190 Register tmp = properties;
137 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); 191 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex);
138 __ Branch(miss_label, ne, map, Operand(tmp)); 192 __ Branch(miss_label, ne, map, Operand(tmp));
139 193
140 // Restore the temporarily used register. 194 // Restore the temporarily used register.
141 __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 195 __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
142 196
143 MaybeObject* result = StringDictionaryLookupStub::GenerateNegativeLookup( 197 MaybeObject* result = StringDictionaryLookupStub::TryGenerateNegativeLookup(
144 masm, 198 masm,
145 miss_label, 199 miss_label,
146 &done, 200 &done,
147 receiver, 201 receiver,
148 properties, 202 properties,
149 name, 203 name,
150 scratch1); 204 scratch1);
151 if (result->IsFailure()) return result; 205 if (result->IsFailure()) return result;
152 206
153 __ bind(&done); 207 __ bind(&done);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 __ li(prototype, Handle<Map>(function->initial_map())); 308 __ li(prototype, Handle<Map>(function->initial_map()));
255 // Load the prototype from the initial map. 309 // Load the prototype from the initial map.
256 __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); 310 __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
257 } 311 }
258 312
259 313
260 // Load a fast property out of a holder object (src). In-object properties 314 // Load a fast property out of a holder object (src). In-object properties
261 // are loaded directly otherwise the property is loaded from the properties 315 // are loaded directly otherwise the property is loaded from the properties
262 // fixed array. 316 // fixed array.
263 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, 317 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
264 Register dst, Register src, 318 Register dst,
265 JSObject* holder, int index) { 319 Register src,
320 Handle<JSObject> holder,
321 int index) {
266 // Adjust for the number of properties stored in the holder. 322 // Adjust for the number of properties stored in the holder.
267 index -= holder->map()->inobject_properties(); 323 index -= holder->map()->inobject_properties();
268 if (index < 0) { 324 if (index < 0) {
269 // Get the property straight out of the holder. 325 // Get the property straight out of the holder.
270 int offset = holder->map()->instance_size() + (index * kPointerSize); 326 int offset = holder->map()->instance_size() + (index * kPointerSize);
271 __ lw(dst, FieldMemOperand(src, offset)); 327 __ lw(dst, FieldMemOperand(src, offset));
272 } else { 328 } else {
273 // Calculate the offset into the properties array. 329 // Calculate the offset into the properties array.
274 int offset = index * kPointerSize + FixedArray::kHeaderSize; 330 int offset = index * kPointerSize + FixedArray::kHeaderSize;
275 __ lw(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); 331 __ lw(dst, FieldMemOperand(src, JSObject::kPropertiesOffset));
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 518
463 // Return the value (register v0). 519 // Return the value (register v0).
464 __ bind(&exit); 520 __ bind(&exit);
465 __ mov(v0, a0); 521 __ mov(v0, a0);
466 __ Ret(); 522 __ Ret();
467 } 523 }
468 524
469 525
470 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { 526 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) {
471 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); 527 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
472 Code* code = NULL; 528 Handle<Code> code = (kind == Code::LOAD_IC)
473 if (kind == Code::LOAD_IC) { 529 ? masm->isolate()->builtins()->LoadIC_Miss()
474 code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss); 530 : masm->isolate()->builtins()->KeyedLoadIC_Miss();
475 } else { 531 __ Jump(code, RelocInfo::CODE_TARGET);
476 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss);
477 }
478
479 Handle<Code> ic(code);
480 __ Jump(ic, RelocInfo::CODE_TARGET);
481 } 532 }
482 533
483 534
484 static void GenerateCallFunction(MacroAssembler* masm, 535 static void GenerateCallFunction(MacroAssembler* masm,
485 Object* object, 536 Handle<Object> object,
486 const ParameterCount& arguments, 537 const ParameterCount& arguments,
487 Label* miss, 538 Label* miss,
488 Code::ExtraICState extra_ic_state) { 539 Code::ExtraICState extra_ic_state) {
489 // ----------- S t a t e ------------- 540 // ----------- S t a t e -------------
490 // -- a0: receiver 541 // -- a0: receiver
491 // -- a1: function to call 542 // -- a1: function to call
492 // ----------------------------------- 543 // -----------------------------------
493 // Check that the function really is a function. 544 // Check that the function really is a function.
494 __ JumpIfSmi(a1, miss); 545 __ JumpIfSmi(a1, miss);
495 __ GetObjectType(a1, a3, a3); 546 __ GetObjectType(a1, a3, a3);
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
871 const ParameterCount& arguments_; 922 const ParameterCount& arguments_;
872 Register name_; 923 Register name_;
873 Code::ExtraICState extra_ic_state_; 924 Code::ExtraICState extra_ic_state_;
874 }; 925 };
875 926
876 927
877 928
878 // Generate code to check that a global property cell is empty. Create 929 // Generate code to check that a global property cell is empty. Create
879 // the property cell at compilation time if no cell exists for the 930 // the property cell at compilation time if no cell exists for the
880 // property. 931 // property.
881 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCell( 932 static void GenerateCheckPropertyCell(MacroAssembler* masm,
933 Handle<GlobalObject> global,
934 Handle<String> name,
935 Register scratch,
936 Label* miss) {
937 Handle<JSGlobalPropertyCell> cell =
938 GlobalObject::EnsurePropertyCell(global, name);
939 ASSERT(cell->value()->IsTheHole());
940 __ li(scratch, Operand(cell));
941 __ lw(scratch,
942 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
943 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
944 __ Branch(miss, ne, scratch, Operand(at));
945 }
946
947
948 // TODO(kmillikin): Eliminate this function when the stub cache is fully
949 // handlified.
950 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCell(
882 MacroAssembler* masm, 951 MacroAssembler* masm,
883 GlobalObject* global, 952 GlobalObject* global,
884 String* name, 953 String* name,
885 Register scratch, 954 Register scratch,
886 Label* miss) { 955 Label* miss) {
887 Object* probe; 956 Object* probe;
888 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); 957 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name);
889 if (!maybe_probe->ToObject(&probe)) return maybe_probe; 958 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
890 } 959 }
891 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); 960 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe);
892 ASSERT(cell->value()->IsTheHole()); 961 ASSERT(cell->value()->IsTheHole());
893 __ li(scratch, Operand(Handle<Object>(cell))); 962 __ li(scratch, Operand(Handle<Object>(cell)));
894 __ lw(scratch, 963 __ lw(scratch,
895 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); 964 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
896 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 965 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
897 __ Branch(miss, ne, scratch, Operand(at)); 966 __ Branch(miss, ne, scratch, Operand(at));
898 return cell; 967 return cell;
899 } 968 }
900 969
901 970
902 // Calls GenerateCheckPropertyCell for each global object in the prototype chain 971 // Calls GenerateCheckPropertyCell for each global object in the prototype chain
903 // from object to (but not including) holder. 972 // from object to (but not including) holder.
904 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCells( 973 static void GenerateCheckPropertyCells(MacroAssembler* masm,
974 Handle<JSObject> object,
975 Handle<JSObject> holder,
976 Handle<String> name,
977 Register scratch,
978 Label* miss) {
979 Handle<JSObject> current = object;
980 while (!current.is_identical_to(holder)) {
981 if (current->IsGlobalObject()) {
982 GenerateCheckPropertyCell(masm,
983 Handle<GlobalObject>::cast(current),
984 name,
985 scratch,
986 miss);
987 }
988 current = Handle<JSObject>(JSObject::cast(current->GetPrototype()));
989 }
990 }
991
992
993 // TODO(kmillikin): Eliminate this function when the stub cache is fully
994 // handlified.
995 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCells(
905 MacroAssembler* masm, 996 MacroAssembler* masm,
906 JSObject* object, 997 JSObject* object,
907 JSObject* holder, 998 JSObject* holder,
908 String* name, 999 String* name,
909 Register scratch, 1000 Register scratch,
910 Label* miss) { 1001 Label* miss) {
911 JSObject* current = object; 1002 JSObject* current = object;
912 while (current != holder) { 1003 while (current != holder) {
913 if (current->IsGlobalObject()) { 1004 if (current->IsGlobalObject()) {
914 // Returns a cell or a failure. 1005 // Returns a cell or a failure.
915 MaybeObject* result = GenerateCheckPropertyCell( 1006 MaybeObject* result = TryGenerateCheckPropertyCell(
916 masm, 1007 masm,
917 GlobalObject::cast(current), 1008 GlobalObject::cast(current),
918 name, 1009 name,
919 scratch, 1010 scratch,
920 miss); 1011 miss);
921 if (result->IsFailure()) return result; 1012 if (result->IsFailure()) return result;
922 } 1013 }
923 ASSERT(current->IsJSObject()); 1014 ASSERT(current->IsJSObject());
924 current = JSObject::cast(current->GetPrototype()); 1015 current = JSObject::cast(current->GetPrototype());
925 } 1016 }
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1040 __ nor(scratch, scratch, scratch); 1131 __ nor(scratch, scratch, scratch);
1041 __ and_(hiword, hiword, scratch); 1132 __ and_(hiword, hiword, scratch);
1042 } 1133 }
1043 } 1134 }
1044 1135
1045 1136
1046 #undef __ 1137 #undef __
1047 #define __ ACCESS_MASM(masm()) 1138 #define __ ACCESS_MASM(masm())
1048 1139
1049 1140
1141 Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
1142 Register object_reg,
1143 Handle<JSObject> holder,
1144 Register holder_reg,
1145 Register scratch1,
1146 Register scratch2,
1147 Handle<String> name,
1148 int save_at_depth,
1149 Label* miss) {
1150 // Make sure there's no overlap between holder and object registers.
1151 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
1152 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
1153 && !scratch2.is(scratch1));
1154
1155 // Keep track of the current object in register reg.
1156 Register reg = object_reg;
1157 int depth = 0;
1158
1159 if (save_at_depth == depth) {
1160 __ sw(reg, MemOperand(sp));
1161 }
1162
1163 // Check the maps in the prototype chain.
1164 // Traverse the prototype chain from the object and do map checks.
1165 Handle<JSObject> current = object;
1166 while (!current.is_identical_to(holder)) {
1167 ++depth;
1168
1169 // Only global objects and objects that do not require access
1170 // checks are allowed in stubs.
1171 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded());
1172
1173 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype()));
1174 if (!current->HasFastProperties() &&
1175 !current->IsJSGlobalObject() &&
1176 !current->IsJSGlobalProxy()) {
1177 if (!name->IsSymbol()) {
1178 name = factory()->LookupSymbol(name);
1179 }
1180 ASSERT(current->property_dictionary()->FindEntry(*name) ==
1181 StringDictionary::kNotFound);
1182
1183 GenerateDictionaryNegativeLookup(masm(), miss, reg, name,
1184 scratch1, scratch2);
1185
1186 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
1187 reg = holder_reg; // From now on the object will be in holder_reg.
1188 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
1189 } else {
1190 Handle<Map> current_map(current->map());
1191 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
1192 // Branch on the result of the map check.
1193 __ Branch(miss, ne, scratch1, Operand(current_map));
1194 // Check access rights to the global object. This has to happen after
1195 // the map check so that we know that the object is actually a global
1196 // object.
1197 if (current->IsJSGlobalProxy()) {
1198 __ CheckAccessGlobalProxy(reg, scratch2, miss);
1199 }
1200 reg = holder_reg; // From now on the object will be in holder_reg.
1201
1202 if (heap()->InNewSpace(*prototype)) {
1203 // The prototype is in new space; we cannot store a reference to it
1204 // in the code. Load it from the map.
1205 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
1206 } else {
1207 // The prototype is in old space; load it directly.
1208 __ li(reg, Operand(prototype));
1209 }
1210 }
1211
1212 if (save_at_depth == depth) {
1213 __ sw(reg, MemOperand(sp));
1214 }
1215
1216 // Go to the next object in the prototype chain.
1217 current = prototype;
1218 }
1219
1220 // Log the check depth.
1221 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1));
1222
1223 // Check the holder map.
1224 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
1225 __ Branch(miss, ne, scratch1, Operand(Handle<Map>(current->map())));
1226
1227 // Perform security check for access to the global object.
1228 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
1229 if (holder->IsJSGlobalProxy()) {
1230 __ CheckAccessGlobalProxy(reg, scratch1, miss);
1231 }
1232
1233 // If we've skipped any global objects, it's not enough to verify that
1234 // their maps haven't changed. We also need to check that the property
1235 // cell for the property is still empty.
1236 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss);
1237
1238 // Return the register containing the holder.
1239 return reg;
1240 }
1241
1242
1050 Register StubCompiler::CheckPrototypes(JSObject* object, 1243 Register StubCompiler::CheckPrototypes(JSObject* object,
1051 Register object_reg, 1244 Register object_reg,
1052 JSObject* holder, 1245 JSObject* holder,
1053 Register holder_reg, 1246 Register holder_reg,
1054 Register scratch1, 1247 Register scratch1,
1055 Register scratch2, 1248 Register scratch2,
1056 String* name, 1249 String* name,
1057 int save_at_depth, 1250 int save_at_depth,
1058 Label* miss) { 1251 Label* miss) {
1059 // Make sure there's no overlap between holder and object registers. 1252 // Make sure there's no overlap between holder and object registers.
(...skipping 29 matching lines...) Expand all
1089 Object* lookup_result = NULL; // Initialization to please compiler. 1282 Object* lookup_result = NULL; // Initialization to please compiler.
1090 if (!maybe_lookup_result->ToObject(&lookup_result)) { 1283 if (!maybe_lookup_result->ToObject(&lookup_result)) {
1091 set_failure(Failure::cast(maybe_lookup_result)); 1284 set_failure(Failure::cast(maybe_lookup_result));
1092 return reg; 1285 return reg;
1093 } 1286 }
1094 name = String::cast(lookup_result); 1287 name = String::cast(lookup_result);
1095 } 1288 }
1096 ASSERT(current->property_dictionary()->FindEntry(name) == 1289 ASSERT(current->property_dictionary()->FindEntry(name) ==
1097 StringDictionary::kNotFound); 1290 StringDictionary::kNotFound);
1098 1291
1099 MaybeObject* negative_lookup = GenerateDictionaryNegativeLookup(masm(), 1292 MaybeObject* negative_lookup =
1100 miss, 1293 TryGenerateDictionaryNegativeLookup(masm(),
1101 reg, 1294 miss,
1102 name, 1295 reg,
1103 scratch1, 1296 name,
1104 scratch2); 1297 scratch1,
1298 scratch2);
1299
1105 if (negative_lookup->IsFailure()) { 1300 if (negative_lookup->IsFailure()) {
1106 set_failure(Failure::cast(negative_lookup)); 1301 set_failure(Failure::cast(negative_lookup));
1107 return reg; 1302 return reg;
1108 } 1303 }
1109 1304
1110 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); 1305 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
1111 reg = holder_reg; // From now the object is in holder_reg. 1306 reg = holder_reg; // From now the object is in holder_reg.
1112 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); 1307 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
1113 } else if (heap()->InNewSpace(prototype)) { 1308 } else if (heap()->InNewSpace(prototype)) {
1114 // Get the map of the current object. 1309 // Get the map of the current object.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1159 // Check the holder map. 1354 // Check the holder map.
1160 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); 1355 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
1161 __ Branch(miss, ne, scratch1, Operand(Handle<Map>(current->map()))); 1356 __ Branch(miss, ne, scratch1, Operand(Handle<Map>(current->map())));
1162 1357
1163 // Log the check depth. 1358 // Log the check depth.
1164 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); 1359 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1));
1165 // Perform security check for access to the global object. 1360 // Perform security check for access to the global object.
1166 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 1361 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
1167 if (holder->IsJSGlobalProxy()) { 1362 if (holder->IsJSGlobalProxy()) {
1168 __ CheckAccessGlobalProxy(reg, scratch1, miss); 1363 __ CheckAccessGlobalProxy(reg, scratch1, miss);
1169 }; 1364 }
1170 1365
1171 // If we've skipped any global objects, it's not enough to verify 1366 // If we've skipped any global objects, it's not enough to verify
1172 // that their maps haven't changed. We also need to check that the 1367 // that their maps haven't changed. We also need to check that the
1173 // property cell for the property is still empty. 1368 // property cell for the property is still empty.
1174 1369
1175 MaybeObject* result = GenerateCheckPropertyCells(masm(), 1370 MaybeObject* result = TryGenerateCheckPropertyCells(masm(),
1176 object, 1371 object,
1177 holder, 1372 holder,
1178 name, 1373 name,
1179 scratch1, 1374 scratch1,
1180 miss); 1375 miss);
1181 if (result->IsFailure()) set_failure(Failure::cast(result)); 1376 if (result->IsFailure()) set_failure(Failure::cast(result));
1182 1377
1183 // Return the register containing the holder. 1378 // Return the register containing the holder.
1184 return reg; 1379 return reg;
1185 } 1380 }
1186 1381
1187 1382
1188 void StubCompiler::GenerateLoadField(JSObject* object, 1383 void StubCompiler::GenerateLoadField(Handle<JSObject> object,
1189 JSObject* holder, 1384 Handle<JSObject> holder,
1190 Register receiver, 1385 Register receiver,
1191 Register scratch1, 1386 Register scratch1,
1192 Register scratch2, 1387 Register scratch2,
1193 Register scratch3, 1388 Register scratch3,
1194 int index, 1389 int index,
1195 String* name, 1390 Handle<String> name,
1196 Label* miss) { 1391 Label* miss) {
1197 // Check that the receiver isn't a smi. 1392 // Check that the receiver isn't a smi.
1198 __ And(scratch1, receiver, Operand(kSmiTagMask)); 1393 __ And(scratch1, receiver, Operand(kSmiTagMask));
1199 __ Branch(miss, eq, scratch1, Operand(zero_reg)); 1394 __ Branch(miss, eq, scratch1, Operand(zero_reg));
1200 1395
1201 // Check that the maps haven't changed. 1396 // Check that the maps haven't changed.
1202 Register reg = 1397 Register reg = CheckPrototypes(
1203 CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, 1398 object, receiver, holder, scratch1, scratch2, scratch3, name, miss);
1204 name, miss);
1205 GenerateFastPropertyLoad(masm(), v0, reg, holder, index); 1399 GenerateFastPropertyLoad(masm(), v0, reg, holder, index);
1206 __ Ret(); 1400 __ Ret();
1207 } 1401 }
1208 1402
1209 1403
1210 void StubCompiler::GenerateLoadConstant(JSObject* object, 1404 void StubCompiler::GenerateLoadConstant(Handle<JSObject> object,
1211 JSObject* holder, 1405 Handle<JSObject> holder,
1212 Register receiver, 1406 Register receiver,
1213 Register scratch1, 1407 Register scratch1,
1214 Register scratch2, 1408 Register scratch2,
1215 Register scratch3, 1409 Register scratch3,
1216 Object* value, 1410 Handle<Object> value,
1217 String* name, 1411 Handle<String> name,
1218 Label* miss) { 1412 Label* miss) {
1219 // Check that the receiver isn't a smi. 1413 // Check that the receiver isn't a smi.
1220 __ JumpIfSmi(receiver, miss, scratch1); 1414 __ JumpIfSmi(receiver, miss, scratch1);
1221 1415
1222 // Check that the maps haven't changed. 1416 // Check that the maps haven't changed.
1223 Register reg = 1417 Register reg =
1224 CheckPrototypes(object, receiver, holder, 1418 CheckPrototypes(object, receiver, holder,
1225 scratch1, scratch2, scratch3, name, miss); 1419 scratch1, scratch2, scratch3, name, miss);
1226 1420
1227 // Return the constant value. 1421 // Return the constant value.
1228 __ li(v0, Operand(Handle<Object>(value))); 1422 __ li(v0, Operand(value));
1229 __ Ret(); 1423 __ Ret();
1230 } 1424 }
1231 1425
1232 1426
1233 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, 1427 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object,
1234 JSObject* holder, 1428 JSObject* holder,
1235 Register receiver, 1429 Register receiver,
1236 Register name_reg, 1430 Register name_reg,
1237 Register scratch1, 1431 Register scratch1,
1238 Register scratch2, 1432 Register scratch2,
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 scratch2, 1577 scratch2,
1384 scratch3, 1578 scratch3,
1385 name, 1579 name,
1386 miss); 1580 miss);
1387 } 1581 }
1388 1582
1389 if (lookup->type() == FIELD) { 1583 if (lookup->type() == FIELD) {
1390 // We found FIELD property in prototype chain of interceptor's holder. 1584 // We found FIELD property in prototype chain of interceptor's holder.
1391 // Retrieve a field from field's holder. 1585 // Retrieve a field from field's holder.
1392 GenerateFastPropertyLoad(masm(), v0, holder_reg, 1586 GenerateFastPropertyLoad(masm(), v0, holder_reg,
1393 lookup->holder(), lookup->GetFieldIndex()); 1587 Handle<JSObject>(lookup->holder()),
1588 lookup->GetFieldIndex());
1394 __ Ret(); 1589 __ Ret();
1395 } else { 1590 } else {
1396 // We found CALLBACKS property in prototype chain of interceptor's 1591 // We found CALLBACKS property in prototype chain of interceptor's
1397 // holder. 1592 // holder.
1398 ASSERT(lookup->type() == CALLBACKS); 1593 ASSERT(lookup->type() == CALLBACKS);
1399 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); 1594 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo());
1400 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); 1595 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject());
1401 ASSERT(callback != NULL); 1596 ASSERT(callback != NULL);
1402 ASSERT(callback->getter() != NULL); 1597 ASSERT(callback->getter() != NULL);
1403 1598
(...skipping 29 matching lines...) Expand all
1433 PushInterceptorArguments(masm(), receiver, holder_reg, 1628 PushInterceptorArguments(masm(), receiver, holder_reg,
1434 name_reg, interceptor_holder); 1629 name_reg, interceptor_holder);
1435 1630
1436 ExternalReference ref = ExternalReference( 1631 ExternalReference ref = ExternalReference(
1437 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), masm()->isolate()); 1632 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), masm()->isolate());
1438 __ TailCallExternalReference(ref, 5, 1); 1633 __ TailCallExternalReference(ref, 5, 1);
1439 } 1634 }
1440 } 1635 }
1441 1636
1442 1637
1443 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { 1638 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) {
1444 if (kind_ == Code::KEYED_CALL_IC) { 1639 if (kind_ == Code::KEYED_CALL_IC) {
1445 __ Branch(miss, ne, a2, Operand(Handle<String>(name))); 1640 __ Branch(miss, ne, a2, Operand(name));
1446 } 1641 }
1447 } 1642 }
1448 1643
1449 1644
1450 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, 1645 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object,
1451 JSObject* holder, 1646 JSObject* holder,
1452 String* name, 1647 String* name,
1453 Label* miss) { 1648 Label* miss) {
1454 ASSERT(holder->IsGlobalObject()); 1649 ASSERT(holder->IsGlobalObject());
1455 1650
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1492 // Check the shared function info. Make sure it hasn't changed. 1687 // Check the shared function info. Make sure it hasn't changed.
1493 __ li(a3, Handle<SharedFunctionInfo>(function->shared())); 1688 __ li(a3, Handle<SharedFunctionInfo>(function->shared()));
1494 __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); 1689 __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
1495 __ Branch(miss, ne, t0, Operand(a3)); 1690 __ Branch(miss, ne, t0, Operand(a3));
1496 } else { 1691 } else {
1497 __ Branch(miss, ne, a1, Operand(Handle<JSFunction>(function))); 1692 __ Branch(miss, ne, a1, Operand(Handle<JSFunction>(function)));
1498 } 1693 }
1499 } 1694 }
1500 1695
1501 1696
1502 MaybeObject* CallStubCompiler::GenerateMissBranch() { 1697 void CallStubCompiler::GenerateMissBranch() {
1503 MaybeObject* maybe_obj = 1698 Handle<Code> code =
1504 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), 1699 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(),
1505 kind_, 1700 kind_,
1506 extra_ic_state_); 1701 extra_state_);
1702 __ Jump(code, RelocInfo::CODE_TARGET);
1703 }
1704
1705
1706 // TODO(kmillikin): Eliminate this function when the stub cache is fully
1707 // handlified.
1708 MaybeObject* CallStubCompiler::TryGenerateMissBranch() {
1709 MaybeObject* maybe_obj =
1710 isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(),
1711 kind_,
1712 extra_state_);
1507 Object* obj; 1713 Object* obj;
1508 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1714 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1509 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); 1715 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET);
1510 return obj; 1716 return obj;
1511 } 1717 }
1512 1718
1513 1719
1514 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object, 1720 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
1515 JSObject* holder, 1721 Handle<JSObject> holder,
1516 int index, 1722 int index,
1517 String* name) { 1723 Handle<String> name) {
1518 // ----------- S t a t e ------------- 1724 // ----------- S t a t e -------------
1519 // -- a2 : name 1725 // -- a2 : name
1520 // -- ra : return address 1726 // -- ra : return address
1521 // ----------------------------------- 1727 // -----------------------------------
1522 Label miss; 1728 Label miss;
1523 1729
1524 GenerateNameCheck(name, &miss); 1730 GenerateNameCheck(name, &miss);
1525 1731
1526 const int argc = arguments().immediate(); 1732 const int argc = arguments().immediate();
1527 1733
1528 // Get the receiver of the function from the stack into a0. 1734 // Get the receiver of the function from the stack into a0.
1529 __ lw(a0, MemOperand(sp, argc * kPointerSize)); 1735 __ lw(a0, MemOperand(sp, argc * kPointerSize));
1530 // Check that the receiver isn't a smi. 1736 // Check that the receiver isn't a smi.
1531 __ JumpIfSmi(a0, &miss, t0); 1737 __ JumpIfSmi(a0, &miss, t0);
1532 1738
1533 // Do the right check and compute the holder register. 1739 // Do the right check and compute the holder register.
1534 Register reg = CheckPrototypes(object, a0, holder, a1, a3, t0, name, &miss); 1740 Register reg = CheckPrototypes(object, a0, holder, a1, a3, t0, name, &miss);
1535 GenerateFastPropertyLoad(masm(), a1, reg, holder, index); 1741 GenerateFastPropertyLoad(masm(), a1, reg, holder, index);
1536 1742
1537 GenerateCallFunction(masm(), object, arguments(), &miss, extra_ic_state_); 1743 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_);
1538 1744
1539 // Handle call cache miss. 1745 // Handle call cache miss.
1540 __ bind(&miss); 1746 __ bind(&miss);
1541 MaybeObject* maybe_result = GenerateMissBranch(); 1747 GenerateMissBranch();
1542 if (maybe_result->IsFailure()) return maybe_result;
1543 1748
1544 // Return the generated code. 1749 // Return the generated code.
1545 return GetCode(FIELD, name); 1750 return GetCode(FIELD, name);
1546 } 1751 }
1547 1752
1548 1753
1549 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, 1754 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object,
1550 JSObject* holder, 1755 JSObject* holder,
1551 JSGlobalPropertyCell* cell, 1756 JSGlobalPropertyCell* cell,
1552 JSFunction* function, 1757 JSFunction* function,
1553 String* name) { 1758 String* name) {
1554 // ----------- S t a t e ------------- 1759 // ----------- S t a t e -------------
1555 // -- a2 : name 1760 // -- a2 : name
1556 // -- ra : return address 1761 // -- ra : return address
1557 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 1762 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
1558 // -- ... 1763 // -- ...
1559 // -- sp[argc * 4] : receiver 1764 // -- sp[argc * 4] : receiver
1560 // ----------------------------------- 1765 // -----------------------------------
1561 1766
1562 // If object is not an array, bail out to regular call. 1767 // If object is not an array, bail out to regular call.
1563 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); 1768 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value();
1564 1769
1565 Label miss; 1770 Label miss;
1566 1771
1567 GenerateNameCheck(name, &miss); 1772 GenerateNameCheck(Handle<String>(name), &miss);
1568 1773
1569 Register receiver = a1; 1774 Register receiver = a1;
1570 1775
1571 // Get the receiver from the stack. 1776 // Get the receiver from the stack.
1572 const int argc = arguments().immediate(); 1777 const int argc = arguments().immediate();
1573 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); 1778 __ lw(receiver, MemOperand(sp, argc * kPointerSize));
1574 1779
1575 // Check that the receiver isn't a smi. 1780 // Check that the receiver isn't a smi.
1576 __ JumpIfSmi(receiver, &miss); 1781 __ JumpIfSmi(receiver, &miss);
1577 1782
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1633 __ Addu(end_elements, end_elements, kEndElementsOffset); 1838 __ Addu(end_elements, end_elements, kEndElementsOffset);
1634 __ sw(t0, MemOperand(end_elements)); 1839 __ sw(t0, MemOperand(end_elements));
1635 1840
1636 // Check for a smi. 1841 // Check for a smi.
1637 __ Drop(argc + 1); 1842 __ Drop(argc + 1);
1638 __ Ret(); 1843 __ Ret();
1639 1844
1640 __ bind(&with_write_barrier); 1845 __ bind(&with_write_barrier);
1641 1846
1642 __ lw(t2, FieldMemOperand(receiver, HeapObject::kMapOffset)); 1847 __ lw(t2, FieldMemOperand(receiver, HeapObject::kMapOffset));
1643 __ CheckFastSmiOnlyElements(t2, t2, &call_builtin); 1848 __ CheckFastObjectElements(t2, t2, &call_builtin);
1644 1849
1645 // Save new length. 1850 // Save new length.
1646 __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1851 __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset));
1647 1852
1648 // Push the element. 1853 // Push the element.
1649 // We may need a register containing the address end_elements below, 1854 // We may need a register containing the address end_elements below,
1650 // so write back the value in end_elements. 1855 // so write back the value in end_elements.
1651 __ sll(end_elements, v0, kPointerSizeLog2 - kSmiTagSize); 1856 __ sll(end_elements, v0, kPointerSizeLog2 - kSmiTagSize);
1652 __ Addu(end_elements, elements, end_elements); 1857 __ Addu(end_elements, elements, end_elements);
1653 __ Addu(end_elements, end_elements, kEndElementsOffset); 1858 __ Addu(end_elements, end_elements, kEndElementsOffset);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1723 } 1928 }
1724 __ bind(&call_builtin); 1929 __ bind(&call_builtin);
1725 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, 1930 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush,
1726 masm()->isolate()), 1931 masm()->isolate()),
1727 argc + 1, 1932 argc + 1,
1728 1); 1933 1);
1729 } 1934 }
1730 1935
1731 // Handle call cache miss. 1936 // Handle call cache miss.
1732 __ bind(&miss); 1937 __ bind(&miss);
1733 MaybeObject* maybe_result = GenerateMissBranch(); 1938 MaybeObject* maybe_result = TryGenerateMissBranch();
1734 if (maybe_result->IsFailure()) return maybe_result; 1939 if (maybe_result->IsFailure()) return maybe_result;
1735 1940
1736 // Return the generated code. 1941 // Return the generated code.
1737 return GetCode(function); 1942 return TryGetCode(function);
1738 } 1943 }
1739 1944
1740 1945
1741 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, 1946 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object,
1742 JSObject* holder, 1947 JSObject* holder,
1743 JSGlobalPropertyCell* cell, 1948 JSGlobalPropertyCell* cell,
1744 JSFunction* function, 1949 JSFunction* function,
1745 String* name) { 1950 String* name) {
1746 // ----------- S t a t e ------------- 1951 // ----------- S t a t e -------------
1747 // -- a2 : name 1952 // -- a2 : name
1748 // -- ra : return address 1953 // -- ra : return address
1749 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 1954 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
1750 // -- ... 1955 // -- ...
1751 // -- sp[argc * 4] : receiver 1956 // -- sp[argc * 4] : receiver
1752 // ----------------------------------- 1957 // -----------------------------------
1753 1958
1754 // If object is not an array, bail out to regular call. 1959 // If object is not an array, bail out to regular call.
1755 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); 1960 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value();
1756 1961
1757 Label miss, return_undefined, call_builtin; 1962 Label miss, return_undefined, call_builtin;
1758 1963
1759 Register receiver = a1; 1964 Register receiver = a1;
1760 Register elements = a3; 1965 Register elements = a3;
1761 1966
1762 GenerateNameCheck(name, &miss); 1967 GenerateNameCheck(Handle<String>(name), &miss);
1763 1968
1764 // Get the receiver from the stack. 1969 // Get the receiver from the stack.
1765 const int argc = arguments().immediate(); 1970 const int argc = arguments().immediate();
1766 __ lw(receiver, MemOperand(sp, argc * kPointerSize)); 1971 __ lw(receiver, MemOperand(sp, argc * kPointerSize));
1767 1972
1768 // Check that the receiver isn't a smi. 1973 // Check that the receiver isn't a smi.
1769 __ JumpIfSmi(receiver, &miss); 1974 __ JumpIfSmi(receiver, &miss);
1770 1975
1771 // Check that the maps haven't changed. 1976 // Check that the maps haven't changed.
1772 CheckPrototypes(JSObject::cast(object), 1977 CheckPrototypes(JSObject::cast(object),
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1812 __ Ret(); 2017 __ Ret();
1813 2018
1814 __ bind(&call_builtin); 2019 __ bind(&call_builtin);
1815 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop, 2020 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop,
1816 masm()->isolate()), 2021 masm()->isolate()),
1817 argc + 1, 2022 argc + 1,
1818 1); 2023 1);
1819 2024
1820 // Handle call cache miss. 2025 // Handle call cache miss.
1821 __ bind(&miss); 2026 __ bind(&miss);
1822 MaybeObject* maybe_result = GenerateMissBranch(); 2027 MaybeObject* maybe_result = TryGenerateMissBranch();
1823 if (maybe_result->IsFailure()) return maybe_result; 2028 if (maybe_result->IsFailure()) return maybe_result;
1824 2029
1825 // Return the generated code. 2030 // Return the generated code.
1826 return GetCode(function); 2031 return TryGetCode(function);
1827 } 2032 }
1828 2033
1829 2034
1830 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( 2035 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall(
1831 Object* object, 2036 Object* object,
1832 JSObject* holder, 2037 JSObject* holder,
1833 JSGlobalPropertyCell* cell, 2038 JSGlobalPropertyCell* cell,
1834 JSFunction* function, 2039 JSFunction* function,
1835 String* name) { 2040 String* name) {
1836 // ----------- S t a t e ------------- 2041 // ----------- S t a t e -------------
1837 // -- a2 : function name 2042 // -- a2 : function name
1838 // -- ra : return address 2043 // -- ra : return address
1839 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 2044 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
1840 // -- ... 2045 // -- ...
1841 // -- sp[argc * 4] : receiver 2046 // -- sp[argc * 4] : receiver
1842 // ----------------------------------- 2047 // -----------------------------------
1843 2048
1844 // If object is not a string, bail out to regular call. 2049 // If object is not a string, bail out to regular call.
1845 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); 2050 if (!object->IsString() || cell != NULL) return heap()->undefined_value();
1846 2051
1847 const int argc = arguments().immediate(); 2052 const int argc = arguments().immediate();
1848 2053
1849 Label miss; 2054 Label miss;
1850 Label name_miss; 2055 Label name_miss;
1851 Label index_out_of_range; 2056 Label index_out_of_range;
1852 2057
1853 Label* index_out_of_range_label = &index_out_of_range; 2058 Label* index_out_of_range_label = &index_out_of_range;
1854 2059
1855 if (kind_ == Code::CALL_IC && 2060 if (kind_ == Code::CALL_IC &&
1856 (CallICBase::StringStubState::decode(extra_ic_state_) == 2061 (CallICBase::StringStubState::decode(extra_state_) ==
1857 DEFAULT_STRING_STUB)) { 2062 DEFAULT_STRING_STUB)) {
1858 index_out_of_range_label = &miss; 2063 index_out_of_range_label = &miss;
1859 } 2064 }
1860 2065
1861 GenerateNameCheck(name, &name_miss); 2066 GenerateNameCheck(Handle<String>(name), &name_miss);
1862 2067
1863 // Check that the maps starting from the prototype haven't changed. 2068 // Check that the maps starting from the prototype haven't changed.
1864 GenerateDirectLoadGlobalFunctionPrototype(masm(), 2069 GenerateDirectLoadGlobalFunctionPrototype(masm(),
1865 Context::STRING_FUNCTION_INDEX, 2070 Context::STRING_FUNCTION_INDEX,
1866 v0, 2071 v0,
1867 &miss); 2072 &miss);
1868 ASSERT(object != holder); 2073 ASSERT(object != holder);
1869 CheckPrototypes(JSObject::cast(object->GetPrototype()), v0, holder, 2074 CheckPrototypes(JSObject::cast(object->GetPrototype()), v0, holder,
1870 a1, a3, t0, name, &miss); 2075 a1, a3, t0, name, &miss);
1871 2076
(...skipping 27 matching lines...) Expand all
1899 __ bind(&index_out_of_range); 2104 __ bind(&index_out_of_range);
1900 __ LoadRoot(v0, Heap::kNanValueRootIndex); 2105 __ LoadRoot(v0, Heap::kNanValueRootIndex);
1901 __ Drop(argc + 1); 2106 __ Drop(argc + 1);
1902 __ Ret(); 2107 __ Ret();
1903 } 2108 }
1904 2109
1905 __ bind(&miss); 2110 __ bind(&miss);
1906 // Restore function name in a2. 2111 // Restore function name in a2.
1907 __ li(a2, Handle<String>(name)); 2112 __ li(a2, Handle<String>(name));
1908 __ bind(&name_miss); 2113 __ bind(&name_miss);
1909 MaybeObject* maybe_result = GenerateMissBranch(); 2114 MaybeObject* maybe_result = TryGenerateMissBranch();
1910 if (maybe_result->IsFailure()) return maybe_result; 2115 if (maybe_result->IsFailure()) return maybe_result;
1911 2116
1912 // Return the generated code. 2117 // Return the generated code.
1913 return GetCode(function); 2118 return TryGetCode(function);
1914 } 2119 }
1915 2120
1916 2121
1917 MaybeObject* CallStubCompiler::CompileStringCharAtCall( 2122 MaybeObject* CallStubCompiler::CompileStringCharAtCall(
1918 Object* object, 2123 Object* object,
1919 JSObject* holder, 2124 JSObject* holder,
1920 JSGlobalPropertyCell* cell, 2125 JSGlobalPropertyCell* cell,
1921 JSFunction* function, 2126 JSFunction* function,
1922 String* name) { 2127 String* name) {
1923 // ----------- S t a t e ------------- 2128 // ----------- S t a t e -------------
1924 // -- a2 : function name 2129 // -- a2 : function name
1925 // -- ra : return address 2130 // -- ra : return address
1926 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 2131 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
1927 // -- ... 2132 // -- ...
1928 // -- sp[argc * 4] : receiver 2133 // -- sp[argc * 4] : receiver
1929 // ----------------------------------- 2134 // -----------------------------------
1930 2135
1931 // If object is not a string, bail out to regular call. 2136 // If object is not a string, bail out to regular call.
1932 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); 2137 if (!object->IsString() || cell != NULL) return heap()->undefined_value();
1933 2138
1934 const int argc = arguments().immediate(); 2139 const int argc = arguments().immediate();
1935 2140
1936 Label miss; 2141 Label miss;
1937 Label name_miss; 2142 Label name_miss;
1938 Label index_out_of_range; 2143 Label index_out_of_range;
1939 Label* index_out_of_range_label = &index_out_of_range; 2144 Label* index_out_of_range_label = &index_out_of_range;
1940 2145
1941 if (kind_ == Code::CALL_IC && 2146 if (kind_ == Code::CALL_IC &&
1942 (CallICBase::StringStubState::decode(extra_ic_state_) == 2147 (CallICBase::StringStubState::decode(extra_state_) ==
1943 DEFAULT_STRING_STUB)) { 2148 DEFAULT_STRING_STUB)) {
1944 index_out_of_range_label = &miss; 2149 index_out_of_range_label = &miss;
1945 } 2150 }
1946 2151
1947 GenerateNameCheck(name, &name_miss); 2152 GenerateNameCheck(Handle<String>(name), &name_miss);
1948 2153
1949 // Check that the maps starting from the prototype haven't changed. 2154 // Check that the maps starting from the prototype haven't changed.
1950 GenerateDirectLoadGlobalFunctionPrototype(masm(), 2155 GenerateDirectLoadGlobalFunctionPrototype(masm(),
1951 Context::STRING_FUNCTION_INDEX, 2156 Context::STRING_FUNCTION_INDEX,
1952 v0, 2157 v0,
1953 &miss); 2158 &miss);
1954 ASSERT(object != holder); 2159 ASSERT(object != holder);
1955 CheckPrototypes(JSObject::cast(object->GetPrototype()), v0, holder, 2160 CheckPrototypes(JSObject::cast(object->GetPrototype()), v0, holder,
1956 a1, a3, t0, name, &miss); 2161 a1, a3, t0, name, &miss);
1957 2162
(...skipping 29 matching lines...) Expand all
1987 __ bind(&index_out_of_range); 2192 __ bind(&index_out_of_range);
1988 __ LoadRoot(v0, Heap::kEmptyStringRootIndex); 2193 __ LoadRoot(v0, Heap::kEmptyStringRootIndex);
1989 __ Drop(argc + 1); 2194 __ Drop(argc + 1);
1990 __ Ret(); 2195 __ Ret();
1991 } 2196 }
1992 2197
1993 __ bind(&miss); 2198 __ bind(&miss);
1994 // Restore function name in a2. 2199 // Restore function name in a2.
1995 __ li(a2, Handle<String>(name)); 2200 __ li(a2, Handle<String>(name));
1996 __ bind(&name_miss); 2201 __ bind(&name_miss);
1997 MaybeObject* maybe_result = GenerateMissBranch(); 2202 MaybeObject* maybe_result = TryGenerateMissBranch();
1998 if (maybe_result->IsFailure()) return maybe_result; 2203 if (maybe_result->IsFailure()) return maybe_result;
1999 2204
2000 // Return the generated code. 2205 // Return the generated code.
2001 return GetCode(function); 2206 return TryGetCode(function);
2002 } 2207 }
2003 2208
2004 2209
2005 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( 2210 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall(
2006 Object* object, 2211 Object* object,
2007 JSObject* holder, 2212 JSObject* holder,
2008 JSGlobalPropertyCell* cell, 2213 JSGlobalPropertyCell* cell,
2009 JSFunction* function, 2214 JSFunction* function,
2010 String* name) { 2215 String* name) {
2011 // ----------- S t a t e ------------- 2216 // ----------- S t a t e -------------
2012 // -- a2 : function name 2217 // -- a2 : function name
2013 // -- ra : return address 2218 // -- ra : return address
2014 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 2219 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2015 // -- ... 2220 // -- ...
2016 // -- sp[argc * 4] : receiver 2221 // -- sp[argc * 4] : receiver
2017 // ----------------------------------- 2222 // -----------------------------------
2018 2223
2019 const int argc = arguments().immediate(); 2224 const int argc = arguments().immediate();
2020 2225
2021 // If the object is not a JSObject or we got an unexpected number of 2226 // If the object is not a JSObject or we got an unexpected number of
2022 // arguments, bail out to the regular call. 2227 // arguments, bail out to the regular call.
2023 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); 2228 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value();
2024 2229
2025 Label miss; 2230 Label miss;
2026 GenerateNameCheck(name, &miss); 2231 GenerateNameCheck(Handle<String>(name), &miss);
2027 2232
2028 if (cell == NULL) { 2233 if (cell == NULL) {
2029 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); 2234 __ lw(a1, MemOperand(sp, 1 * kPointerSize));
2030 2235
2031 STATIC_ASSERT(kSmiTag == 0); 2236 STATIC_ASSERT(kSmiTag == 0);
2032 __ JumpIfSmi(a1, &miss); 2237 __ JumpIfSmi(a1, &miss);
2033 2238
2034 CheckPrototypes(JSObject::cast(object), a1, holder, v0, a3, t0, name, 2239 CheckPrototypes(JSObject::cast(object), a1, holder, v0, a3, t0, name,
2035 &miss); 2240 &miss);
2036 } else { 2241 } else {
(...skipping 22 matching lines...) Expand all
2059 StubRuntimeCallHelper call_helper; 2264 StubRuntimeCallHelper call_helper;
2060 char_from_code_generator.GenerateSlow(masm(), call_helper); 2265 char_from_code_generator.GenerateSlow(masm(), call_helper);
2061 2266
2062 // Tail call the full function. We do not have to patch the receiver 2267 // Tail call the full function. We do not have to patch the receiver
2063 // because the function makes no use of it. 2268 // because the function makes no use of it.
2064 __ bind(&slow); 2269 __ bind(&slow);
2065 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); 2270 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD);
2066 2271
2067 __ bind(&miss); 2272 __ bind(&miss);
2068 // a2: function name. 2273 // a2: function name.
2069 MaybeObject* maybe_result = GenerateMissBranch(); 2274 MaybeObject* maybe_result = TryGenerateMissBranch();
2070 if (maybe_result->IsFailure()) return maybe_result; 2275 if (maybe_result->IsFailure()) return maybe_result;
2071 2276
2072 // Return the generated code. 2277 // Return the generated code.
2073 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); 2278 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name);
2074 } 2279 }
2075 2280
2076 2281
2077 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, 2282 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object,
2078 JSObject* holder, 2283 JSObject* holder,
2079 JSGlobalPropertyCell* cell, 2284 JSGlobalPropertyCell* cell,
2080 JSFunction* function, 2285 JSFunction* function,
2081 String* name) { 2286 String* name) {
2082 // ----------- S t a t e ------------- 2287 // ----------- S t a t e -------------
2083 // -- a2 : function name 2288 // -- a2 : function name
2084 // -- ra : return address 2289 // -- ra : return address
2085 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 2290 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2086 // -- ... 2291 // -- ...
2087 // -- sp[argc * 4] : receiver 2292 // -- sp[argc * 4] : receiver
2088 // ----------------------------------- 2293 // -----------------------------------
2089 2294
2090 if (!CpuFeatures::IsSupported(FPU)) 2295 if (!CpuFeatures::IsSupported(FPU))
2091 return heap()->undefined_value(); 2296 return heap()->undefined_value();
2092 CpuFeatures::Scope scope_fpu(FPU); 2297 CpuFeatures::Scope scope_fpu(FPU);
2093 2298
2094 const int argc = arguments().immediate(); 2299 const int argc = arguments().immediate();
2095 2300
2096 // If the object is not a JSObject or we got an unexpected number of 2301 // If the object is not a JSObject or we got an unexpected number of
2097 // arguments, bail out to the regular call. 2302 // arguments, bail out to the regular call.
2098 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); 2303 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value();
2099 2304
2100 Label miss, slow; 2305 Label miss, slow;
2101 GenerateNameCheck(name, &miss); 2306 GenerateNameCheck(Handle<String>(name), &miss);
2102 2307
2103 if (cell == NULL) { 2308 if (cell == NULL) {
2104 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); 2309 __ lw(a1, MemOperand(sp, 1 * kPointerSize));
2105 2310
2106 STATIC_ASSERT(kSmiTag == 0); 2311 STATIC_ASSERT(kSmiTag == 0);
2107 __ JumpIfSmi(a1, &miss); 2312 __ JumpIfSmi(a1, &miss);
2108 2313
2109 CheckPrototypes(JSObject::cast(object), a1, holder, a0, a3, t0, name, 2314 CheckPrototypes(JSObject::cast(object), a1, holder, a0, a3, t0, name,
2110 &miss); 2315 &miss);
2111 } else { 2316 } else {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2193 // Restore FCSR and fall to slow case. 2398 // Restore FCSR and fall to slow case.
2194 __ ctc1(a3, FCSR); 2399 __ ctc1(a3, FCSR);
2195 2400
2196 __ bind(&slow); 2401 __ bind(&slow);
2197 // Tail call the full function. We do not have to patch the receiver 2402 // Tail call the full function. We do not have to patch the receiver
2198 // because the function makes no use of it. 2403 // because the function makes no use of it.
2199 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); 2404 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD);
2200 2405
2201 __ bind(&miss); 2406 __ bind(&miss);
2202 // a2: function name. 2407 // a2: function name.
2203 MaybeObject* obj = GenerateMissBranch(); 2408 MaybeObject* obj = TryGenerateMissBranch();
2204 if (obj->IsFailure()) return obj; 2409 if (obj->IsFailure()) return obj;
2205 2410
2206 // Return the generated code. 2411 // Return the generated code.
2207 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); 2412 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name);
2208 } 2413 }
2209 2414
2210 2415
2211 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, 2416 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object,
2212 JSObject* holder, 2417 JSObject* holder,
2213 JSGlobalPropertyCell* cell, 2418 JSGlobalPropertyCell* cell,
2214 JSFunction* function, 2419 JSFunction* function,
2215 String* name) { 2420 String* name) {
2216 // ----------- S t a t e ------------- 2421 // ----------- S t a t e -------------
2217 // -- a2 : function name 2422 // -- a2 : function name
2218 // -- ra : return address 2423 // -- ra : return address
2219 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) 2424 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
2220 // -- ... 2425 // -- ...
2221 // -- sp[argc * 4] : receiver 2426 // -- sp[argc * 4] : receiver
2222 // ----------------------------------- 2427 // -----------------------------------
2223 2428
2224 const int argc = arguments().immediate(); 2429 const int argc = arguments().immediate();
2225 2430
2226 // If the object is not a JSObject or we got an unexpected number of 2431 // If the object is not a JSObject or we got an unexpected number of
2227 // arguments, bail out to the regular call. 2432 // arguments, bail out to the regular call.
2228 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); 2433 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value();
2229 2434
2230 Label miss; 2435 Label miss;
2231 GenerateNameCheck(name, &miss); 2436 GenerateNameCheck(Handle<String>(name), &miss);
2232 2437
2233 if (cell == NULL) { 2438 if (cell == NULL) {
2234 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); 2439 __ lw(a1, MemOperand(sp, 1 * kPointerSize));
2235 2440
2236 STATIC_ASSERT(kSmiTag == 0); 2441 STATIC_ASSERT(kSmiTag == 0);
2237 __ JumpIfSmi(a1, &miss); 2442 __ JumpIfSmi(a1, &miss);
2238 2443
2239 CheckPrototypes(JSObject::cast(object), a1, holder, v0, a3, t0, name, 2444 CheckPrototypes(JSObject::cast(object), a1, holder, v0, a3, t0, name,
2240 &miss); 2445 &miss);
2241 } else { 2446 } else {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2295 __ Drop(argc + 1); 2500 __ Drop(argc + 1);
2296 __ Ret(); 2501 __ Ret();
2297 2502
2298 // Tail call the full function. We do not have to patch the receiver 2503 // Tail call the full function. We do not have to patch the receiver
2299 // because the function makes no use of it. 2504 // because the function makes no use of it.
2300 __ bind(&slow); 2505 __ bind(&slow);
2301 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); 2506 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD);
2302 2507
2303 __ bind(&miss); 2508 __ bind(&miss);
2304 // a2: function name. 2509 // a2: function name.
2305 MaybeObject* maybe_result = GenerateMissBranch(); 2510 MaybeObject* maybe_result = TryGenerateMissBranch();
2306 if (maybe_result->IsFailure()) return maybe_result; 2511 if (maybe_result->IsFailure()) return maybe_result;
2307 2512
2308 // Return the generated code. 2513 // Return the generated code.
2309 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); 2514 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name);
2310 } 2515 }
2311 2516
2312 2517
2313 MaybeObject* CallStubCompiler::CompileFastApiCall( 2518 MaybeObject* CallStubCompiler::CompileFastApiCall(
2314 const CallOptimization& optimization, 2519 const CallOptimization& optimization,
2315 Object* object, 2520 Object* object,
2316 JSObject* holder, 2521 JSObject* holder,
2317 JSGlobalPropertyCell* cell, 2522 JSGlobalPropertyCell* cell,
2318 JSFunction* function, 2523 JSFunction* function,
2319 String* name) { 2524 String* name) {
2320 2525
2321 Counters* counters = isolate()->counters(); 2526 Counters* counters = isolate()->counters();
2322 2527
2323 ASSERT(optimization.is_simple_api_call()); 2528 ASSERT(optimization.is_simple_api_call());
2324 // Bail out if object is a global object as we don't want to 2529 // Bail out if object is a global object as we don't want to
2325 // repatch it to global receiver. 2530 // repatch it to global receiver.
2326 if (object->IsGlobalObject()) return heap()->undefined_value(); 2531 if (object->IsGlobalObject()) return heap()->undefined_value();
2327 if (cell != NULL) return heap()->undefined_value(); 2532 if (cell != NULL) return heap()->undefined_value();
2328 if (!object->IsJSObject()) return heap()->undefined_value(); 2533 if (!object->IsJSObject()) return heap()->undefined_value();
2329 int depth = optimization.GetPrototypeDepthOfExpectedType( 2534 int depth = optimization.GetPrototypeDepthOfExpectedType(
2330 JSObject::cast(object), holder); 2535 JSObject::cast(object), holder);
2331 if (depth == kInvalidProtoDepth) return heap()->undefined_value(); 2536 if (depth == kInvalidProtoDepth) return heap()->undefined_value();
2332 2537
2333 Label miss, miss_before_stack_reserved; 2538 Label miss, miss_before_stack_reserved;
2334 2539
2335 GenerateNameCheck(name, &miss_before_stack_reserved); 2540 GenerateNameCheck(Handle<String>(name), &miss_before_stack_reserved);
2336 2541
2337 // Get the receiver from the stack. 2542 // Get the receiver from the stack.
2338 const int argc = arguments().immediate(); 2543 const int argc = arguments().immediate();
2339 __ lw(a1, MemOperand(sp, argc * kPointerSize)); 2544 __ lw(a1, MemOperand(sp, argc * kPointerSize));
2340 2545
2341 // Check that the receiver isn't a smi. 2546 // Check that the receiver isn't a smi.
2342 __ JumpIfSmi(a1, &miss_before_stack_reserved); 2547 __ JumpIfSmi(a1, &miss_before_stack_reserved);
2343 2548
2344 __ IncrementCounter(counters->call_const(), 1, a0, a3); 2549 __ IncrementCounter(counters->call_const(), 1, a0, a3);
2345 __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a3); 2550 __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a3);
2346 2551
2347 ReserveSpaceForFastApiCall(masm(), a0); 2552 ReserveSpaceForFastApiCall(masm(), a0);
2348 2553
2349 // Check that the maps haven't changed and find a Holder as a side effect. 2554 // Check that the maps haven't changed and find a Holder as a side effect.
2350 CheckPrototypes(JSObject::cast(object), a1, holder, a0, a3, t0, name, 2555 CheckPrototypes(JSObject::cast(object), a1, holder, a0, a3, t0, name,
2351 depth, &miss); 2556 depth, &miss);
2352 2557
2353 MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); 2558 MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc);
2354 if (result->IsFailure()) return result; 2559 if (result->IsFailure()) return result;
2355 2560
2356 __ bind(&miss); 2561 __ bind(&miss);
2357 FreeSpaceForFastApiCall(masm()); 2562 FreeSpaceForFastApiCall(masm());
2358 2563
2359 __ bind(&miss_before_stack_reserved); 2564 __ bind(&miss_before_stack_reserved);
2360 MaybeObject* maybe_result = GenerateMissBranch(); 2565 MaybeObject* maybe_result = TryGenerateMissBranch();
2361 if (maybe_result->IsFailure()) return maybe_result; 2566 if (maybe_result->IsFailure()) return maybe_result;
2362 2567
2363 // Return the generated code. 2568 // Return the generated code.
2364 return GetCode(function); 2569 return TryGetCode(function);
2365 } 2570 }
2366 2571
2367 2572
2368 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, 2573 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object,
2369 JSObject* holder, 2574 JSObject* holder,
2370 JSFunction* function, 2575 JSFunction* function,
2371 String* name, 2576 String* name,
2372 CheckType check) { 2577 CheckType check) {
2373 // ----------- S t a t e ------------- 2578 // ----------- S t a t e -------------
2374 // -- a2 : name 2579 // -- a2 : name
2375 // -- ra : return address 2580 // -- ra : return address
2376 // ----------------------------------- 2581 // -----------------------------------
2377 if (HasCustomCallGenerator(function)) { 2582 if (HasCustomCallGenerator(function)) {
2378 MaybeObject* maybe_result = CompileCustomCall( 2583 MaybeObject* maybe_result = CompileCustomCall(
2379 object, holder, NULL, function, name); 2584 object, holder, NULL, function, name);
2380 Object* result; 2585 Object* result;
2381 if (!maybe_result->ToObject(&result)) return maybe_result; 2586 if (!maybe_result->ToObject(&result)) return maybe_result;
2382 // Undefined means bail out to regular compiler. 2587 // Undefined means bail out to regular compiler.
2383 if (!result->IsUndefined()) return result; 2588 if (!result->IsUndefined()) return result;
2384 } 2589 }
2385 2590
2386 Label miss; 2591 Label miss;
2387 2592
2388 GenerateNameCheck(name, &miss); 2593 GenerateNameCheck(Handle<String>(name), &miss);
2389 2594
2390 // Get the receiver from the stack. 2595 // Get the receiver from the stack.
2391 const int argc = arguments().immediate(); 2596 const int argc = arguments().immediate();
2392 __ lw(a1, MemOperand(sp, argc * kPointerSize)); 2597 __ lw(a1, MemOperand(sp, argc * kPointerSize));
2393 2598
2394 // Check that the receiver isn't a smi. 2599 // Check that the receiver isn't a smi.
2395 if (check != NUMBER_CHECK) { 2600 if (check != NUMBER_CHECK) {
2396 __ And(t1, a1, Operand(kSmiTagMask)); 2601 __ And(t1, a1, Operand(kSmiTagMask));
2397 __ Branch(&miss, eq, t1, Operand(zero_reg)); 2602 __ Branch(&miss, eq, t1, Operand(zero_reg));
2398 } 2603 }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
2477 CheckPrototypes(JSObject::cast(object->GetPrototype()), a0, holder, a3, 2682 CheckPrototypes(JSObject::cast(object->GetPrototype()), a0, holder, a3,
2478 a1, t0, name, &miss); 2683 a1, t0, name, &miss);
2479 } 2684 }
2480 break; 2685 break;
2481 } 2686 }
2482 2687
2483 default: 2688 default:
2484 UNREACHABLE(); 2689 UNREACHABLE();
2485 } 2690 }
2486 2691
2487 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) 2692 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2488 ? CALL_AS_FUNCTION 2693 ? CALL_AS_FUNCTION
2489 : CALL_AS_METHOD; 2694 : CALL_AS_METHOD;
2490 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind); 2695 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind);
2491 2696
2492 // Handle call cache miss. 2697 // Handle call cache miss.
2493 __ bind(&miss); 2698 __ bind(&miss);
2494 2699
2495 MaybeObject* maybe_result = GenerateMissBranch(); 2700 MaybeObject* maybe_result = TryGenerateMissBranch();
2496 if (maybe_result->IsFailure()) return maybe_result; 2701 if (maybe_result->IsFailure()) return maybe_result;
2497 2702
2498 // Return the generated code. 2703 // Return the generated code.
2499 return GetCode(function); 2704 return TryGetCode(function);
2500 } 2705 }
2501 2706
2502 2707
2503 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, 2708 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object,
2504 JSObject* holder, 2709 JSObject* holder,
2505 String* name) { 2710 String* name) {
2506 // ----------- S t a t e ------------- 2711 // ----------- S t a t e -------------
2507 // -- a2 : name 2712 // -- a2 : name
2508 // -- ra : return address 2713 // -- ra : return address
2509 // ----------------------------------- 2714 // -----------------------------------
2510 2715
2511 Label miss; 2716 Label miss;
2512 2717
2513 GenerateNameCheck(name, &miss); 2718 GenerateNameCheck(Handle<String>(name), &miss);
2514 2719
2515 // Get the number of arguments. 2720 // Get the number of arguments.
2516 const int argc = arguments().immediate(); 2721 const int argc = arguments().immediate();
2517 2722
2518 LookupResult lookup; 2723 LookupResult lookup(isolate());
2519 LookupPostInterceptor(holder, name, &lookup); 2724 LookupPostInterceptor(holder, name, &lookup);
2520 2725
2521 // Get the receiver from the stack. 2726 // Get the receiver from the stack.
2522 __ lw(a1, MemOperand(sp, argc * kPointerSize)); 2727 __ lw(a1, MemOperand(sp, argc * kPointerSize));
2523 2728
2524 CallInterceptorCompiler compiler(this, arguments(), a2, extra_ic_state_); 2729 CallInterceptorCompiler compiler(this, arguments(), a2, extra_state_);
2525 MaybeObject* result = compiler.Compile(masm(), 2730 MaybeObject* result = compiler.Compile(masm(),
2526 object, 2731 object,
2527 holder, 2732 holder,
2528 name, 2733 name,
2529 &lookup, 2734 &lookup,
2530 a1, 2735 a1,
2531 a3, 2736 a3,
2532 t0, 2737 t0,
2533 a0, 2738 a0,
2534 &miss); 2739 &miss);
2535 if (result->IsFailure()) { 2740 if (result->IsFailure()) {
2536 return result; 2741 return result;
2537 } 2742 }
2538 2743
2539 // Move returned value, the function to call, to a1. 2744 // Move returned value, the function to call, to a1.
2540 __ mov(a1, v0); 2745 __ mov(a1, v0);
2541 // Restore receiver. 2746 // Restore receiver.
2542 __ lw(a0, MemOperand(sp, argc * kPointerSize)); 2747 __ lw(a0, MemOperand(sp, argc * kPointerSize));
2543 2748
2544 GenerateCallFunction(masm(), object, arguments(), &miss, extra_ic_state_); 2749 GenerateCallFunction(masm(), Handle<Object>(object), arguments(), &miss,
2750 extra_state_);
2545 2751
2546 // Handle call cache miss. 2752 // Handle call cache miss.
2547 __ bind(&miss); 2753 __ bind(&miss);
2548 MaybeObject* maybe_result = GenerateMissBranch(); 2754 MaybeObject* maybe_result = TryGenerateMissBranch();
2549 if (maybe_result->IsFailure()) return maybe_result; 2755 if (maybe_result->IsFailure()) return maybe_result;
2550 2756
2551 // Return the generated code. 2757 // Return the generated code.
2552 return GetCode(INTERCEPTOR, name); 2758 return TryGetCode(INTERCEPTOR, name);
2553 } 2759 }
2554 2760
2555 2761
2556 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, 2762 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object,
2557 GlobalObject* holder, 2763 GlobalObject* holder,
2558 JSGlobalPropertyCell* cell, 2764 JSGlobalPropertyCell* cell,
2559 JSFunction* function, 2765 JSFunction* function,
2560 String* name) { 2766 String* name) {
2561 // ----------- S t a t e ------------- 2767 // ----------- S t a t e -------------
2562 // -- a2 : name 2768 // -- a2 : name
2563 // -- ra : return address 2769 // -- ra : return address
2564 // ----------------------------------- 2770 // -----------------------------------
2565 2771
2566 if (HasCustomCallGenerator(function)) { 2772 if (HasCustomCallGenerator(function)) {
2567 MaybeObject* maybe_result = CompileCustomCall( 2773 MaybeObject* maybe_result = CompileCustomCall(
2568 object, holder, cell, function, name); 2774 object, holder, cell, function, name);
2569 Object* result; 2775 Object* result;
2570 if (!maybe_result->ToObject(&result)) return maybe_result; 2776 if (!maybe_result->ToObject(&result)) return maybe_result;
2571 // Undefined means bail out to regular compiler. 2777 // Undefined means bail out to regular compiler.
2572 if (!result->IsUndefined()) return result; 2778 if (!result->IsUndefined()) return result;
2573 } 2779 }
2574 2780
2575 Label miss; 2781 Label miss;
2576 2782
2577 GenerateNameCheck(name, &miss); 2783 GenerateNameCheck(Handle<String>(name), &miss);
2578 2784
2579 // Get the number of arguments. 2785 // Get the number of arguments.
2580 const int argc = arguments().immediate(); 2786 const int argc = arguments().immediate();
2581 2787
2582 GenerateGlobalReceiverCheck(object, holder, name, &miss); 2788 GenerateGlobalReceiverCheck(object, holder, name, &miss);
2583 GenerateLoadFunctionFromCell(cell, function, &miss); 2789 GenerateLoadFunctionFromCell(cell, function, &miss);
2584 2790
2585 // Patch the receiver on the stack with the global proxy if 2791 // Patch the receiver on the stack with the global proxy if
2586 // necessary. 2792 // necessary.
2587 if (object->IsGlobalObject()) { 2793 if (object->IsGlobalObject()) {
2588 __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset)); 2794 __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset));
2589 __ sw(a3, MemOperand(sp, argc * kPointerSize)); 2795 __ sw(a3, MemOperand(sp, argc * kPointerSize));
2590 } 2796 }
2591 2797
2592 // Setup the context (function already in r1). 2798 // Setup the context (function already in r1).
2593 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); 2799 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
2594 2800
2595 // Jump to the cached code (tail call). 2801 // Jump to the cached code (tail call).
2596 Counters* counters = masm()->isolate()->counters(); 2802 Counters* counters = masm()->isolate()->counters();
2597 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); 2803 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0);
2598 ASSERT(function->is_compiled());
2599 Handle<Code> code(function->code()); 2804 Handle<Code> code(function->code());
2600 ParameterCount expected(function->shared()->formal_parameter_count()); 2805 ParameterCount expected(function->shared()->formal_parameter_count());
2601 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) 2806 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2602 ? CALL_AS_FUNCTION 2807 ? CALL_AS_FUNCTION
2603 : CALL_AS_METHOD; 2808 : CALL_AS_METHOD;
2604 if (V8::UseCrankshaft()) { 2809 // We call indirectly through the code field in the function to
2605 // TODO(kasperl): For now, we always call indirectly through the 2810 // allow recompilation to take effect without changing any of the
2606 // code field in the function to allow recompilation to take effect 2811 // call sites.
2607 // without changing any of the call sites. 2812 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
2608 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); 2813 __ InvokeCode(a3, expected, arguments(), JUMP_FUNCTION,
2609 __ InvokeCode(a3, expected, arguments(), JUMP_FUNCTION, 2814 NullCallWrapper(), call_kind);
2610 NullCallWrapper(), call_kind);
2611 } else {
2612 __ InvokeCode(code, expected, arguments(), RelocInfo::CODE_TARGET,
2613 JUMP_FUNCTION, call_kind);
2614 }
2615 2815
2616 // Handle call cache miss. 2816 // Handle call cache miss.
2617 __ bind(&miss); 2817 __ bind(&miss);
2618 __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3); 2818 __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3);
2619 MaybeObject* maybe_result = GenerateMissBranch(); 2819 MaybeObject* maybe_result = TryGenerateMissBranch();
2620 if (maybe_result->IsFailure()) return maybe_result; 2820 if (maybe_result->IsFailure()) return maybe_result;
2621 2821
2622 // Return the generated code. 2822 // Return the generated code.
2623 return GetCode(NORMAL, name); 2823 return TryGetCode(NORMAL, name);
2624 } 2824 }
2625 2825
2626 2826
2627 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, 2827 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object,
2628 int index, 2828 int index,
2629 Map* transition, 2829 Map* transition,
2630 String* name) { 2830 String* name) {
2631 // ----------- S t a t e ------------- 2831 // ----------- S t a t e -------------
2632 // -- a0 : value 2832 // -- a0 : value
2633 // -- a1 : receiver 2833 // -- a1 : receiver
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
2792 __ bind(&miss); 2992 __ bind(&miss);
2793 __ IncrementCounter(counters->named_store_global_inline_miss(), 1, a1, a3); 2993 __ IncrementCounter(counters->named_store_global_inline_miss(), 1, a1, a3);
2794 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); 2994 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
2795 __ Jump(ic, RelocInfo::CODE_TARGET); 2995 __ Jump(ic, RelocInfo::CODE_TARGET);
2796 2996
2797 // Return the generated code. 2997 // Return the generated code.
2798 return GetCode(NORMAL, name); 2998 return GetCode(NORMAL, name);
2799 } 2999 }
2800 3000
2801 3001
2802 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, 3002 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<String> name,
2803 JSObject* object, 3003 Handle<JSObject> object,
2804 JSObject* last) { 3004 Handle<JSObject> last) {
2805 // ----------- S t a t e ------------- 3005 // ----------- S t a t e -------------
2806 // -- a0 : receiver 3006 // -- a0 : receiver
2807 // -- ra : return address 3007 // -- ra : return address
2808 // ----------------------------------- 3008 // -----------------------------------
2809 Label miss; 3009 Label miss;
2810 3010
2811 // Check that the receiver is not a smi. 3011 // Check that the receiver is not a smi.
2812 __ JumpIfSmi(a0, &miss); 3012 __ JumpIfSmi(a0, &miss);
2813 3013
2814 // Check the maps of the full prototype chain. 3014 // Check the maps of the full prototype chain.
2815 CheckPrototypes(object, a0, last, a3, a1, t0, name, &miss); 3015 CheckPrototypes(object, a0, last, a3, a1, t0, name, &miss);
2816 3016
2817 // If the last object in the prototype chain is a global object, 3017 // If the last object in the prototype chain is a global object,
2818 // check that the global property cell is empty. 3018 // check that the global property cell is empty.
2819 if (last->IsGlobalObject()) { 3019 if (last->IsGlobalObject()) {
2820 MaybeObject* cell = GenerateCheckPropertyCell(masm(), 3020 GenerateCheckPropertyCell(
2821 GlobalObject::cast(last), 3021 masm(), Handle<GlobalObject>::cast(last), name, a1, &miss);
2822 name,
2823 a1,
2824 &miss);
2825 if (cell->IsFailure()) {
2826 miss.Unuse();
2827 return cell;
2828 }
2829 } 3022 }
2830 3023
2831 // Return undefined if maps of the full prototype chain is still the same. 3024 // Return undefined if maps of the full prototype chain is still the same.
2832 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); 3025 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
2833 __ Ret(); 3026 __ Ret();
2834 3027
2835 __ bind(&miss); 3028 __ bind(&miss);
2836 GenerateLoadMiss(masm(), Code::LOAD_IC); 3029 GenerateLoadMiss(masm(), Code::LOAD_IC);
2837 3030
2838 // Return the generated code. 3031 // Return the generated code.
2839 return GetCode(NONEXISTENT, heap()->empty_string()); 3032 return GetCode(NONEXISTENT, factory()->empty_string());
2840 } 3033 }
2841 3034
2842 3035
2843 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object, 3036 Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object,
2844 JSObject* holder, 3037 Handle<JSObject> holder,
2845 int index, 3038 int index,
2846 String* name) { 3039 Handle<String> name) {
2847 // ----------- S t a t e ------------- 3040 // ----------- S t a t e -------------
2848 // -- a0 : receiver 3041 // -- a0 : receiver
2849 // -- a2 : name 3042 // -- a2 : name
2850 // -- ra : return address 3043 // -- ra : return address
2851 // ----------------------------------- 3044 // -----------------------------------
2852 Label miss; 3045 Label miss;
2853 3046
2854 __ mov(v0, a0); 3047 __ mov(v0, a0);
2855 3048
2856 GenerateLoadField(object, holder, v0, a3, a1, t0, index, name, &miss); 3049 GenerateLoadField(object, holder, v0, a3, a1, t0, index, name, &miss);
(...skipping 20 matching lines...) Expand all
2877 callback, name, &miss); 3070 callback, name, &miss);
2878 if (result->IsFailure()) { 3071 if (result->IsFailure()) {
2879 miss.Unuse(); 3072 miss.Unuse();
2880 return result; 3073 return result;
2881 } 3074 }
2882 3075
2883 __ bind(&miss); 3076 __ bind(&miss);
2884 GenerateLoadMiss(masm(), Code::LOAD_IC); 3077 GenerateLoadMiss(masm(), Code::LOAD_IC);
2885 3078
2886 // Return the generated code. 3079 // Return the generated code.
2887 return GetCode(CALLBACKS, name); 3080 return TryGetCode(CALLBACKS, name);
2888 } 3081 }
2889 3082
2890 3083
2891 MaybeObject* LoadStubCompiler::CompileLoadConstant(JSObject* object, 3084 Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object,
2892 JSObject* holder, 3085 Handle<JSObject> holder,
2893 Object* value, 3086 Handle<Object> value,
2894 String* name) { 3087 Handle<String> name) {
2895 // ----------- S t a t e ------------- 3088 // ----------- S t a t e -------------
2896 // -- a0 : receiver 3089 // -- a0 : receiver
2897 // -- a2 : name 3090 // -- a2 : name
2898 // -- ra : return address 3091 // -- ra : return address
2899 // ----------------------------------- 3092 // -----------------------------------
2900 Label miss; 3093 Label miss;
2901 3094
2902 GenerateLoadConstant(object, holder, a0, a3, a1, t0, value, name, &miss); 3095 GenerateLoadConstant(object, holder, a0, a3, a1, t0, value, name, &miss);
2903 __ bind(&miss); 3096 __ bind(&miss);
2904 GenerateLoadMiss(masm(), Code::LOAD_IC); 3097 GenerateLoadMiss(masm(), Code::LOAD_IC);
2905 3098
2906 // Return the generated code. 3099 // Return the generated code.
2907 return GetCode(CONSTANT_FUNCTION, name); 3100 return GetCode(CONSTANT_FUNCTION, name);
2908 } 3101 }
2909 3102
2910 3103
2911 MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* object, 3104 MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* object,
2912 JSObject* holder, 3105 JSObject* holder,
2913 String* name) { 3106 String* name) {
2914 // ----------- S t a t e ------------- 3107 // ----------- S t a t e -------------
2915 // -- a0 : receiver 3108 // -- a0 : receiver
2916 // -- a2 : name 3109 // -- a2 : name
2917 // -- ra : return address 3110 // -- ra : return address
2918 // -- [sp] : receiver 3111 // -- [sp] : receiver
2919 // ----------------------------------- 3112 // -----------------------------------
2920 Label miss; 3113 Label miss;
2921 3114
2922 LookupResult lookup; 3115 LookupResult lookup(isolate());
2923 LookupPostInterceptor(holder, name, &lookup); 3116 LookupPostInterceptor(holder, name, &lookup);
2924 GenerateLoadInterceptor(object, 3117 GenerateLoadInterceptor(object,
2925 holder, 3118 holder,
2926 &lookup, 3119 &lookup,
2927 a0, 3120 a0,
2928 a2, 3121 a2,
2929 a3, 3122 a3,
2930 a1, 3123 a1,
2931 t0, 3124 t0,
2932 name, 3125 name,
2933 &miss); 3126 &miss);
2934 __ bind(&miss); 3127 __ bind(&miss);
2935 GenerateLoadMiss(masm(), Code::LOAD_IC); 3128 GenerateLoadMiss(masm(), Code::LOAD_IC);
2936 3129
2937 // Return the generated code. 3130 // Return the generated code.
2938 return GetCode(INTERCEPTOR, name); 3131 return TryGetCode(INTERCEPTOR, name);
2939 } 3132 }
2940 3133
2941 3134
2942 MaybeObject* LoadStubCompiler::CompileLoadGlobal(JSObject* object, 3135 MaybeObject* LoadStubCompiler::CompileLoadGlobal(JSObject* object,
2943 GlobalObject* holder, 3136 GlobalObject* holder,
2944 JSGlobalPropertyCell* cell, 3137 JSGlobalPropertyCell* cell,
2945 String* name, 3138 String* name,
2946 bool is_dont_delete) { 3139 bool is_dont_delete) {
2947 // ----------- S t a t e ------------- 3140 // ----------- S t a t e -------------
2948 // -- a0 : receiver 3141 // -- a0 : receiver
(...skipping 26 matching lines...) Expand all
2975 __ mov(v0, t0); 3168 __ mov(v0, t0);
2976 Counters* counters = masm()->isolate()->counters(); 3169 Counters* counters = masm()->isolate()->counters();
2977 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); 3170 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3);
2978 __ Ret(); 3171 __ Ret();
2979 3172
2980 __ bind(&miss); 3173 __ bind(&miss);
2981 __ IncrementCounter(counters->named_load_global_stub_miss(), 1, a1, a3); 3174 __ IncrementCounter(counters->named_load_global_stub_miss(), 1, a1, a3);
2982 GenerateLoadMiss(masm(), Code::LOAD_IC); 3175 GenerateLoadMiss(masm(), Code::LOAD_IC);
2983 3176
2984 // Return the generated code. 3177 // Return the generated code.
2985 return GetCode(NORMAL, name); 3178 return TryGetCode(NORMAL, name);
2986 } 3179 }
2987 3180
2988 3181
2989 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, 3182 Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name,
2990 JSObject* receiver, 3183 Handle<JSObject> receiver,
2991 JSObject* holder, 3184 Handle<JSObject> holder,
2992 int index) { 3185 int index) {
2993 // ----------- S t a t e ------------- 3186 // ----------- S t a t e -------------
2994 // -- ra : return address 3187 // -- ra : return address
2995 // -- a0 : key 3188 // -- a0 : key
2996 // -- a1 : receiver 3189 // -- a1 : receiver
2997 // ----------------------------------- 3190 // -----------------------------------
2998 Label miss; 3191 Label miss;
2999 3192
3000 // Check the key is the cached one. 3193 // Check the key is the cached one.
3001 __ Branch(&miss, ne, a0, Operand(Handle<String>(name))); 3194 __ Branch(&miss, ne, a0, Operand(name));
3002 3195
3003 GenerateLoadField(receiver, holder, a1, a2, a3, t0, index, name, &miss); 3196 GenerateLoadField(receiver, holder, a1, a2, a3, t0, index, name, &miss);
3004 __ bind(&miss); 3197 __ bind(&miss);
3005 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3198 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3006 3199
3007 return GetCode(FIELD, name); 3200 return GetCode(FIELD, name);
3008 } 3201 }
3009 3202
3010 3203
3011 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback( 3204 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback(
(...skipping 14 matching lines...) Expand all
3026 MaybeObject* result = GenerateLoadCallback(receiver, holder, a1, a0, a2, a3, 3219 MaybeObject* result = GenerateLoadCallback(receiver, holder, a1, a0, a2, a3,
3027 t0, callback, name, &miss); 3220 t0, callback, name, &miss);
3028 if (result->IsFailure()) { 3221 if (result->IsFailure()) {
3029 miss.Unuse(); 3222 miss.Unuse();
3030 return result; 3223 return result;
3031 } 3224 }
3032 3225
3033 __ bind(&miss); 3226 __ bind(&miss);
3034 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3227 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3035 3228
3036 return GetCode(CALLBACKS, name); 3229 return TryGetCode(CALLBACKS, name);
3037 } 3230 }
3038 3231
3039 3232
3040 MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name, 3233 Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant(
3041 JSObject* receiver, 3234 Handle<String> name,
3042 JSObject* holder, 3235 Handle<JSObject> receiver,
3043 Object* value) { 3236 Handle<JSObject> holder,
3237 Handle<Object> value) {
3044 // ----------- S t a t e ------------- 3238 // ----------- S t a t e -------------
3045 // -- ra : return address 3239 // -- ra : return address
3046 // -- a0 : key 3240 // -- a0 : key
3047 // -- a1 : receiver 3241 // -- a1 : receiver
3048 // ----------------------------------- 3242 // -----------------------------------
3049 Label miss; 3243 Label miss;
3050 3244
3051 // Check the key is the cached one. 3245 // Check the key is the cached one.
3052 __ Branch(&miss, ne, a0, Operand(Handle<String>(name))); 3246 __ Branch(&miss, ne, a0, Operand(name));
3053 3247
3054 GenerateLoadConstant(receiver, holder, a1, a2, a3, t0, value, name, &miss); 3248 GenerateLoadConstant(receiver, holder, a1, a2, a3, t0, value, name, &miss);
3055 __ bind(&miss); 3249 __ bind(&miss);
3056 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3250 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3057 3251
3058 // Return the generated code. 3252 // Return the generated code.
3059 return GetCode(CONSTANT_FUNCTION, name); 3253 return GetCode(CONSTANT_FUNCTION, name);
3060 } 3254 }
3061 3255
3062 3256
3063 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, 3257 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
3064 JSObject* holder, 3258 JSObject* holder,
3065 String* name) { 3259 String* name) {
3066 // ----------- S t a t e ------------- 3260 // ----------- S t a t e -------------
3067 // -- ra : return address 3261 // -- ra : return address
3068 // -- a0 : key 3262 // -- a0 : key
3069 // -- a1 : receiver 3263 // -- a1 : receiver
3070 // ----------------------------------- 3264 // -----------------------------------
3071 Label miss; 3265 Label miss;
3072 3266
3073 // Check the key is the cached one. 3267 // Check the key is the cached one.
3074 __ Branch(&miss, ne, a0, Operand(Handle<String>(name))); 3268 __ Branch(&miss, ne, a0, Operand(Handle<String>(name)));
3075 3269
3076 LookupResult lookup; 3270 LookupResult lookup(isolate());
3077 LookupPostInterceptor(holder, name, &lookup); 3271 LookupPostInterceptor(holder, name, &lookup);
3078 GenerateLoadInterceptor(receiver, 3272 GenerateLoadInterceptor(receiver,
3079 holder, 3273 holder,
3080 &lookup, 3274 &lookup,
3081 a1, 3275 a1,
3082 a0, 3276 a0,
3083 a2, 3277 a2,
3084 a3, 3278 a3,
3085 t0, 3279 t0,
3086 name, 3280 name,
3087 &miss); 3281 &miss);
3088 __ bind(&miss); 3282 __ bind(&miss);
3089 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3283 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3090 3284
3091 return GetCode(INTERCEPTOR, name); 3285 return TryGetCode(INTERCEPTOR, name);
3092 } 3286 }
3093 3287
3094 3288
3095 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { 3289 Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength(
3290 Handle<String> name) {
3096 // ----------- S t a t e ------------- 3291 // ----------- S t a t e -------------
3097 // -- ra : return address 3292 // -- ra : return address
3098 // -- a0 : key 3293 // -- a0 : key
3099 // -- a1 : receiver 3294 // -- a1 : receiver
3100 // ----------------------------------- 3295 // -----------------------------------
3101 Label miss; 3296 Label miss;
3102 3297
3103 // Check the key is the cached one. 3298 // Check the key is the cached one.
3104 __ Branch(&miss, ne, a0, Operand(Handle<String>(name))); 3299 __ Branch(&miss, ne, a0, Operand(name));
3105 3300
3106 GenerateLoadArrayLength(masm(), a1, a2, &miss); 3301 GenerateLoadArrayLength(masm(), a1, a2, &miss);
3107 __ bind(&miss); 3302 __ bind(&miss);
3108 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3303 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3109 3304
3110 return GetCode(CALLBACKS, name); 3305 return GetCode(CALLBACKS, name);
3111 } 3306 }
3112 3307
3113 3308
3114 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { 3309 Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength(
3310 Handle<String> name) {
3115 // ----------- S t a t e ------------- 3311 // ----------- S t a t e -------------
3116 // -- ra : return address 3312 // -- ra : return address
3117 // -- a0 : key 3313 // -- a0 : key
3118 // -- a1 : receiver 3314 // -- a1 : receiver
3119 // ----------------------------------- 3315 // -----------------------------------
3120 Label miss; 3316 Label miss;
3121 3317
3122 Counters* counters = masm()->isolate()->counters(); 3318 Counters* counters = masm()->isolate()->counters();
3123 __ IncrementCounter(counters->keyed_load_string_length(), 1, a2, a3); 3319 __ IncrementCounter(counters->keyed_load_string_length(), 1, a2, a3);
3124 3320
3125 // Check the key is the cached one. 3321 // Check the key is the cached one.
3126 __ Branch(&miss, ne, a0, Operand(Handle<String>(name))); 3322 __ Branch(&miss, ne, a0, Operand(name));
3127 3323
3128 GenerateLoadStringLength(masm(), a1, a2, a3, &miss, true); 3324 GenerateLoadStringLength(masm(), a1, a2, a3, &miss, true);
3129 __ bind(&miss); 3325 __ bind(&miss);
3130 __ DecrementCounter(counters->keyed_load_string_length(), 1, a2, a3); 3326 __ DecrementCounter(counters->keyed_load_string_length(), 1, a2, a3);
3131 3327
3132 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3328 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3133 3329
3134 return GetCode(CALLBACKS, name); 3330 return GetCode(CALLBACKS, name);
3135 } 3331 }
3136 3332
3137 3333
3138 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { 3334 Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype(
3335 Handle<String> name) {
3139 // ----------- S t a t e ------------- 3336 // ----------- S t a t e -------------
3140 // -- ra : return address 3337 // -- ra : return address
3141 // -- a0 : key 3338 // -- a0 : key
3142 // -- a1 : receiver 3339 // -- a1 : receiver
3143 // ----------------------------------- 3340 // -----------------------------------
3144 Label miss; 3341 Label miss;
3145 3342
3146 Counters* counters = masm()->isolate()->counters(); 3343 Counters* counters = masm()->isolate()->counters();
3147 __ IncrementCounter(counters->keyed_load_function_prototype(), 1, a2, a3); 3344 __ IncrementCounter(counters->keyed_load_function_prototype(), 1, a2, a3);
3148 3345
3149 // Check the name hasn't changed. 3346 // Check the name hasn't changed.
3150 __ Branch(&miss, ne, a0, Operand(Handle<String>(name))); 3347 __ Branch(&miss, ne, a0, Operand(name));
3151 3348
3152 GenerateLoadFunctionPrototype(masm(), a1, a2, a3, &miss); 3349 GenerateLoadFunctionPrototype(masm(), a1, a2, a3, &miss);
3153 __ bind(&miss); 3350 __ bind(&miss);
3154 __ DecrementCounter(counters->keyed_load_function_prototype(), 1, a2, a3); 3351 __ DecrementCounter(counters->keyed_load_function_prototype(), 1, a2, a3);
3155 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3352 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3156 3353
3157 return GetCode(CALLBACKS, name); 3354 return GetCode(CALLBACKS, name);
3158 } 3355 }
3159 3356
3160 3357
(...skipping 10 matching lines...) Expand all
3171 __ DispatchMap(a1, 3368 __ DispatchMap(a1,
3172 a2, 3369 a2,
3173 Handle<Map>(receiver_map), 3370 Handle<Map>(receiver_map),
3174 Handle<Code>(stub), 3371 Handle<Code>(stub),
3175 DO_SMI_CHECK); 3372 DO_SMI_CHECK);
3176 3373
3177 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); 3374 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss();
3178 __ Jump(ic, RelocInfo::CODE_TARGET); 3375 __ Jump(ic, RelocInfo::CODE_TARGET);
3179 3376
3180 // Return the generated code. 3377 // Return the generated code.
3181 return GetCode(NORMAL, NULL); 3378 return TryGetCode(NORMAL, NULL);
3182 } 3379 }
3183 3380
3184 3381
3185 MaybeObject* KeyedLoadStubCompiler::CompileLoadPolymorphic( 3382 MaybeObject* KeyedLoadStubCompiler::CompileLoadPolymorphic(
3186 MapList* receiver_maps, 3383 MapList* receiver_maps,
3187 CodeList* handler_ics) { 3384 CodeList* handler_ics) {
3188 // ----------- S t a t e ------------- 3385 // ----------- S t a t e -------------
3189 // -- ra : return address 3386 // -- ra : return address
3190 // -- a0 : key 3387 // -- a0 : key
3191 // -- a1 : receiver 3388 // -- a1 : receiver
3192 // ----------------------------------- 3389 // -----------------------------------
3193 Label miss; 3390 Label miss;
3194 __ JumpIfSmi(a1, &miss); 3391 __ JumpIfSmi(a1, &miss);
3195 3392
3196 int receiver_count = receiver_maps->length(); 3393 int receiver_count = receiver_maps->length();
3197 __ lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset)); 3394 __ lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset));
3198 for (int current = 0; current < receiver_count; ++current) { 3395 for (int current = 0; current < receiver_count; ++current) {
3199 Handle<Map> map(receiver_maps->at(current)); 3396 Handle<Map> map(receiver_maps->at(current));
3200 Handle<Code> code(handler_ics->at(current)); 3397 Handle<Code> code(handler_ics->at(current));
3201 __ Jump(code, RelocInfo::CODE_TARGET, eq, a2, Operand(map)); 3398 __ Jump(code, RelocInfo::CODE_TARGET, eq, a2, Operand(map));
3202 } 3399 }
3203 3400
3204 __ bind(&miss); 3401 __ bind(&miss);
3205 Handle<Code> miss_ic = isolate()->builtins()->KeyedLoadIC_Miss(); 3402 Handle<Code> miss_ic = isolate()->builtins()->KeyedLoadIC_Miss();
3206 __ Jump(miss_ic, RelocInfo::CODE_TARGET); 3403 __ Jump(miss_ic, RelocInfo::CODE_TARGET);
3207 3404
3208 // Return the generated code. 3405 // Return the generated code.
3209 return GetCode(NORMAL, NULL, MEGAMORPHIC); 3406 return TryGetCode(NORMAL, NULL, MEGAMORPHIC);
3210 } 3407 }
3211 3408
3212 3409
3213 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, 3410 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object,
3214 int index, 3411 int index,
3215 Map* transition, 3412 Map* transition,
3216 String* name) { 3413 String* name) {
3217 // ----------- S t a t e ------------- 3414 // ----------- S t a t e -------------
3218 // -- a0 : value 3415 // -- a0 : value
3219 // -- a1 : key 3416 // -- a1 : key
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
3292 3489
3293 int receiver_count = receiver_maps->length(); 3490 int receiver_count = receiver_maps->length();
3294 __ lw(a3, FieldMemOperand(a2, HeapObject::kMapOffset)); 3491 __ lw(a3, FieldMemOperand(a2, HeapObject::kMapOffset));
3295 for (int i = 0; i < receiver_count; ++i) { 3492 for (int i = 0; i < receiver_count; ++i) {
3296 Handle<Map> map(receiver_maps->at(i)); 3493 Handle<Map> map(receiver_maps->at(i));
3297 Handle<Code> code(handler_stubs->at(i)); 3494 Handle<Code> code(handler_stubs->at(i));
3298 if (transitioned_maps->at(i) == NULL) { 3495 if (transitioned_maps->at(i) == NULL) {
3299 __ Jump(code, RelocInfo::CODE_TARGET, eq, a3, Operand(map)); 3496 __ Jump(code, RelocInfo::CODE_TARGET, eq, a3, Operand(map));
3300 } else { 3497 } else {
3301 Label next_map; 3498 Label next_map;
3302 __ Branch(&next_map, eq, a3, Operand(map)); 3499 __ Branch(&next_map, ne, a3, Operand(map));
3303 __ li(t0, Operand(Handle<Map>(transitioned_maps->at(i)))); 3500 __ li(a3, Operand(Handle<Map>(transitioned_maps->at(i))));
3304 __ Jump(code, RelocInfo::CODE_TARGET); 3501 __ Jump(code, RelocInfo::CODE_TARGET);
3305 __ bind(&next_map); 3502 __ bind(&next_map);
3306 } 3503 }
3307 } 3504 }
3308 3505
3309 __ bind(&miss); 3506 __ bind(&miss);
3310 Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss(); 3507 Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss();
3311 __ Jump(miss_ic, RelocInfo::CODE_TARGET); 3508 __ Jump(miss_ic, RelocInfo::CODE_TARGET);
3312 3509
3313 // Return the generated code. 3510 // Return the generated code.
(...skipping 1216 matching lines...) Expand 10 before | Expand all | Expand 10 after
4530 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); 4727 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
4531 __ Jump(ic_miss, RelocInfo::CODE_TARGET); 4728 __ Jump(ic_miss, RelocInfo::CODE_TARGET);
4532 } 4729 }
4533 4730
4534 4731
4535 #undef __ 4732 #undef __
4536 4733
4537 } } // namespace v8::internal 4734 } } // namespace v8::internal
4538 4735
4539 #endif // V8_TARGET_ARCH_MIPS 4736 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/simulator-mips.cc ('k') | src/mirror-debugger.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698