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

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

Issue 148593004: A64: Synchronize with r18084. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/simulator-ia32.cc ('k') | src/ic.h » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 __ push(receiver); 398 __ push(receiver);
399 __ push(holder); 399 __ push(holder);
400 } 400 }
401 401
402 402
403 static void CompileCallLoadPropertyWithInterceptor( 403 static void CompileCallLoadPropertyWithInterceptor(
404 MacroAssembler* masm, 404 MacroAssembler* masm,
405 Register receiver, 405 Register receiver,
406 Register holder, 406 Register holder,
407 Register name, 407 Register name,
408 Handle<JSObject> holder_obj) { 408 Handle<JSObject> holder_obj,
409 IC::UtilityId id) {
409 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 410 PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
410 __ CallExternalReference( 411 __ CallExternalReference(
411 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly), 412 ExternalReference(IC_Utility(id), masm->isolate()),
412 masm->isolate()),
413 StubCache::kInterceptorArgsLength); 413 StubCache::kInterceptorArgsLength);
414 } 414 }
415 415
416 416
417 // Number of pointers to be reserved on stack for fast API call. 417 // Number of pointers to be reserved on stack for fast API call.
418 static const int kFastApiCallArguments = FunctionCallbackArguments::kArgsLength; 418 static const int kFastApiCallArguments = FunctionCallbackArguments::kArgsLength;
419 419
420 420
421 // Reserves space for the extra arguments to API function in the 421 // Reserves space for the extra arguments to API function in the
422 // caller's frame. 422 // caller's frame.
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 if (can_do_fast_api_call) { 716 if (can_do_fast_api_call) {
717 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1); 717 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1);
718 ReserveSpaceForFastApiCall(masm, scratch1); 718 ReserveSpaceForFastApiCall(masm, scratch1);
719 } 719 }
720 720
721 // Check that the maps from receiver to interceptor's holder 721 // Check that the maps from receiver to interceptor's holder
722 // haven't changed and thus we can invoke interceptor. 722 // haven't changed and thus we can invoke interceptor.
723 Label miss_cleanup; 723 Label miss_cleanup;
724 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; 724 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label;
725 Register holder = 725 Register holder =
726 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, 726 stub_compiler_->CheckPrototypes(
727 scratch1, scratch2, scratch3, 727 IC::CurrentTypeOf(object, masm->isolate()), receiver,
728 name, depth1, miss); 728 interceptor_holder, scratch1, scratch2, scratch3,
729 name, depth1, miss);
729 730
730 // Invoke an interceptor and if it provides a value, 731 // Invoke an interceptor and if it provides a value,
731 // branch to |regular_invoke|. 732 // branch to |regular_invoke|.
732 Label regular_invoke; 733 Label regular_invoke;
733 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, 734 LoadWithInterceptor(masm, receiver, holder, interceptor_holder,
734 &regular_invoke); 735 &regular_invoke);
735 736
736 // Interceptor returned nothing for this property. Try to use cached 737 // Interceptor returned nothing for this property. Try to use cached
737 // constant function. 738 // constant function.
738 739
739 // Check that the maps from interceptor's holder to constant function's 740 // Check that the maps from interceptor's holder to constant function's
740 // holder haven't changed and thus we can use cached constant function. 741 // holder haven't changed and thus we can use cached constant function.
741 if (*interceptor_holder != lookup->holder()) { 742 if (*interceptor_holder != lookup->holder()) {
742 stub_compiler_->CheckPrototypes(interceptor_holder, receiver, 743 stub_compiler_->CheckPrototypes(
743 Handle<JSObject>(lookup->holder()), 744 IC::CurrentTypeOf(interceptor_holder, masm->isolate()), receiver,
744 scratch1, scratch2, scratch3, 745 handle(lookup->holder()), scratch1, scratch2, scratch3,
745 name, depth2, miss); 746 name, depth2, miss);
746 } else { 747 } else {
747 // CheckPrototypes has a side effect of fetching a 'holder' 748 // CheckPrototypes has a side effect of fetching a 'holder'
748 // for API (object which is instanceof for the signature). It's 749 // for API (object which is instanceof for the signature). It's
749 // safe to omit it here, as if present, it should be fetched 750 // safe to omit it here, as if present, it should be fetched
750 // by the previous CheckPrototypes. 751 // by the previous CheckPrototypes.
751 ASSERT(depth2 == kInvalidProtoDepth); 752 ASSERT(depth2 == kInvalidProtoDepth);
752 } 753 }
753 754
754 // Invoke function. 755 // Invoke function.
755 if (can_do_fast_api_call) { 756 if (can_do_fast_api_call) {
(...skipping 25 matching lines...) Expand all
781 void CompileRegular(MacroAssembler* masm, 782 void CompileRegular(MacroAssembler* masm,
782 Handle<JSObject> object, 783 Handle<JSObject> object,
783 Register receiver, 784 Register receiver,
784 Register scratch1, 785 Register scratch1,
785 Register scratch2, 786 Register scratch2,
786 Register scratch3, 787 Register scratch3,
787 Handle<Name> name, 788 Handle<Name> name,
788 Handle<JSObject> interceptor_holder, 789 Handle<JSObject> interceptor_holder,
789 Label* miss_label) { 790 Label* miss_label) {
790 Register holder = 791 Register holder =
791 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, 792 stub_compiler_->CheckPrototypes(
792 scratch1, scratch2, scratch3, 793 IC::CurrentTypeOf(object, masm->isolate()), receiver,
793 name, miss_label); 794 interceptor_holder, scratch1, scratch2, scratch3, name, miss_label);
794 795
795 FrameScope scope(masm, StackFrame::INTERNAL); 796 FrameScope scope(masm, StackFrame::INTERNAL);
796 // Save the name_ register across the call. 797 // Save the name_ register across the call.
797 __ push(name_); 798 __ push(name_);
798 799
799 PushInterceptorArguments(masm, receiver, holder, name_, interceptor_holder); 800 CompileCallLoadPropertyWithInterceptor(
800 801 masm, receiver, holder, name_, interceptor_holder,
801 __ CallExternalReference( 802 IC::kLoadPropertyWithInterceptorForCall);
802 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall),
803 masm->isolate()),
804 StubCache::kInterceptorArgsLength);
805 803
806 // Restore the name_ register. 804 // Restore the name_ register.
807 __ pop(name_); 805 __ pop(name_);
808 806
809 // Leave the internal frame. 807 // Leave the internal frame.
810 } 808 }
811 809
812 void LoadWithInterceptor(MacroAssembler* masm, 810 void LoadWithInterceptor(MacroAssembler* masm,
813 Register receiver, 811 Register receiver,
814 Register holder, 812 Register holder,
815 Handle<JSObject> holder_obj, 813 Handle<JSObject> holder_obj,
816 Label* interceptor_succeeded) { 814 Label* interceptor_succeeded) {
817 { 815 {
818 FrameScope scope(masm, StackFrame::INTERNAL); 816 FrameScope scope(masm, StackFrame::INTERNAL);
819 __ push(holder); // Save the holder. 817 __ push(holder); // Save the holder.
820 __ push(name_); // Save the name. 818 __ push(name_); // Save the name.
821 819
822 CompileCallLoadPropertyWithInterceptor(masm, 820 CompileCallLoadPropertyWithInterceptor(
823 receiver, 821 masm, receiver, holder, name_, holder_obj,
824 holder, 822 IC::kLoadPropertyWithInterceptorOnly);
825 name_,
826 holder_obj);
827 823
828 __ pop(name_); // Restore the name. 824 __ pop(name_); // Restore the name.
829 __ pop(receiver); // Restore the holder. 825 __ pop(receiver); // Restore the holder.
830 // Leave the internal frame. 826 // Leave the internal frame.
831 } 827 }
832 828
833 __ cmp(eax, masm->isolate()->factory()->no_interceptor_result_sentinel()); 829 __ cmp(eax, masm->isolate()->factory()->no_interceptor_result_sentinel());
834 __ j(not_equal, interceptor_succeeded); 830 __ j(not_equal, interceptor_succeeded);
835 } 831 }
836 832
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 smi_check); 1173 smi_check);
1178 } 1174 }
1179 } 1175 }
1180 1176
1181 // Return the value (register eax). 1177 // Return the value (register eax).
1182 ASSERT(value_reg.is(eax)); 1178 ASSERT(value_reg.is(eax));
1183 __ ret(0); 1179 __ ret(0);
1184 } 1180 }
1185 1181
1186 1182
1187 void StubCompiler::GenerateCheckPropertyCells(MacroAssembler* masm,
1188 Handle<JSObject> object,
1189 Handle<JSObject> holder,
1190 Handle<Name> name,
1191 Register scratch,
1192 Label* miss) {
1193 Handle<JSObject> current = object;
1194 while (!current.is_identical_to(holder)) {
1195 if (current->IsJSGlobalObject()) {
1196 GenerateCheckPropertyCell(masm,
1197 Handle<JSGlobalObject>::cast(current),
1198 name,
1199 scratch,
1200 miss);
1201 }
1202 current = Handle<JSObject>(JSObject::cast(current->GetPrototype()));
1203 }
1204 }
1205
1206
1207 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { 1183 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
1208 __ jmp(code, RelocInfo::CODE_TARGET); 1184 __ jmp(code, RelocInfo::CODE_TARGET);
1209 } 1185 }
1210 1186
1211 1187
1212 #undef __ 1188 #undef __
1213 #define __ ACCESS_MASM(masm()) 1189 #define __ ACCESS_MASM(masm())
1214 1190
1215 1191
1216 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, 1192 Register StubCompiler::CheckPrototypes(Handle<Type> type,
1217 Register object_reg, 1193 Register object_reg,
1218 Handle<JSObject> holder, 1194 Handle<JSObject> holder,
1219 Register holder_reg, 1195 Register holder_reg,
1220 Register scratch1, 1196 Register scratch1,
1221 Register scratch2, 1197 Register scratch2,
1222 Handle<Name> name, 1198 Handle<Name> name,
1223 int save_at_depth, 1199 int save_at_depth,
1224 Label* miss, 1200 Label* miss,
1225 PrototypeCheckType check) { 1201 PrototypeCheckType check) {
1226 const int kHolderIndex = FunctionCallbackArguments::kHolderIndex + 1; 1202 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate()));
1227 // Make sure that the type feedback oracle harvests the receiver map. 1203 // Make sure that the type feedback oracle harvests the receiver map.
1228 // TODO(svenpanne) Remove this hack when all ICs are reworked. 1204 // TODO(svenpanne) Remove this hack when all ICs are reworked.
1229 __ mov(scratch1, Handle<Map>(object->map())); 1205 __ mov(scratch1, receiver_map);
1230 1206
1231 Handle<JSObject> first = object;
1232 // Make sure there's no overlap between holder and object registers. 1207 // Make sure there's no overlap between holder and object registers.
1233 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 1208 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
1234 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 1209 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
1235 && !scratch2.is(scratch1)); 1210 && !scratch2.is(scratch1));
1236 1211
1237 // Keep track of the current object in register reg. 1212 // Keep track of the current object in register reg.
1238 Register reg = object_reg; 1213 Register reg = object_reg;
1239 Handle<JSObject> current = object;
1240 int depth = 0; 1214 int depth = 0;
1241 1215
1216 const int kHolderIndex = FunctionCallbackArguments::kHolderIndex + 1;
1242 if (save_at_depth == depth) { 1217 if (save_at_depth == depth) {
1243 __ mov(Operand(esp, kHolderIndex * kPointerSize), reg); 1218 __ mov(Operand(esp, kHolderIndex * kPointerSize), reg);
1244 } 1219 }
1245 1220
1221 Handle<JSObject> current = Handle<JSObject>::null();
1222 if (type->IsConstant()) current = Handle<JSObject>::cast(type->AsConstant());
1223 Handle<JSObject> prototype = Handle<JSObject>::null();
1224 Handle<Map> current_map = receiver_map;
1225 Handle<Map> holder_map(holder->map());
1246 // Traverse the prototype chain and check the maps in the prototype chain for 1226 // Traverse the prototype chain and check the maps in the prototype chain for
1247 // fast and global objects or do negative lookup for normal objects. 1227 // fast and global objects or do negative lookup for normal objects.
1248 while (!current.is_identical_to(holder)) { 1228 while (!current_map.is_identical_to(holder_map)) {
1249 ++depth; 1229 ++depth;
1250 1230
1251 // Only global objects and objects that do not require access 1231 // Only global objects and objects that do not require access
1252 // checks are allowed in stubs. 1232 // checks are allowed in stubs.
1253 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); 1233 ASSERT(current_map->IsJSGlobalProxyMap() ||
1234 !current_map->is_access_check_needed());
1254 1235
1255 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); 1236 prototype = handle(JSObject::cast(current_map->prototype()));
1256 if (!current->HasFastProperties() && 1237 if (current_map->is_dictionary_map() &&
1257 !current->IsJSGlobalObject() && 1238 !current_map->IsJSGlobalObjectMap() &&
1258 !current->IsJSGlobalProxy()) { 1239 !current_map->IsJSGlobalProxyMap()) {
1259 if (!name->IsUniqueName()) { 1240 if (!name->IsUniqueName()) {
1260 ASSERT(name->IsString()); 1241 ASSERT(name->IsString());
1261 name = factory()->InternalizeString(Handle<String>::cast(name)); 1242 name = factory()->InternalizeString(Handle<String>::cast(name));
1262 } 1243 }
1263 ASSERT(current->property_dictionary()->FindEntry(*name) == 1244 ASSERT(current.is_null() ||
1245 current->property_dictionary()->FindEntry(*name) ==
1264 NameDictionary::kNotFound); 1246 NameDictionary::kNotFound);
1265 1247
1266 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, 1248 GenerateDictionaryNegativeLookup(masm(), miss, reg, name,
1267 scratch1, scratch2); 1249 scratch1, scratch2);
1268 1250
1269 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 1251 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
1270 reg = holder_reg; // From now on the object will be in holder_reg. 1252 reg = holder_reg; // From now on the object will be in holder_reg.
1271 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 1253 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
1272 } else { 1254 } else {
1273 bool in_new_space = heap()->InNewSpace(*prototype); 1255 bool in_new_space = heap()->InNewSpace(*prototype);
1274 Handle<Map> current_map(current->map()); 1256 if (depth != 1 || check == CHECK_ALL_MAPS) {
1275 if (!current.is_identical_to(first) || check == CHECK_ALL_MAPS) {
1276 __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK); 1257 __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK);
1277 } 1258 }
1278 1259
1279 // Check access rights to the global object. This has to happen after 1260 // Check access rights to the global object. This has to happen after
1280 // the map check so that we know that the object is actually a global 1261 // the map check so that we know that the object is actually a global
1281 // object. 1262 // object.
1282 if (current->IsJSGlobalProxy()) { 1263 if (current_map->IsJSGlobalProxyMap()) {
1283 __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss); 1264 __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss);
1265 } else if (current_map->IsJSGlobalObjectMap()) {
1266 GenerateCheckPropertyCell(
1267 masm(), Handle<JSGlobalObject>::cast(current), name,
1268 scratch2, miss);
1284 } 1269 }
1285 1270
1286 if (in_new_space) { 1271 if (in_new_space) {
1287 // Save the map in scratch1 for later. 1272 // Save the map in scratch1 for later.
1288 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 1273 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
1289 } 1274 }
1290 1275
1291 reg = holder_reg; // From now on the object will be in holder_reg. 1276 reg = holder_reg; // From now on the object will be in holder_reg.
1292 1277
1293 if (in_new_space) { 1278 if (in_new_space) {
1294 // The prototype is in new space; we cannot store a reference to it 1279 // The prototype is in new space; we cannot store a reference to it
1295 // in the code. Load it from the map. 1280 // in the code. Load it from the map.
1296 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 1281 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
1297 } else { 1282 } else {
1298 // The prototype is in old space; load it directly. 1283 // The prototype is in old space; load it directly.
1299 __ mov(reg, prototype); 1284 __ mov(reg, prototype);
1300 } 1285 }
1301 } 1286 }
1302 1287
1303 if (save_at_depth == depth) { 1288 if (save_at_depth == depth) {
1304 __ mov(Operand(esp, kHolderIndex * kPointerSize), reg); 1289 __ mov(Operand(esp, kHolderIndex * kPointerSize), reg);
1305 } 1290 }
1306 1291
1307 // Go to the next object in the prototype chain. 1292 // Go to the next object in the prototype chain.
1308 current = prototype; 1293 current = prototype;
1294 current_map = handle(current->map());
1309 } 1295 }
1310 ASSERT(current.is_identical_to(holder));
1311 1296
1312 // Log the check depth. 1297 // Log the check depth.
1313 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 1298 LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
1314 1299
1315 if (!holder.is_identical_to(first) || check == CHECK_ALL_MAPS) { 1300 if (depth != 0 || check == CHECK_ALL_MAPS) {
1316 // Check the holder map. 1301 // Check the holder map.
1317 __ CheckMap(reg, Handle<Map>(holder->map()), miss, DONT_DO_SMI_CHECK); 1302 __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK);
1318 } 1303 }
1319 1304
1320 // Perform security check for access to the global object. 1305 // Perform security check for access to the global object.
1321 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 1306 ASSERT(current_map->IsJSGlobalProxyMap() ||
1322 if (holder->IsJSGlobalProxy()) { 1307 !current_map->is_access_check_needed());
1308 if (current_map->IsJSGlobalProxyMap()) {
1323 __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss); 1309 __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss);
1324 } 1310 }
1325 1311
1326 // If we've skipped any global objects, it's not enough to verify that
1327 // their maps haven't changed. We also need to check that the property
1328 // cell for the property is still empty.
1329 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss);
1330
1331 // Return the register containing the holder. 1312 // Return the register containing the holder.
1332 return reg; 1313 return reg;
1333 } 1314 }
1334 1315
1335 1316
1336 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { 1317 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) {
1337 if (!miss->is_unused()) { 1318 if (!miss->is_unused()) {
1338 Label success; 1319 Label success;
1339 __ jmp(&success); 1320 __ jmp(&success);
1340 __ bind(miss); 1321 __ bind(miss);
1341 TailCallBuiltin(masm(), MissBuiltin(kind())); 1322 TailCallBuiltin(masm(), MissBuiltin(kind()));
1342 __ bind(&success); 1323 __ bind(&success);
1343 } 1324 }
1344 } 1325 }
1345 1326
1346 1327
1347 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { 1328 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) {
1348 if (!miss->is_unused()) { 1329 if (!miss->is_unused()) {
1349 Label success; 1330 Label success;
1350 __ jmp(&success); 1331 __ jmp(&success);
1351 GenerateRestoreName(masm(), miss, name); 1332 GenerateRestoreName(masm(), miss, name);
1352 TailCallBuiltin(masm(), MissBuiltin(kind())); 1333 TailCallBuiltin(masm(), MissBuiltin(kind()));
1353 __ bind(&success); 1334 __ bind(&success);
1354 } 1335 }
1355 } 1336 }
1356 1337
1357 1338
1358 Register LoadStubCompiler::CallbackHandlerFrontend( 1339 Register LoadStubCompiler::CallbackHandlerFrontend(
1359 Handle<Object> object, 1340 Handle<Type> type,
1360 Register object_reg, 1341 Register object_reg,
1361 Handle<JSObject> holder, 1342 Handle<JSObject> holder,
1362 Handle<Name> name, 1343 Handle<Name> name,
1363 Handle<Object> callback) { 1344 Handle<Object> callback) {
1364 Label miss; 1345 Label miss;
1365 1346
1366 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); 1347 Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss);
1367 1348
1368 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 1349 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
1369 ASSERT(!reg.is(scratch2())); 1350 ASSERT(!reg.is(scratch2()));
1370 ASSERT(!reg.is(scratch3())); 1351 ASSERT(!reg.is(scratch3()));
1371 Register dictionary = scratch1(); 1352 Register dictionary = scratch1();
1372 bool must_preserve_dictionary_reg = reg.is(dictionary); 1353 bool must_preserve_dictionary_reg = reg.is(dictionary);
1373 1354
1374 // Load the properties dictionary. 1355 // Load the properties dictionary.
1375 if (must_preserve_dictionary_reg) { 1356 if (must_preserve_dictionary_reg) {
1376 __ push(dictionary); 1357 __ push(dictionary);
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
1560 1541
1561 if (must_preserve_receiver_reg) { 1542 if (must_preserve_receiver_reg) {
1562 __ push(receiver()); 1543 __ push(receiver());
1563 } 1544 }
1564 __ push(holder_reg); 1545 __ push(holder_reg);
1565 __ push(this->name()); 1546 __ push(this->name());
1566 1547
1567 // Invoke an interceptor. Note: map checks from receiver to 1548 // Invoke an interceptor. Note: map checks from receiver to
1568 // interceptor's holder has been compiled before (see a caller 1549 // interceptor's holder has been compiled before (see a caller
1569 // of this method.) 1550 // of this method.)
1570 CompileCallLoadPropertyWithInterceptor(masm(), 1551 CompileCallLoadPropertyWithInterceptor(
1571 receiver(), 1552 masm(), receiver(), holder_reg, this->name(), interceptor_holder,
1572 holder_reg, 1553 IC::kLoadPropertyWithInterceptorOnly);
1573 this->name(),
1574 interceptor_holder);
1575 1554
1576 // Check if interceptor provided a value for property. If it's 1555 // Check if interceptor provided a value for property. If it's
1577 // the case, return immediately. 1556 // the case, return immediately.
1578 Label interceptor_failed; 1557 Label interceptor_failed;
1579 __ cmp(eax, factory()->no_interceptor_result_sentinel()); 1558 __ cmp(eax, factory()->no_interceptor_result_sentinel());
1580 __ j(equal, &interceptor_failed); 1559 __ j(equal, &interceptor_failed);
1581 frame_scope.GenerateLeaveFrame(); 1560 frame_scope.GenerateLeaveFrame();
1582 __ ret(0); 1561 __ ret(0);
1583 1562
1584 // Clobber registers when generating debug-code to provoke errors. 1563 // Clobber registers when generating debug-code to provoke errors.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1631 1610
1632 // Get the number of arguments. 1611 // Get the number of arguments.
1633 const int argc = arguments().immediate(); 1612 const int argc = arguments().immediate();
1634 1613
1635 // Get the receiver from the stack. 1614 // Get the receiver from the stack.
1636 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1615 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1637 1616
1638 1617
1639 // Check that the maps haven't changed. 1618 // Check that the maps haven't changed.
1640 __ JumpIfSmi(edx, miss); 1619 __ JumpIfSmi(edx, miss);
1641 CheckPrototypes(object, edx, holder, ebx, eax, edi, name, miss); 1620 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
1621 ebx, eax, edi, name, miss);
1642 } 1622 }
1643 1623
1644 1624
1645 void CallStubCompiler::GenerateLoadFunctionFromCell( 1625 void CallStubCompiler::GenerateLoadFunctionFromCell(
1646 Handle<Cell> cell, 1626 Handle<Cell> cell,
1647 Handle<JSFunction> function, 1627 Handle<JSFunction> function,
1648 Label* miss) { 1628 Label* miss) {
1649 // Get the value from the cell. 1629 // Get the value from the cell.
1650 if (Serializer::enabled()) { 1630 if (Serializer::enabled()) {
1651 __ mov(edi, Immediate(cell)); 1631 __ mov(edi, Immediate(cell));
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1700 GenerateNameCheck(name, &miss); 1680 GenerateNameCheck(name, &miss);
1701 1681
1702 // Get the receiver from the stack. 1682 // Get the receiver from the stack.
1703 const int argc = arguments().immediate(); 1683 const int argc = arguments().immediate();
1704 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1684 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1705 1685
1706 // Check that the receiver isn't a smi. 1686 // Check that the receiver isn't a smi.
1707 __ JumpIfSmi(edx, &miss); 1687 __ JumpIfSmi(edx, &miss);
1708 1688
1709 // Do the right check and compute the holder register. 1689 // Do the right check and compute the holder register.
1710 Register reg = CheckPrototypes(object, edx, holder, ebx, eax, edi, 1690 Register reg = CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx,
1711 name, &miss); 1691 holder, ebx, eax, edi, name, &miss);
1712 1692
1713 GenerateFastPropertyLoad( 1693 GenerateFastPropertyLoad(
1714 masm(), edi, reg, index.is_inobject(holder), 1694 masm(), edi, reg, index.is_inobject(holder),
1715 index.translate(holder), Representation::Tagged()); 1695 index.translate(holder), Representation::Tagged());
1716 1696
1717 // Check that the function really is a function. 1697 // Check that the function really is a function.
1718 __ JumpIfSmi(edi, &miss); 1698 __ JumpIfSmi(edi, &miss);
1719 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); 1699 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx);
1720 __ j(not_equal, &miss); 1700 __ j(not_equal, &miss);
1721 1701
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1754 // Check that function is still array 1734 // Check that function is still array
1755 const int argc = arguments().immediate(); 1735 const int argc = arguments().immediate();
1756 GenerateNameCheck(name, &miss); 1736 GenerateNameCheck(name, &miss);
1757 1737
1758 if (cell.is_null()) { 1738 if (cell.is_null()) {
1759 // Get the receiver from the stack. 1739 // Get the receiver from the stack.
1760 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1740 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1761 1741
1762 // Check that the receiver isn't a smi. 1742 // Check that the receiver isn't a smi.
1763 __ JumpIfSmi(edx, &miss); 1743 __ JumpIfSmi(edx, &miss);
1764 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, 1744 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
1765 name, &miss); 1745 ebx, eax, edi, name, &miss);
1766 } else { 1746 } else {
1767 ASSERT(cell->value() == *function); 1747 ASSERT(cell->value() == *function);
1768 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 1748 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
1769 &miss); 1749 &miss);
1770 GenerateLoadFunctionFromCell(cell, function, &miss); 1750 GenerateLoadFunctionFromCell(cell, function, &miss);
1771 } 1751 }
1772 1752
1773 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); 1753 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite();
1774 site->SetElementsKind(GetInitialFastElementsKind()); 1754 site->SetElementsKind(GetInitialFastElementsKind());
1775 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); 1755 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1814 1794
1815 GenerateNameCheck(name, &miss); 1795 GenerateNameCheck(name, &miss);
1816 1796
1817 // Get the receiver from the stack. 1797 // Get the receiver from the stack.
1818 const int argc = arguments().immediate(); 1798 const int argc = arguments().immediate();
1819 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1799 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1820 1800
1821 // Check that the receiver isn't a smi. 1801 // Check that the receiver isn't a smi.
1822 __ JumpIfSmi(edx, &miss); 1802 __ JumpIfSmi(edx, &miss);
1823 1803
1824 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, 1804 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
1825 name, &miss); 1805 ebx, eax, edi, name, &miss);
1826 1806
1827 if (argc == 0) { 1807 if (argc == 0) {
1828 // Noop, return the length. 1808 // Noop, return the length.
1829 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); 1809 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
1830 __ ret((argc + 1) * kPointerSize); 1810 __ ret((argc + 1) * kPointerSize);
1831 } else { 1811 } else {
1832 Label call_builtin; 1812 Label call_builtin;
1833 1813
1834 if (argc == 1) { // Otherwise fall through to call builtin. 1814 if (argc == 1) { // Otherwise fall through to call builtin.
1835 Label attempt_to_grow_elements, with_write_barrier, check_double; 1815 Label attempt_to_grow_elements, with_write_barrier, check_double;
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
2074 Label miss, return_undefined, call_builtin; 2054 Label miss, return_undefined, call_builtin;
2075 2055
2076 GenerateNameCheck(name, &miss); 2056 GenerateNameCheck(name, &miss);
2077 2057
2078 // Get the receiver from the stack. 2058 // Get the receiver from the stack.
2079 const int argc = arguments().immediate(); 2059 const int argc = arguments().immediate();
2080 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2060 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2081 2061
2082 // Check that the receiver isn't a smi. 2062 // Check that the receiver isn't a smi.
2083 __ JumpIfSmi(edx, &miss); 2063 __ JumpIfSmi(edx, &miss);
2084 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, 2064 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
2085 name, &miss); 2065 ebx, eax, edi, name, &miss);
2086 2066
2087 // Get the elements array of the object. 2067 // Get the elements array of the object.
2088 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset)); 2068 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset));
2089 2069
2090 // Check that the elements are in fast mode and writable. 2070 // Check that the elements are in fast mode and writable.
2091 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), 2071 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
2092 Immediate(factory()->fixed_array_map())); 2072 Immediate(factory()->fixed_array_map()));
2093 __ j(not_equal, &call_builtin); 2073 __ j(not_equal, &call_builtin);
2094 2074
2095 // Get the array's length into ecx and calculate new length. 2075 // Get the array's length into ecx and calculate new length.
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2168 } 2148 }
2169 2149
2170 GenerateNameCheck(name, &name_miss); 2150 GenerateNameCheck(name, &name_miss);
2171 2151
2172 // Check that the maps starting from the prototype haven't changed. 2152 // Check that the maps starting from the prototype haven't changed.
2173 GenerateDirectLoadGlobalFunctionPrototype(masm(), 2153 GenerateDirectLoadGlobalFunctionPrototype(masm(),
2174 Context::STRING_FUNCTION_INDEX, 2154 Context::STRING_FUNCTION_INDEX,
2175 eax, 2155 eax,
2176 &miss); 2156 &miss);
2177 ASSERT(!object.is_identical_to(holder)); 2157 ASSERT(!object.is_identical_to(holder));
2158 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2178 CheckPrototypes( 2159 CheckPrototypes(
2179 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2160 IC::CurrentTypeOf(prototype, isolate()),
2180 eax, holder, ebx, edx, edi, name, &miss); 2161 eax, holder, ebx, edx, edi, name, &miss);
2181 2162
2182 Register receiver = ebx; 2163 Register receiver = ebx;
2183 Register index = edi; 2164 Register index = edi;
2184 Register result = eax; 2165 Register result = eax;
2185 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); 2166 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize));
2186 if (argc > 0) { 2167 if (argc > 0) {
2187 __ mov(index, Operand(esp, (argc - 0) * kPointerSize)); 2168 __ mov(index, Operand(esp, (argc - 0) * kPointerSize));
2188 } else { 2169 } else {
2189 __ Set(index, Immediate(factory()->undefined_value())); 2170 __ Set(index, Immediate(factory()->undefined_value()));
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2253 } 2234 }
2254 2235
2255 GenerateNameCheck(name, &name_miss); 2236 GenerateNameCheck(name, &name_miss);
2256 2237
2257 // Check that the maps starting from the prototype haven't changed. 2238 // Check that the maps starting from the prototype haven't changed.
2258 GenerateDirectLoadGlobalFunctionPrototype(masm(), 2239 GenerateDirectLoadGlobalFunctionPrototype(masm(),
2259 Context::STRING_FUNCTION_INDEX, 2240 Context::STRING_FUNCTION_INDEX,
2260 eax, 2241 eax,
2261 &miss); 2242 &miss);
2262 ASSERT(!object.is_identical_to(holder)); 2243 ASSERT(!object.is_identical_to(holder));
2244 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2263 CheckPrototypes( 2245 CheckPrototypes(
2264 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2246 IC::CurrentTypeOf(prototype, isolate()),
2265 eax, holder, ebx, edx, edi, name, &miss); 2247 eax, holder, ebx, edx, edi, name, &miss);
2266 2248
2267 Register receiver = eax; 2249 Register receiver = eax;
2268 Register index = edi; 2250 Register index = edi;
2269 Register scratch = edx; 2251 Register scratch = edx;
2270 Register result = eax; 2252 Register result = eax;
2271 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); 2253 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize));
2272 if (argc > 0) { 2254 if (argc > 0) {
2273 __ mov(index, Operand(esp, (argc - 0) * kPointerSize)); 2255 __ mov(index, Operand(esp, (argc - 0) * kPointerSize));
2274 } else { 2256 } else {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2329 return Handle<Code>::null(); 2311 return Handle<Code>::null();
2330 } 2312 }
2331 2313
2332 Label miss; 2314 Label miss;
2333 GenerateNameCheck(name, &miss); 2315 GenerateNameCheck(name, &miss);
2334 2316
2335 if (cell.is_null()) { 2317 if (cell.is_null()) {
2336 __ mov(edx, Operand(esp, 2 * kPointerSize)); 2318 __ mov(edx, Operand(esp, 2 * kPointerSize));
2337 STATIC_ASSERT(kSmiTag == 0); 2319 STATIC_ASSERT(kSmiTag == 0);
2338 __ JumpIfSmi(edx, &miss); 2320 __ JumpIfSmi(edx, &miss);
2339 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, 2321 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
2340 name, &miss); 2322 ebx, eax, edi, name, &miss);
2341 } else { 2323 } else {
2342 ASSERT(cell->value() == *function); 2324 ASSERT(cell->value() == *function);
2343 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 2325 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2344 &miss); 2326 &miss);
2345 GenerateLoadFunctionFromCell(cell, function, &miss); 2327 GenerateLoadFunctionFromCell(cell, function, &miss);
2346 } 2328 }
2347 2329
2348 // Load the char code argument. 2330 // Load the char code argument.
2349 Register code = ebx; 2331 Register code = ebx;
2350 __ mov(code, Operand(esp, 1 * kPointerSize)); 2332 __ mov(code, Operand(esp, 1 * kPointerSize));
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2414 2396
2415 Label miss; 2397 Label miss;
2416 GenerateNameCheck(name, &miss); 2398 GenerateNameCheck(name, &miss);
2417 2399
2418 if (cell.is_null()) { 2400 if (cell.is_null()) {
2419 __ mov(edx, Operand(esp, 2 * kPointerSize)); 2401 __ mov(edx, Operand(esp, 2 * kPointerSize));
2420 2402
2421 STATIC_ASSERT(kSmiTag == 0); 2403 STATIC_ASSERT(kSmiTag == 0);
2422 __ JumpIfSmi(edx, &miss); 2404 __ JumpIfSmi(edx, &miss);
2423 2405
2424 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, 2406 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
2425 name, &miss); 2407 ebx, eax, edi, name, &miss);
2426 } else { 2408 } else {
2427 ASSERT(cell->value() == *function); 2409 ASSERT(cell->value() == *function);
2428 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 2410 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2429 &miss); 2411 &miss);
2430 GenerateLoadFunctionFromCell(cell, function, &miss); 2412 GenerateLoadFunctionFromCell(cell, function, &miss);
2431 } 2413 }
2432 2414
2433 // Load the (only) argument into eax. 2415 // Load the (only) argument into eax.
2434 __ mov(eax, Operand(esp, 1 * kPointerSize)); 2416 __ mov(eax, Operand(esp, 1 * kPointerSize));
2435 2417
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
2540 2522
2541 Label miss; 2523 Label miss;
2542 GenerateNameCheck(name, &miss); 2524 GenerateNameCheck(name, &miss);
2543 2525
2544 if (cell.is_null()) { 2526 if (cell.is_null()) {
2545 __ mov(edx, Operand(esp, 2 * kPointerSize)); 2527 __ mov(edx, Operand(esp, 2 * kPointerSize));
2546 2528
2547 STATIC_ASSERT(kSmiTag == 0); 2529 STATIC_ASSERT(kSmiTag == 0);
2548 __ JumpIfSmi(edx, &miss); 2530 __ JumpIfSmi(edx, &miss);
2549 2531
2550 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, 2532 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
2551 name, &miss); 2533 ebx, eax, edi, name, &miss);
2552 } else { 2534 } else {
2553 ASSERT(cell->value() == *function); 2535 ASSERT(cell->value() == *function);
2554 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 2536 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2555 &miss); 2537 &miss);
2556 GenerateLoadFunctionFromCell(cell, function, &miss); 2538 GenerateLoadFunctionFromCell(cell, function, &miss);
2557 } 2539 }
2558 2540
2559 // Load the (only) argument into eax. 2541 // Load the (only) argument into eax.
2560 __ mov(eax, Operand(esp, 1 * kPointerSize)); 2542 __ mov(eax, Operand(esp, 1 * kPointerSize));
2561 2543
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
2654 2636
2655 Counters* counters = isolate()->counters(); 2637 Counters* counters = isolate()->counters();
2656 __ IncrementCounter(counters->call_const(), 1); 2638 __ IncrementCounter(counters->call_const(), 1);
2657 __ IncrementCounter(counters->call_const_fast_api(), 1); 2639 __ IncrementCounter(counters->call_const_fast_api(), 1);
2658 2640
2659 // Allocate space for v8::Arguments implicit values. Must be initialized 2641 // Allocate space for v8::Arguments implicit values. Must be initialized
2660 // before calling any runtime function. 2642 // before calling any runtime function.
2661 __ sub(esp, Immediate(kFastApiCallArguments * kPointerSize)); 2643 __ sub(esp, Immediate(kFastApiCallArguments * kPointerSize));
2662 2644
2663 // Check that the maps haven't changed and find a Holder as a side effect. 2645 // Check that the maps haven't changed and find a Holder as a side effect.
2664 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, 2646 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
2665 name, depth, &miss); 2647 ebx, eax, edi, name, depth, &miss);
2666 2648
2667 // Move the return address on top of the stack. 2649 // Move the return address on top of the stack.
2668 __ mov(eax, Operand(esp, kFastApiCallArguments * kPointerSize)); 2650 __ mov(eax, Operand(esp, kFastApiCallArguments * kPointerSize));
2669 __ mov(Operand(esp, 0 * kPointerSize), eax); 2651 __ mov(Operand(esp, 0 * kPointerSize), eax);
2670 2652
2671 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains 2653 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains
2672 // duplicate of return address and will be overwritten. 2654 // duplicate of return address and will be overwritten.
2673 GenerateFastApiCall(masm(), optimization, argc); 2655 GenerateFastApiCall(masm(), optimization, argc);
2674 2656
2675 __ bind(&miss); 2657 __ bind(&miss);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2718 } 2700 }
2719 2701
2720 // Make sure that it's okay not to patch the on stack receiver 2702 // Make sure that it's okay not to patch the on stack receiver
2721 // unless we're doing a receiver map check. 2703 // unless we're doing a receiver map check.
2722 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 2704 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
2723 switch (check) { 2705 switch (check) {
2724 case RECEIVER_MAP_CHECK: 2706 case RECEIVER_MAP_CHECK:
2725 __ IncrementCounter(isolate()->counters()->call_const(), 1); 2707 __ IncrementCounter(isolate()->counters()->call_const(), 1);
2726 2708
2727 // Check that the maps haven't changed. 2709 // Check that the maps haven't changed.
2728 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, 2710 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), edx, holder,
2729 edi, name, &miss); 2711 ebx, eax, edi, name, &miss);
2730 2712
2731 // Patch the receiver on the stack with the global proxy if 2713 // Patch the receiver on the stack with the global proxy if
2732 // necessary. 2714 // necessary.
2733 if (object->IsGlobalObject()) { 2715 if (object->IsGlobalObject()) {
2734 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 2716 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2735 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); 2717 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
2736 } 2718 }
2737 break; 2719 break;
2738 2720
2739 case STRING_CHECK: 2721 case STRING_CHECK: {
2740 // Check that the object is a string. 2722 // Check that the object is a string.
2741 __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, eax); 2723 __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, eax);
2742 __ j(above_equal, &miss); 2724 __ j(above_equal, &miss);
2743 // Check that the maps starting from the prototype haven't changed. 2725 // Check that the maps starting from the prototype haven't changed.
2744 GenerateDirectLoadGlobalFunctionPrototype( 2726 GenerateDirectLoadGlobalFunctionPrototype(
2745 masm(), Context::STRING_FUNCTION_INDEX, eax, &miss); 2727 masm(), Context::STRING_FUNCTION_INDEX, eax, &miss);
2728 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2746 CheckPrototypes( 2729 CheckPrototypes(
2747 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2730 IC::CurrentTypeOf(prototype, isolate()),
2748 eax, holder, ebx, edx, edi, name, &miss); 2731 eax, holder, ebx, edx, edi, name, &miss);
2749 break; 2732 break;
2750 2733 }
2751 case SYMBOL_CHECK: 2734 case SYMBOL_CHECK: {
2752 // Check that the object is a symbol. 2735 // Check that the object is a symbol.
2753 __ CmpObjectType(edx, SYMBOL_TYPE, eax); 2736 __ CmpObjectType(edx, SYMBOL_TYPE, eax);
2754 __ j(not_equal, &miss); 2737 __ j(not_equal, &miss);
2755 // Check that the maps starting from the prototype haven't changed. 2738 // Check that the maps starting from the prototype haven't changed.
2756 GenerateDirectLoadGlobalFunctionPrototype( 2739 GenerateDirectLoadGlobalFunctionPrototype(
2757 masm(), Context::SYMBOL_FUNCTION_INDEX, eax, &miss); 2740 masm(), Context::SYMBOL_FUNCTION_INDEX, eax, &miss);
2741 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2758 CheckPrototypes( 2742 CheckPrototypes(
2759 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2743 IC::CurrentTypeOf(prototype, isolate()),
2760 eax, holder, ebx, edx, edi, name, &miss); 2744 eax, holder, ebx, edx, edi, name, &miss);
2761 break; 2745 break;
2762 2746 }
2763 case NUMBER_CHECK: { 2747 case NUMBER_CHECK: {
2764 Label fast; 2748 Label fast;
2765 // Check that the object is a smi or a heap number. 2749 // Check that the object is a smi or a heap number.
2766 __ JumpIfSmi(edx, &fast); 2750 __ JumpIfSmi(edx, &fast);
2767 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, eax); 2751 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, eax);
2768 __ j(not_equal, &miss); 2752 __ j(not_equal, &miss);
2769 __ bind(&fast); 2753 __ bind(&fast);
2770 // Check that the maps starting from the prototype haven't changed. 2754 // Check that the maps starting from the prototype haven't changed.
2771 GenerateDirectLoadGlobalFunctionPrototype( 2755 GenerateDirectLoadGlobalFunctionPrototype(
2772 masm(), Context::NUMBER_FUNCTION_INDEX, eax, &miss); 2756 masm(), Context::NUMBER_FUNCTION_INDEX, eax, &miss);
2757 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2773 CheckPrototypes( 2758 CheckPrototypes(
2774 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2759 IC::CurrentTypeOf(prototype, isolate()),
2775 eax, holder, ebx, edx, edi, name, &miss); 2760 eax, holder, ebx, edx, edi, name, &miss);
2776 break; 2761 break;
2777 } 2762 }
2778 case BOOLEAN_CHECK: { 2763 case BOOLEAN_CHECK: {
2779 GenerateBooleanCheck(edx, &miss); 2764 GenerateBooleanCheck(edx, &miss);
2780 // Check that the maps starting from the prototype haven't changed. 2765 // Check that the maps starting from the prototype haven't changed.
2781 GenerateDirectLoadGlobalFunctionPrototype( 2766 GenerateDirectLoadGlobalFunctionPrototype(
2782 masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, &miss); 2767 masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, &miss);
2768 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2783 CheckPrototypes( 2769 CheckPrototypes(
2784 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2770 IC::CurrentTypeOf(prototype, isolate()),
2785 eax, holder, ebx, edx, edi, name, &miss); 2771 eax, holder, ebx, edx, edi, name, &miss);
2786 break; 2772 break;
2787 } 2773 }
2788 } 2774 }
2789 2775
2790 Label success; 2776 Label success;
2791 __ jmp(&success); 2777 __ jmp(&success);
2792 2778
2793 // Handle call cache miss. 2779 // Handle call cache miss.
2794 __ bind(&miss); 2780 __ bind(&miss);
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
2952 // Return the generated code. 2938 // Return the generated code.
2953 return GetCode(Code::NORMAL, name); 2939 return GetCode(Code::NORMAL, name);
2954 } 2940 }
2955 2941
2956 2942
2957 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2943 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2958 Handle<JSObject> object, 2944 Handle<JSObject> object,
2959 Handle<JSObject> holder, 2945 Handle<JSObject> holder,
2960 Handle<Name> name, 2946 Handle<Name> name,
2961 Handle<ExecutableAccessorInfo> callback) { 2947 Handle<ExecutableAccessorInfo> callback) {
2962 HandlerFrontend(object, receiver(), holder, name); 2948 HandlerFrontend(IC::CurrentTypeOf(object, isolate()),
2949 receiver(), holder, name);
2963 2950
2964 __ pop(scratch1()); // remove the return address 2951 __ pop(scratch1()); // remove the return address
2965 __ push(receiver()); 2952 __ push(receiver());
2966 __ Push(callback); 2953 __ Push(callback);
2967 __ Push(name); 2954 __ Push(name);
2968 __ push(value()); 2955 __ push(value());
2969 __ push(scratch1()); // restore return address 2956 __ push(scratch1()); // restore return address
2970 2957
2971 // Do tail-call to the runtime system. 2958 // Do tail-call to the runtime system.
2972 ExternalReference store_callback_property = 2959 ExternalReference store_callback_property =
2973 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 2960 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
2974 __ TailCallExternalReference(store_callback_property, 4, 1); 2961 __ TailCallExternalReference(store_callback_property, 4, 1);
2975 2962
2976 // Return the generated code. 2963 // Return the generated code.
2977 return GetCode(kind(), Code::FAST, name); 2964 return GetCode(kind(), Code::FAST, name);
2978 } 2965 }
2979 2966
2980 2967
2981 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2968 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2982 Handle<JSObject> object, 2969 Handle<JSObject> object,
2983 Handle<JSObject> holder, 2970 Handle<JSObject> holder,
2984 Handle<Name> name, 2971 Handle<Name> name,
2985 const CallOptimization& call_optimization) { 2972 const CallOptimization& call_optimization) {
2986 HandlerFrontend(object, receiver(), holder, name); 2973 HandlerFrontend(IC::CurrentTypeOf(object, isolate()),
2974 receiver(), holder, name);
2987 2975
2988 Register values[] = { value() }; 2976 Register values[] = { value() };
2989 GenerateFastApiCall( 2977 GenerateFastApiCall(
2990 masm(), call_optimization, receiver(), scratch1(), 2978 masm(), call_optimization, receiver(), scratch1(),
2991 scratch2(), this->name(), 1, values); 2979 scratch2(), this->name(), 1, values);
2992 2980
2993 // Return the generated code. 2981 // Return the generated code.
2994 return GetCode(kind(), Code::FAST, name); 2982 return GetCode(kind(), Code::FAST, name);
2995 } 2983 }
2996 2984
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
3083 } 3071 }
3084 __ bind(&miss); 3072 __ bind(&miss);
3085 TailCallBuiltin(masm(), MissBuiltin(kind())); 3073 TailCallBuiltin(masm(), MissBuiltin(kind()));
3086 3074
3087 // Return the generated code. 3075 // Return the generated code.
3088 return GetICCode( 3076 return GetICCode(
3089 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 3077 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
3090 } 3078 }
3091 3079
3092 3080
3093 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( 3081 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<Type> type,
3094 Handle<Object> object, 3082 Handle<JSObject> last,
3095 Handle<JSObject> last, 3083 Handle<Name> name) {
3096 Handle<Name> name, 3084 NonexistentHandlerFrontend(type, last, name);
3097 Handle<JSGlobalObject> global) {
3098 NonexistentHandlerFrontend(object, last, name, global);
3099 3085
3100 // Return undefined if maps of the full prototype chain are still the 3086 // Return undefined if maps of the full prototype chain are still the
3101 // same and no global property with this name contains a value. 3087 // same and no global property with this name contains a value.
3102 __ mov(eax, isolate()->factory()->undefined_value()); 3088 __ mov(eax, isolate()->factory()->undefined_value());
3103 __ ret(0); 3089 __ ret(0);
3104 3090
3105 // Return the generated code. 3091 // Return the generated code.
3106 return GetCode(kind(), Code::FAST, name); 3092 return GetCode(kind(), Code::FAST, name);
3107 } 3093 }
3108 3094
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
3179 } 3165 }
3180 __ ret(0); 3166 __ ret(0);
3181 } 3167 }
3182 3168
3183 3169
3184 #undef __ 3170 #undef __
3185 #define __ ACCESS_MASM(masm()) 3171 #define __ ACCESS_MASM(masm())
3186 3172
3187 3173
3188 Handle<Code> LoadStubCompiler::CompileLoadGlobal( 3174 Handle<Code> LoadStubCompiler::CompileLoadGlobal(
3189 Handle<Object> object, 3175 Handle<Type> type,
3190 Handle<GlobalObject> global, 3176 Handle<GlobalObject> global,
3191 Handle<PropertyCell> cell, 3177 Handle<PropertyCell> cell,
3192 Handle<Name> name, 3178 Handle<Name> name,
3193 bool is_dont_delete) { 3179 bool is_dont_delete) {
3194 Label miss; 3180 Label miss;
3195 3181
3196 HandlerFrontendHeader(object, receiver(), global, name, &miss); 3182 HandlerFrontendHeader(type, receiver(), global, name, &miss);
3197 // Get the value from the cell. 3183 // Get the value from the cell.
3198 if (Serializer::enabled()) { 3184 if (Serializer::enabled()) {
3199 __ mov(eax, Immediate(cell)); 3185 __ mov(eax, Immediate(cell));
3200 __ mov(eax, FieldOperand(eax, PropertyCell::kValueOffset)); 3186 __ mov(eax, FieldOperand(eax, PropertyCell::kValueOffset));
3201 } else { 3187 } else {
3202 __ mov(eax, Operand::ForCell(cell)); 3188 __ mov(eax, Operand::ForCell(cell));
3203 } 3189 }
3204 3190
3205 // Check for deleted property if property can actually be deleted. 3191 // Check for deleted property if property can actually be deleted.
3206 if (!is_dont_delete) { 3192 if (!is_dont_delete) {
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
3314 // ----------------------------------- 3300 // -----------------------------------
3315 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 3301 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
3316 } 3302 }
3317 3303
3318 3304
3319 #undef __ 3305 #undef __
3320 3306
3321 } } // namespace v8::internal 3307 } } // namespace v8::internal
3322 3308
3323 #endif // V8_TARGET_ARCH_IA32 3309 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/simulator-ia32.cc ('k') | src/ic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698