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

Side by Side Diff: src/x64/stub-cache-x64.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/x64/simulator-x64.cc ('k') | test/benchmarks/testcfg.py » ('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 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 __ push(receiver); 372 __ push(receiver);
373 __ push(holder); 373 __ push(holder);
374 } 374 }
375 375
376 376
377 static void CompileCallLoadPropertyWithInterceptor( 377 static void CompileCallLoadPropertyWithInterceptor(
378 MacroAssembler* masm, 378 MacroAssembler* masm,
379 Register receiver, 379 Register receiver,
380 Register holder, 380 Register holder,
381 Register name, 381 Register name,
382 Handle<JSObject> holder_obj) { 382 Handle<JSObject> holder_obj,
383 IC::UtilityId id) {
383 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 384 PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
384 385 __ CallExternalReference(
385 ExternalReference ref = 386 ExternalReference(IC_Utility(id), masm->isolate()),
386 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly), 387 StubCache::kInterceptorArgsLength);
387 masm->isolate());
388 __ Set(rax, StubCache::kInterceptorArgsLength);
389 __ LoadAddress(rbx, ref);
390
391 CEntryStub stub(1);
392 __ CallStub(&stub);
393 } 388 }
394 389
395 390
396 // Number of pointers to be reserved on stack for fast API call. 391 // Number of pointers to be reserved on stack for fast API call.
397 static const int kFastApiCallArguments = FunctionCallbackArguments::kArgsLength; 392 static const int kFastApiCallArguments = FunctionCallbackArguments::kArgsLength;
398 393
399 394
400 // Reserves space for the extra arguments to API function in the 395 // Reserves space for the extra arguments to API function in the
401 // caller's frame. 396 // caller's frame.
402 // 397 //
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 if (can_do_fast_api_call) { 708 if (can_do_fast_api_call) {
714 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1); 709 __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1);
715 ReserveSpaceForFastApiCall(masm, scratch1); 710 ReserveSpaceForFastApiCall(masm, scratch1);
716 } 711 }
717 712
718 // Check that the maps from receiver to interceptor's holder 713 // Check that the maps from receiver to interceptor's holder
719 // haven't changed and thus we can invoke interceptor. 714 // haven't changed and thus we can invoke interceptor.
720 Label miss_cleanup; 715 Label miss_cleanup;
721 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; 716 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label;
722 Register holder = 717 Register holder =
723 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, 718 stub_compiler_->CheckPrototypes(
724 scratch1, scratch2, scratch3, 719 IC::CurrentTypeOf(object, masm->isolate()), receiver,
725 name, depth1, miss); 720 interceptor_holder, scratch1, scratch2, scratch3,
721 name, depth1, miss);
726 722
727 // Invoke an interceptor and if it provides a value, 723 // Invoke an interceptor and if it provides a value,
728 // branch to |regular_invoke|. 724 // branch to |regular_invoke|.
729 Label regular_invoke; 725 Label regular_invoke;
730 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, 726 LoadWithInterceptor(masm, receiver, holder, interceptor_holder,
731 &regular_invoke); 727 &regular_invoke);
732 728
733 // Interceptor returned nothing for this property. Try to use cached 729 // Interceptor returned nothing for this property. Try to use cached
734 // constant function. 730 // constant function.
735 731
736 // Check that the maps from interceptor's holder to constant function's 732 // Check that the maps from interceptor's holder to constant function's
737 // holder haven't changed and thus we can use cached constant function. 733 // holder haven't changed and thus we can use cached constant function.
738 if (*interceptor_holder != lookup->holder()) { 734 if (*interceptor_holder != lookup->holder()) {
739 stub_compiler_->CheckPrototypes(interceptor_holder, receiver, 735 stub_compiler_->CheckPrototypes(
740 Handle<JSObject>(lookup->holder()), 736 IC::CurrentTypeOf(interceptor_holder, masm->isolate()), receiver,
741 scratch1, scratch2, scratch3, 737 handle(lookup->holder()), scratch1, scratch2, scratch3,
742 name, depth2, miss); 738 name, depth2, miss);
743 } else { 739 } else {
744 // CheckPrototypes has a side effect of fetching a 'holder' 740 // CheckPrototypes has a side effect of fetching a 'holder'
745 // for API (object which is instanceof for the signature). It's 741 // for API (object which is instanceof for the signature). It's
746 // safe to omit it here, as if present, it should be fetched 742 // safe to omit it here, as if present, it should be fetched
747 // by the previous CheckPrototypes. 743 // by the previous CheckPrototypes.
748 ASSERT(depth2 == kInvalidProtoDepth); 744 ASSERT(depth2 == kInvalidProtoDepth);
749 } 745 }
750 746
751 // Invoke function. 747 // Invoke function.
752 if (can_do_fast_api_call) { 748 if (can_do_fast_api_call) {
(...skipping 25 matching lines...) Expand all
778 void CompileRegular(MacroAssembler* masm, 774 void CompileRegular(MacroAssembler* masm,
779 Handle<JSObject> object, 775 Handle<JSObject> object,
780 Register receiver, 776 Register receiver,
781 Register scratch1, 777 Register scratch1,
782 Register scratch2, 778 Register scratch2,
783 Register scratch3, 779 Register scratch3,
784 Handle<Name> name, 780 Handle<Name> name,
785 Handle<JSObject> interceptor_holder, 781 Handle<JSObject> interceptor_holder,
786 Label* miss_label) { 782 Label* miss_label) {
787 Register holder = 783 Register holder =
788 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, 784 stub_compiler_->CheckPrototypes(
789 scratch1, scratch2, scratch3, 785 IC::CurrentTypeOf(object, masm->isolate()), receiver,
790 name, miss_label); 786 interceptor_holder, scratch1, scratch2, scratch3, name, miss_label);
791 787
792 FrameScope scope(masm, StackFrame::INTERNAL); 788 FrameScope scope(masm, StackFrame::INTERNAL);
793 // Save the name_ register across the call. 789 // Save the name_ register across the call.
794 __ push(name_); 790 __ push(name_);
795 791
796 PushInterceptorArguments(masm, receiver, holder, name_, interceptor_holder); 792 CompileCallLoadPropertyWithInterceptor(
797 793 masm, receiver, holder, name_, interceptor_holder,
798 __ CallExternalReference( 794 IC::kLoadPropertyWithInterceptorForCall);
799 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall),
800 masm->isolate()),
801 StubCache::kInterceptorArgsLength);
802 795
803 // Restore the name_ register. 796 // Restore the name_ register.
804 __ pop(name_); 797 __ pop(name_);
805 798
806 // Leave the internal frame. 799 // Leave the internal frame.
807 } 800 }
808 801
809 void LoadWithInterceptor(MacroAssembler* masm, 802 void LoadWithInterceptor(MacroAssembler* masm,
810 Register receiver, 803 Register receiver,
811 Register holder, 804 Register holder,
812 Handle<JSObject> holder_obj, 805 Handle<JSObject> holder_obj,
813 Label* interceptor_succeeded) { 806 Label* interceptor_succeeded) {
814 { 807 {
815 FrameScope scope(masm, StackFrame::INTERNAL); 808 FrameScope scope(masm, StackFrame::INTERNAL);
816 __ push(holder); // Save the holder. 809 __ push(holder); // Save the holder.
817 __ push(name_); // Save the name. 810 __ push(name_); // Save the name.
818 811
819 CompileCallLoadPropertyWithInterceptor(masm, 812 CompileCallLoadPropertyWithInterceptor(
820 receiver, 813 masm, receiver, holder, name_, holder_obj,
821 holder, 814 IC::kLoadPropertyWithInterceptorOnly);
822 name_,
823 holder_obj);
824 815
825 __ pop(name_); // Restore the name. 816 __ pop(name_); // Restore the name.
826 __ pop(receiver); // Restore the holder. 817 __ pop(receiver); // Restore the holder.
827 // Leave the internal frame. 818 // Leave the internal frame.
828 } 819 }
829 820
830 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex); 821 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex);
831 __ j(not_equal, interceptor_succeeded); 822 __ j(not_equal, interceptor_succeeded);
832 } 823 }
833 824
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
1115 EMIT_REMEMBERED_SET, smi_check); 1106 EMIT_REMEMBERED_SET, smi_check);
1116 } 1107 }
1117 } 1108 }
1118 1109
1119 // Return the value (register rax). 1110 // Return the value (register rax).
1120 ASSERT(value_reg.is(rax)); 1111 ASSERT(value_reg.is(rax));
1121 __ ret(0); 1112 __ ret(0);
1122 } 1113 }
1123 1114
1124 1115
1125 void StubCompiler::GenerateCheckPropertyCells(MacroAssembler* masm,
1126 Handle<JSObject> object,
1127 Handle<JSObject> holder,
1128 Handle<Name> name,
1129 Register scratch,
1130 Label* miss) {
1131 Handle<JSObject> current = object;
1132 while (!current.is_identical_to(holder)) {
1133 if (current->IsJSGlobalObject()) {
1134 GenerateCheckPropertyCell(masm,
1135 Handle<JSGlobalObject>::cast(current),
1136 name,
1137 scratch,
1138 miss);
1139 }
1140 current = Handle<JSObject>(JSObject::cast(current->GetPrototype()));
1141 }
1142 }
1143
1144
1145 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { 1116 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
1146 __ jmp(code, RelocInfo::CODE_TARGET); 1117 __ jmp(code, RelocInfo::CODE_TARGET);
1147 } 1118 }
1148 1119
1149 1120
1150 #undef __ 1121 #undef __
1151 #define __ ACCESS_MASM((masm())) 1122 #define __ ACCESS_MASM((masm()))
1152 1123
1153 1124
1154 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, 1125 Register StubCompiler::CheckPrototypes(Handle<Type> type,
1155 Register object_reg, 1126 Register object_reg,
1156 Handle<JSObject> holder, 1127 Handle<JSObject> holder,
1157 Register holder_reg, 1128 Register holder_reg,
1158 Register scratch1, 1129 Register scratch1,
1159 Register scratch2, 1130 Register scratch2,
1160 Handle<Name> name, 1131 Handle<Name> name,
1161 int save_at_depth, 1132 int save_at_depth,
1162 Label* miss, 1133 Label* miss,
1163 PrototypeCheckType check) { 1134 PrototypeCheckType check) {
1135 Handle<Map> receiver_map(IC::TypeToMap(*type, isolate()));
1164 // Make sure that the type feedback oracle harvests the receiver map. 1136 // Make sure that the type feedback oracle harvests the receiver map.
1165 // TODO(svenpanne) Remove this hack when all ICs are reworked. 1137 // TODO(svenpanne) Remove this hack when all ICs are reworked.
1166 __ Move(scratch1, Handle<Map>(object->map())); 1138 __ Move(scratch1, receiver_map);
1167 1139
1168 Handle<JSObject> first = object;
1169 // Make sure there's no overlap between holder and object registers. 1140 // Make sure there's no overlap between holder and object registers.
1170 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 1141 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
1171 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 1142 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
1172 && !scratch2.is(scratch1)); 1143 && !scratch2.is(scratch1));
1173 1144
1174 // Keep track of the current object in register reg. On the first 1145 // Keep track of the current object in register reg. On the first
1175 // iteration, reg is an alias for object_reg, on later iterations, 1146 // iteration, reg is an alias for object_reg, on later iterations,
1176 // it is an alias for holder_reg. 1147 // it is an alias for holder_reg.
1177 Register reg = object_reg; 1148 Register reg = object_reg;
1178 int depth = 0; 1149 int depth = 0;
1179 1150
1180 StackArgumentsAccessor args(rsp, kFastApiCallArguments, 1151 StackArgumentsAccessor args(rsp, kFastApiCallArguments,
1181 ARGUMENTS_DONT_CONTAIN_RECEIVER); 1152 ARGUMENTS_DONT_CONTAIN_RECEIVER);
1182 const int kHolderIndex = kFastApiCallArguments - 1 - 1153 const int kHolderIndex = kFastApiCallArguments - 1 -
1183 FunctionCallbackArguments::kHolderIndex; 1154 FunctionCallbackArguments::kHolderIndex;
1184 1155
1185 if (save_at_depth == depth) { 1156 if (save_at_depth == depth) {
1186 __ movq(args.GetArgumentOperand(kHolderIndex), object_reg); 1157 __ movq(args.GetArgumentOperand(kHolderIndex), object_reg);
1187 } 1158 }
1188 1159
1189 // Check the maps in the prototype chain. 1160 Handle<JSObject> current = Handle<JSObject>::null();
1190 // Traverse the prototype chain from the object and do map checks. 1161 if (type->IsConstant()) current = Handle<JSObject>::cast(type->AsConstant());
1191 Handle<JSObject> current = object; 1162 Handle<JSObject> prototype = Handle<JSObject>::null();
1192 while (!current.is_identical_to(holder)) { 1163 Handle<Map> current_map = receiver_map;
1164 Handle<Map> holder_map(holder->map());
1165 // Traverse the prototype chain and check the maps in the prototype chain for
1166 // fast and global objects or do negative lookup for normal objects.
1167 while (!current_map.is_identical_to(holder_map)) {
1193 ++depth; 1168 ++depth;
1194 1169
1195 // Only global objects and objects that do not require access 1170 // Only global objects and objects that do not require access
1196 // checks are allowed in stubs. 1171 // checks are allowed in stubs.
1197 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); 1172 ASSERT(current_map->IsJSGlobalProxyMap() ||
1173 !current_map->is_access_check_needed());
1198 1174
1199 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); 1175 prototype = handle(JSObject::cast(current_map->prototype()));
1200 if (!current->HasFastProperties() && 1176 if (current_map->is_dictionary_map() &&
1201 !current->IsJSGlobalObject() && 1177 !current_map->IsJSGlobalObjectMap() &&
1202 !current->IsJSGlobalProxy()) { 1178 !current_map->IsJSGlobalProxyMap()) {
1203 if (!name->IsUniqueName()) { 1179 if (!name->IsUniqueName()) {
1204 ASSERT(name->IsString()); 1180 ASSERT(name->IsString());
1205 name = factory()->InternalizeString(Handle<String>::cast(name)); 1181 name = factory()->InternalizeString(Handle<String>::cast(name));
1206 } 1182 }
1207 ASSERT(current->property_dictionary()->FindEntry(*name) == 1183 ASSERT(current.is_null() ||
1184 current->property_dictionary()->FindEntry(*name) ==
1208 NameDictionary::kNotFound); 1185 NameDictionary::kNotFound);
1209 1186
1210 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, 1187 GenerateDictionaryNegativeLookup(masm(), miss, reg, name,
1211 scratch1, scratch2); 1188 scratch1, scratch2);
1212 1189
1213 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 1190 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
1214 reg = holder_reg; // From now on the object will be in holder_reg. 1191 reg = holder_reg; // From now on the object will be in holder_reg.
1215 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 1192 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
1216 } else { 1193 } else {
1217 bool in_new_space = heap()->InNewSpace(*prototype); 1194 bool in_new_space = heap()->InNewSpace(*prototype);
1218 Handle<Map> current_map(current->map());
1219 if (in_new_space) { 1195 if (in_new_space) {
1220 // Save the map in scratch1 for later. 1196 // Save the map in scratch1 for later.
1221 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 1197 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
1222 } 1198 }
1223 if (!current.is_identical_to(first) || check == CHECK_ALL_MAPS) { 1199 if (depth != 1 || check == CHECK_ALL_MAPS) {
1224 __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK); 1200 __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK);
1225 } 1201 }
1226 1202
1227 // Check access rights to the global object. This has to happen after 1203 // Check access rights to the global object. This has to happen after
1228 // the map check so that we know that the object is actually a global 1204 // the map check so that we know that the object is actually a global
1229 // object. 1205 // object.
1230 if (current->IsJSGlobalProxy()) { 1206 if (current_map->IsJSGlobalProxyMap()) {
1231 __ CheckAccessGlobalProxy(reg, scratch2, miss); 1207 __ CheckAccessGlobalProxy(reg, scratch2, miss);
1208 } else if (current_map->IsJSGlobalObjectMap()) {
1209 GenerateCheckPropertyCell(
1210 masm(), Handle<JSGlobalObject>::cast(current), name,
1211 scratch2, miss);
1232 } 1212 }
1233 reg = holder_reg; // From now on the object will be in holder_reg. 1213 reg = holder_reg; // From now on the object will be in holder_reg.
1234 1214
1235 if (in_new_space) { 1215 if (in_new_space) {
1236 // The prototype is in new space; we cannot store a reference to it 1216 // The prototype is in new space; we cannot store a reference to it
1237 // in the code. Load it from the map. 1217 // in the code. Load it from the map.
1238 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 1218 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
1239 } else { 1219 } else {
1240 // The prototype is in old space; load it directly. 1220 // The prototype is in old space; load it directly.
1241 __ Move(reg, prototype); 1221 __ Move(reg, prototype);
1242 } 1222 }
1243 } 1223 }
1244 1224
1245 if (save_at_depth == depth) { 1225 if (save_at_depth == depth) {
1246 __ movq(args.GetArgumentOperand(kHolderIndex), reg); 1226 __ movq(args.GetArgumentOperand(kHolderIndex), reg);
1247 } 1227 }
1248 1228
1249 // Go to the next object in the prototype chain. 1229 // Go to the next object in the prototype chain.
1250 current = prototype; 1230 current = prototype;
1231 current_map = handle(current->map());
1251 } 1232 }
1252 ASSERT(current.is_identical_to(holder));
1253 1233
1254 // Log the check depth. 1234 // Log the check depth.
1255 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 1235 LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
1256 1236
1257 if (!holder.is_identical_to(first) || check == CHECK_ALL_MAPS) { 1237 if (depth != 0 || check == CHECK_ALL_MAPS) {
1258 // Check the holder map. 1238 // Check the holder map.
1259 __ CheckMap(reg, Handle<Map>(holder->map()), miss, DONT_DO_SMI_CHECK); 1239 __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK);
1260 } 1240 }
1261 1241
1262 // Perform security check for access to the global object. 1242 // Perform security check for access to the global object.
1263 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); 1243 ASSERT(current_map->IsJSGlobalProxyMap() ||
1264 if (current->IsJSGlobalProxy()) { 1244 !current_map->is_access_check_needed());
1245 if (current_map->IsJSGlobalProxyMap()) {
1265 __ CheckAccessGlobalProxy(reg, scratch1, miss); 1246 __ CheckAccessGlobalProxy(reg, scratch1, miss);
1266 } 1247 }
1267 1248
1268 // If we've skipped any global objects, it's not enough to verify that
1269 // their maps haven't changed. We also need to check that the property
1270 // cell for the property is still empty.
1271 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss);
1272
1273 // Return the register containing the holder. 1249 // Return the register containing the holder.
1274 return reg; 1250 return reg;
1275 } 1251 }
1276 1252
1277 1253
1278 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { 1254 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) {
1279 if (!miss->is_unused()) { 1255 if (!miss->is_unused()) {
1280 Label success; 1256 Label success;
1281 __ jmp(&success); 1257 __ jmp(&success);
1282 __ bind(miss); 1258 __ bind(miss);
1283 TailCallBuiltin(masm(), MissBuiltin(kind())); 1259 TailCallBuiltin(masm(), MissBuiltin(kind()));
1284 __ bind(&success); 1260 __ bind(&success);
1285 } 1261 }
1286 } 1262 }
1287 1263
1288 1264
1289 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { 1265 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) {
1290 if (!miss->is_unused()) { 1266 if (!miss->is_unused()) {
1291 Label success; 1267 Label success;
1292 __ jmp(&success); 1268 __ jmp(&success);
1293 GenerateRestoreName(masm(), miss, name); 1269 GenerateRestoreName(masm(), miss, name);
1294 TailCallBuiltin(masm(), MissBuiltin(kind())); 1270 TailCallBuiltin(masm(), MissBuiltin(kind()));
1295 __ bind(&success); 1271 __ bind(&success);
1296 } 1272 }
1297 } 1273 }
1298 1274
1299 1275
1300 Register LoadStubCompiler::CallbackHandlerFrontend( 1276 Register LoadStubCompiler::CallbackHandlerFrontend(
1301 Handle<Object> object, 1277 Handle<Type> type,
1302 Register object_reg, 1278 Register object_reg,
1303 Handle<JSObject> holder, 1279 Handle<JSObject> holder,
1304 Handle<Name> name, 1280 Handle<Name> name,
1305 Handle<Object> callback) { 1281 Handle<Object> callback) {
1306 Label miss; 1282 Label miss;
1307 1283
1308 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); 1284 Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss);
1309 1285
1310 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 1286 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
1311 ASSERT(!reg.is(scratch2())); 1287 ASSERT(!reg.is(scratch2()));
1312 ASSERT(!reg.is(scratch3())); 1288 ASSERT(!reg.is(scratch3()));
1313 ASSERT(!reg.is(scratch4())); 1289 ASSERT(!reg.is(scratch4()));
1314 1290
1315 // Load the properties dictionary. 1291 // Load the properties dictionary.
1316 Register dictionary = scratch4(); 1292 Register dictionary = scratch4();
1317 __ movq(dictionary, FieldOperand(reg, JSObject::kPropertiesOffset)); 1293 __ movq(dictionary, FieldOperand(reg, JSObject::kPropertiesOffset));
1318 1294
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
1508 1484
1509 if (must_preserve_receiver_reg) { 1485 if (must_preserve_receiver_reg) {
1510 __ push(receiver()); 1486 __ push(receiver());
1511 } 1487 }
1512 __ push(holder_reg); 1488 __ push(holder_reg);
1513 __ push(this->name()); 1489 __ push(this->name());
1514 1490
1515 // Invoke an interceptor. Note: map checks from receiver to 1491 // Invoke an interceptor. Note: map checks from receiver to
1516 // interceptor's holder has been compiled before (see a caller 1492 // interceptor's holder has been compiled before (see a caller
1517 // of this method.) 1493 // of this method.)
1518 CompileCallLoadPropertyWithInterceptor(masm(), 1494 CompileCallLoadPropertyWithInterceptor(
1519 receiver(), 1495 masm(), receiver(), holder_reg, this->name(), interceptor_holder,
1520 holder_reg, 1496 IC::kLoadPropertyWithInterceptorOnly);
1521 this->name(),
1522 interceptor_holder);
1523 1497
1524 // Check if interceptor provided a value for property. If it's 1498 // Check if interceptor provided a value for property. If it's
1525 // the case, return immediately. 1499 // the case, return immediately.
1526 Label interceptor_failed; 1500 Label interceptor_failed;
1527 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex); 1501 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex);
1528 __ j(equal, &interceptor_failed); 1502 __ j(equal, &interceptor_failed);
1529 frame_scope.GenerateLeaveFrame(); 1503 frame_scope.GenerateLeaveFrame();
1530 __ ret(0); 1504 __ ret(0);
1531 1505
1532 __ bind(&interceptor_failed); 1506 __ bind(&interceptor_failed);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1568 Handle<Name> name, 1542 Handle<Name> name,
1569 Label* miss) { 1543 Label* miss) {
1570 ASSERT(holder->IsGlobalObject()); 1544 ASSERT(holder->IsGlobalObject());
1571 1545
1572 StackArgumentsAccessor args(rsp, arguments()); 1546 StackArgumentsAccessor args(rsp, arguments());
1573 __ movq(rdx, args.GetReceiverOperand()); 1547 __ movq(rdx, args.GetReceiverOperand());
1574 1548
1575 1549
1576 // Check that the maps haven't changed. 1550 // Check that the maps haven't changed.
1577 __ JumpIfSmi(rdx, miss); 1551 __ JumpIfSmi(rdx, miss);
1578 CheckPrototypes(object, rdx, holder, rbx, rax, rdi, name, miss); 1552 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder,
1553 rbx, rax, rdi, name, miss);
1579 } 1554 }
1580 1555
1581 1556
1582 void CallStubCompiler::GenerateLoadFunctionFromCell( 1557 void CallStubCompiler::GenerateLoadFunctionFromCell(
1583 Handle<Cell> cell, 1558 Handle<Cell> cell,
1584 Handle<JSFunction> function, 1559 Handle<JSFunction> function,
1585 Label* miss) { 1560 Label* miss) {
1586 // Get the value from the cell. 1561 // Get the value from the cell.
1587 __ Move(rdi, cell); 1562 __ Move(rdi, cell);
1588 __ movq(rdi, FieldOperand(rdi, Cell::kValueOffset)); 1563 __ movq(rdi, FieldOperand(rdi, Cell::kValueOffset));
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1634 1609
1635 GenerateNameCheck(name, &miss); 1610 GenerateNameCheck(name, &miss);
1636 1611
1637 StackArgumentsAccessor args(rsp, arguments()); 1612 StackArgumentsAccessor args(rsp, arguments());
1638 __ movq(rdx, args.GetReceiverOperand()); 1613 __ movq(rdx, args.GetReceiverOperand());
1639 1614
1640 // Check that the receiver isn't a smi. 1615 // Check that the receiver isn't a smi.
1641 __ JumpIfSmi(rdx, &miss); 1616 __ JumpIfSmi(rdx, &miss);
1642 1617
1643 // Do the right check and compute the holder register. 1618 // Do the right check and compute the holder register.
1644 Register reg = CheckPrototypes(object, rdx, holder, rbx, rax, rdi, 1619 Register reg = CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx,
1645 name, &miss); 1620 holder, rbx, rax, rdi, name, &miss);
1646 1621
1647 GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder), 1622 GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder),
1648 index.translate(holder), Representation::Tagged()); 1623 index.translate(holder), Representation::Tagged());
1649 1624
1650 // Check that the function really is a function. 1625 // Check that the function really is a function.
1651 __ JumpIfSmi(rdi, &miss); 1626 __ JumpIfSmi(rdi, &miss);
1652 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx); 1627 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx);
1653 __ j(not_equal, &miss); 1628 __ j(not_equal, &miss);
1654 1629
1655 // Patch the receiver on the stack with the global proxy if 1630 // Patch the receiver on the stack with the global proxy if
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1687 // Check that function is still array 1662 // Check that function is still array
1688 const int argc = arguments().immediate(); 1663 const int argc = arguments().immediate();
1689 StackArgumentsAccessor args(rsp, argc); 1664 StackArgumentsAccessor args(rsp, argc);
1690 GenerateNameCheck(name, &miss); 1665 GenerateNameCheck(name, &miss);
1691 1666
1692 if (cell.is_null()) { 1667 if (cell.is_null()) {
1693 __ movq(rdx, args.GetReceiverOperand()); 1668 __ movq(rdx, args.GetReceiverOperand());
1694 1669
1695 // Check that the receiver isn't a smi. 1670 // Check that the receiver isn't a smi.
1696 __ JumpIfSmi(rdx, &miss); 1671 __ JumpIfSmi(rdx, &miss);
1697 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 1672 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder,
1698 name, &miss); 1673 rbx, rax, rdi, name, &miss);
1699 } else { 1674 } else {
1700 ASSERT(cell->value() == *function); 1675 ASSERT(cell->value() == *function);
1701 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 1676 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
1702 &miss); 1677 &miss);
1703 GenerateLoadFunctionFromCell(cell, function, &miss); 1678 GenerateLoadFunctionFromCell(cell, function, &miss);
1704 } 1679 }
1705 1680
1706 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); 1681 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite();
1707 site->SetElementsKind(GetInitialFastElementsKind()); 1682 site->SetElementsKind(GetInitialFastElementsKind());
1708 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); 1683 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1746 Label miss; 1721 Label miss;
1747 GenerateNameCheck(name, &miss); 1722 GenerateNameCheck(name, &miss);
1748 1723
1749 const int argc = arguments().immediate(); 1724 const int argc = arguments().immediate();
1750 StackArgumentsAccessor args(rsp, argc); 1725 StackArgumentsAccessor args(rsp, argc);
1751 __ movq(rdx, args.GetReceiverOperand()); 1726 __ movq(rdx, args.GetReceiverOperand());
1752 1727
1753 // Check that the receiver isn't a smi. 1728 // Check that the receiver isn't a smi.
1754 __ JumpIfSmi(rdx, &miss); 1729 __ JumpIfSmi(rdx, &miss);
1755 1730
1756 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 1731 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder,
1757 name, &miss); 1732 rbx, rax, rdi, name, &miss);
1758 1733
1759 if (argc == 0) { 1734 if (argc == 0) {
1760 // Noop, return the length. 1735 // Noop, return the length.
1761 __ movq(rax, FieldOperand(rdx, JSArray::kLengthOffset)); 1736 __ movq(rax, FieldOperand(rdx, JSArray::kLengthOffset));
1762 __ ret((argc + 1) * kPointerSize); 1737 __ ret((argc + 1) * kPointerSize);
1763 } else { 1738 } else {
1764 Label call_builtin; 1739 Label call_builtin;
1765 1740
1766 if (argc == 1) { // Otherwise fall through to call builtin. 1741 if (argc == 1) { // Otherwise fall through to call builtin.
1767 Label attempt_to_grow_elements, with_write_barrier, check_double; 1742 Label attempt_to_grow_elements, with_write_barrier, check_double;
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
2001 Label miss, return_undefined, call_builtin; 1976 Label miss, return_undefined, call_builtin;
2002 GenerateNameCheck(name, &miss); 1977 GenerateNameCheck(name, &miss);
2003 1978
2004 const int argc = arguments().immediate(); 1979 const int argc = arguments().immediate();
2005 StackArgumentsAccessor args(rsp, argc); 1980 StackArgumentsAccessor args(rsp, argc);
2006 __ movq(rdx, args.GetReceiverOperand()); 1981 __ movq(rdx, args.GetReceiverOperand());
2007 1982
2008 // Check that the receiver isn't a smi. 1983 // Check that the receiver isn't a smi.
2009 __ JumpIfSmi(rdx, &miss); 1984 __ JumpIfSmi(rdx, &miss);
2010 1985
2011 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 1986 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder,
2012 name, &miss); 1987 rbx, rax, rdi, name, &miss);
2013 1988
2014 // Get the elements array of the object. 1989 // Get the elements array of the object.
2015 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset)); 1990 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset));
2016 1991
2017 // Check that the elements are in fast mode and writable. 1992 // Check that the elements are in fast mode and writable.
2018 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), 1993 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset),
2019 Heap::kFixedArrayMapRootIndex); 1994 Heap::kFixedArrayMapRootIndex);
2020 __ j(not_equal, &call_builtin); 1995 __ j(not_equal, &call_builtin);
2021 1996
2022 // Get the array's length into rcx and calculate new length. 1997 // Get the array's length into rcx and calculate new length.
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2093 index_out_of_range_label = &miss; 2068 index_out_of_range_label = &miss;
2094 } 2069 }
2095 GenerateNameCheck(name, &name_miss); 2070 GenerateNameCheck(name, &name_miss);
2096 2071
2097 // Check that the maps starting from the prototype haven't changed. 2072 // Check that the maps starting from the prototype haven't changed.
2098 GenerateDirectLoadGlobalFunctionPrototype(masm(), 2073 GenerateDirectLoadGlobalFunctionPrototype(masm(),
2099 Context::STRING_FUNCTION_INDEX, 2074 Context::STRING_FUNCTION_INDEX,
2100 rax, 2075 rax,
2101 &miss); 2076 &miss);
2102 ASSERT(!object.is_identical_to(holder)); 2077 ASSERT(!object.is_identical_to(holder));
2078 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2103 CheckPrototypes( 2079 CheckPrototypes(
2104 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2080 IC::CurrentTypeOf(prototype, isolate()),
2105 rax, holder, rbx, rdx, rdi, name, &miss); 2081 rax, holder, rbx, rdx, rdi, name, &miss);
2106 2082
2107 Register receiver = rbx; 2083 Register receiver = rbx;
2108 Register index = rdi; 2084 Register index = rdi;
2109 Register result = rax; 2085 Register result = rax;
2110 __ movq(receiver, args.GetReceiverOperand()); 2086 __ movq(receiver, args.GetReceiverOperand());
2111 if (argc > 0) { 2087 if (argc > 0) {
2112 __ movq(index, args.GetArgumentOperand(1)); 2088 __ movq(index, args.GetArgumentOperand(1));
2113 } else { 2089 } else {
2114 __ LoadRoot(index, Heap::kUndefinedValueRootIndex); 2090 __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2175 index_out_of_range_label = &miss; 2151 index_out_of_range_label = &miss;
2176 } 2152 }
2177 GenerateNameCheck(name, &name_miss); 2153 GenerateNameCheck(name, &name_miss);
2178 2154
2179 // Check that the maps starting from the prototype haven't changed. 2155 // Check that the maps starting from the prototype haven't changed.
2180 GenerateDirectLoadGlobalFunctionPrototype(masm(), 2156 GenerateDirectLoadGlobalFunctionPrototype(masm(),
2181 Context::STRING_FUNCTION_INDEX, 2157 Context::STRING_FUNCTION_INDEX,
2182 rax, 2158 rax,
2183 &miss); 2159 &miss);
2184 ASSERT(!object.is_identical_to(holder)); 2160 ASSERT(!object.is_identical_to(holder));
2161 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2185 CheckPrototypes( 2162 CheckPrototypes(
2186 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2163 IC::CurrentTypeOf(prototype, isolate()),
2187 rax, holder, rbx, rdx, rdi, name, &miss); 2164 rax, holder, rbx, rdx, rdi, name, &miss);
2188 2165
2189 Register receiver = rax; 2166 Register receiver = rax;
2190 Register index = rdi; 2167 Register index = rdi;
2191 Register scratch = rdx; 2168 Register scratch = rdx;
2192 Register result = rax; 2169 Register result = rax;
2193 __ movq(receiver, args.GetReceiverOperand()); 2170 __ movq(receiver, args.GetReceiverOperand());
2194 if (argc > 0) { 2171 if (argc > 0) {
2195 __ movq(index, args.GetArgumentOperand(1)); 2172 __ movq(index, args.GetArgumentOperand(1));
2196 } else { 2173 } else {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2247 const int argc = arguments().immediate(); 2224 const int argc = arguments().immediate();
2248 StackArgumentsAccessor args(rsp, argc); 2225 StackArgumentsAccessor args(rsp, argc);
2249 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2226 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2250 2227
2251 Label miss; 2228 Label miss;
2252 GenerateNameCheck(name, &miss); 2229 GenerateNameCheck(name, &miss);
2253 2230
2254 if (cell.is_null()) { 2231 if (cell.is_null()) {
2255 __ movq(rdx, args.GetReceiverOperand()); 2232 __ movq(rdx, args.GetReceiverOperand());
2256 __ JumpIfSmi(rdx, &miss); 2233 __ JumpIfSmi(rdx, &miss);
2257 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 2234 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder,
2258 name, &miss); 2235 rbx, rax, rdi, name, &miss);
2259 } else { 2236 } else {
2260 ASSERT(cell->value() == *function); 2237 ASSERT(cell->value() == *function);
2261 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 2238 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2262 &miss); 2239 &miss);
2263 GenerateLoadFunctionFromCell(cell, function, &miss); 2240 GenerateLoadFunctionFromCell(cell, function, &miss);
2264 } 2241 }
2265 2242
2266 // Load the char code argument. 2243 // Load the char code argument.
2267 Register code = rbx; 2244 Register code = rbx;
2268 __ movq(code, args.GetArgumentOperand(1)); 2245 __ movq(code, args.GetArgumentOperand(1));
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2325 2302
2326 Label miss; 2303 Label miss;
2327 GenerateNameCheck(name, &miss); 2304 GenerateNameCheck(name, &miss);
2328 2305
2329 if (cell.is_null()) { 2306 if (cell.is_null()) {
2330 __ movq(rdx, args.GetReceiverOperand()); 2307 __ movq(rdx, args.GetReceiverOperand());
2331 2308
2332 STATIC_ASSERT(kSmiTag == 0); 2309 STATIC_ASSERT(kSmiTag == 0);
2333 __ JumpIfSmi(rdx, &miss); 2310 __ JumpIfSmi(rdx, &miss);
2334 2311
2335 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 2312 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder,
2336 name, &miss); 2313 rbx, rax, rdi, name, &miss);
2337 } else { 2314 } else {
2338 ASSERT(cell->value() == *function); 2315 ASSERT(cell->value() == *function);
2339 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 2316 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2340 &miss); 2317 &miss);
2341 GenerateLoadFunctionFromCell(cell, function, &miss); 2318 GenerateLoadFunctionFromCell(cell, function, &miss);
2342 } 2319 }
2343 2320
2344 // Load the (only) argument into rax. 2321 // Load the (only) argument into rax.
2345 __ movq(rax, args.GetArgumentOperand(1)); 2322 __ movq(rax, args.GetArgumentOperand(1));
2346 2323
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
2448 const int argc = arguments().immediate(); 2425 const int argc = arguments().immediate();
2449 StackArgumentsAccessor args(rsp, argc); 2426 StackArgumentsAccessor args(rsp, argc);
2450 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2427 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2451 2428
2452 Label miss; 2429 Label miss;
2453 GenerateNameCheck(name, &miss); 2430 GenerateNameCheck(name, &miss);
2454 2431
2455 if (cell.is_null()) { 2432 if (cell.is_null()) {
2456 __ movq(rdx, args.GetReceiverOperand()); 2433 __ movq(rdx, args.GetReceiverOperand());
2457 __ JumpIfSmi(rdx, &miss); 2434 __ JumpIfSmi(rdx, &miss);
2458 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 2435 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder,
2459 name, &miss); 2436 rbx, rax, rdi, name, &miss);
2460 } else { 2437 } else {
2461 ASSERT(cell->value() == *function); 2438 ASSERT(cell->value() == *function);
2462 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 2439 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2463 &miss); 2440 &miss);
2464 GenerateLoadFunctionFromCell(cell, function, &miss); 2441 GenerateLoadFunctionFromCell(cell, function, &miss);
2465 } 2442 }
2466 // Load the (only) argument into rax. 2443 // Load the (only) argument into rax.
2467 __ movq(rax, args.GetArgumentOperand(1)); 2444 __ movq(rax, args.GetArgumentOperand(1));
2468 2445
2469 // Check if the argument is a smi. 2446 // Check if the argument is a smi.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
2562 2539
2563 Counters* counters = isolate()->counters(); 2540 Counters* counters = isolate()->counters();
2564 __ IncrementCounter(counters->call_const(), 1); 2541 __ IncrementCounter(counters->call_const(), 1);
2565 __ IncrementCounter(counters->call_const_fast_api(), 1); 2542 __ IncrementCounter(counters->call_const_fast_api(), 1);
2566 2543
2567 // Allocate space for v8::Arguments implicit values. Must be initialized 2544 // Allocate space for v8::Arguments implicit values. Must be initialized
2568 // before calling any runtime function. 2545 // before calling any runtime function.
2569 __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); 2546 __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
2570 2547
2571 // Check that the maps haven't changed and find a Holder as a side effect. 2548 // Check that the maps haven't changed and find a Holder as a side effect.
2572 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 2549 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder,
2573 name, depth, &miss); 2550 rbx, rax, rdi, name, depth, &miss);
2574 2551
2575 // Move the return address on top of the stack. 2552 // Move the return address on top of the stack.
2576 __ movq(rax, 2553 __ movq(rax,
2577 StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize)); 2554 StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize));
2578 __ movq(StackOperandForReturnAddress(0), rax); 2555 __ movq(StackOperandForReturnAddress(0), rax);
2579 2556
2580 GenerateFastApiCall(masm(), optimization, argc); 2557 GenerateFastApiCall(masm(), optimization, argc);
2581 2558
2582 __ bind(&miss); 2559 __ bind(&miss);
2583 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); 2560 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2628 // Make sure that it's okay not to patch the on stack receiver 2605 // Make sure that it's okay not to patch the on stack receiver
2629 // unless we're doing a receiver map check. 2606 // unless we're doing a receiver map check.
2630 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 2607 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
2631 2608
2632 Counters* counters = isolate()->counters(); 2609 Counters* counters = isolate()->counters();
2633 switch (check) { 2610 switch (check) {
2634 case RECEIVER_MAP_CHECK: 2611 case RECEIVER_MAP_CHECK:
2635 __ IncrementCounter(counters->call_const(), 1); 2612 __ IncrementCounter(counters->call_const(), 1);
2636 2613
2637 // Check that the maps haven't changed. 2614 // Check that the maps haven't changed.
2638 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, 2615 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder,
2639 rdi, name, &miss); 2616 rbx, rax, rdi, name, &miss);
2640 2617
2641 // Patch the receiver on the stack with the global proxy if 2618 // Patch the receiver on the stack with the global proxy if
2642 // necessary. 2619 // necessary.
2643 if (object->IsGlobalObject()) { 2620 if (object->IsGlobalObject()) {
2644 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 2621 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
2645 __ movq(args.GetReceiverOperand(), rdx); 2622 __ movq(args.GetReceiverOperand(), rdx);
2646 } 2623 }
2647 break; 2624 break;
2648 2625
2649 case STRING_CHECK: 2626 case STRING_CHECK: {
2650 // Check that the object is a string. 2627 // Check that the object is a string.
2651 __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax); 2628 __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax);
2652 __ j(above_equal, &miss); 2629 __ j(above_equal, &miss);
2653 // Check that the maps starting from the prototype haven't changed. 2630 // Check that the maps starting from the prototype haven't changed.
2654 GenerateDirectLoadGlobalFunctionPrototype( 2631 GenerateDirectLoadGlobalFunctionPrototype(
2655 masm(), Context::STRING_FUNCTION_INDEX, rax, &miss); 2632 masm(), Context::STRING_FUNCTION_INDEX, rax, &miss);
2633 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2656 CheckPrototypes( 2634 CheckPrototypes(
2657 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2635 IC::CurrentTypeOf(prototype, isolate()),
2658 rax, holder, rbx, rdx, rdi, name, &miss); 2636 rax, holder, rbx, rdx, rdi, name, &miss);
2659 break; 2637 break;
2660 2638 }
2661 case SYMBOL_CHECK: 2639 case SYMBOL_CHECK: {
2662 // Check that the object is a symbol. 2640 // Check that the object is a symbol.
2663 __ CmpObjectType(rdx, SYMBOL_TYPE, rax); 2641 __ CmpObjectType(rdx, SYMBOL_TYPE, rax);
2664 __ j(not_equal, &miss); 2642 __ j(not_equal, &miss);
2665 // Check that the maps starting from the prototype haven't changed. 2643 // Check that the maps starting from the prototype haven't changed.
2666 GenerateDirectLoadGlobalFunctionPrototype( 2644 GenerateDirectLoadGlobalFunctionPrototype(
2667 masm(), Context::SYMBOL_FUNCTION_INDEX, rax, &miss); 2645 masm(), Context::SYMBOL_FUNCTION_INDEX, rax, &miss);
2646 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2668 CheckPrototypes( 2647 CheckPrototypes(
2669 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2648 IC::CurrentTypeOf(prototype, isolate()),
2670 rax, holder, rbx, rdx, rdi, name, &miss); 2649 rax, holder, rbx, rdx, rdi, name, &miss);
2671 break; 2650 break;
2672 2651 }
2673 case NUMBER_CHECK: { 2652 case NUMBER_CHECK: {
2674 Label fast; 2653 Label fast;
2675 // Check that the object is a smi or a heap number. 2654 // Check that the object is a smi or a heap number.
2676 __ JumpIfSmi(rdx, &fast); 2655 __ JumpIfSmi(rdx, &fast);
2677 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rax); 2656 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rax);
2678 __ j(not_equal, &miss); 2657 __ j(not_equal, &miss);
2679 __ bind(&fast); 2658 __ bind(&fast);
2680 // Check that the maps starting from the prototype haven't changed. 2659 // Check that the maps starting from the prototype haven't changed.
2681 GenerateDirectLoadGlobalFunctionPrototype( 2660 GenerateDirectLoadGlobalFunctionPrototype(
2682 masm(), Context::NUMBER_FUNCTION_INDEX, rax, &miss); 2661 masm(), Context::NUMBER_FUNCTION_INDEX, rax, &miss);
2662 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2683 CheckPrototypes( 2663 CheckPrototypes(
2684 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2664 IC::CurrentTypeOf(prototype, isolate()),
2685 rax, holder, rbx, rdx, rdi, name, &miss); 2665 rax, holder, rbx, rdx, rdi, name, &miss);
2686 break; 2666 break;
2687 } 2667 }
2688 case BOOLEAN_CHECK: { 2668 case BOOLEAN_CHECK: {
2689 GenerateBooleanCheck(rdx, &miss); 2669 GenerateBooleanCheck(rdx, &miss);
2690 // Check that the maps starting from the prototype haven't changed. 2670 // Check that the maps starting from the prototype haven't changed.
2691 GenerateDirectLoadGlobalFunctionPrototype( 2671 GenerateDirectLoadGlobalFunctionPrototype(
2692 masm(), Context::BOOLEAN_FUNCTION_INDEX, rax, &miss); 2672 masm(), Context::BOOLEAN_FUNCTION_INDEX, rax, &miss);
2673 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2693 CheckPrototypes( 2674 CheckPrototypes(
2694 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2675 IC::CurrentTypeOf(prototype, isolate()),
2695 rax, holder, rbx, rdx, rdi, name, &miss); 2676 rax, holder, rbx, rdx, rdi, name, &miss);
2696 break; 2677 break;
2697 } 2678 }
2698 } 2679 }
2699 2680
2700 Label success; 2681 Label success;
2701 __ jmp(&success); 2682 __ jmp(&success);
2702 2683
2703 // Handle call cache miss. 2684 // Handle call cache miss.
2704 __ bind(&miss); 2685 __ bind(&miss);
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
2862 // Return the generated code. 2843 // Return the generated code.
2863 return GetCode(Code::NORMAL, name); 2844 return GetCode(Code::NORMAL, name);
2864 } 2845 }
2865 2846
2866 2847
2867 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2848 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2868 Handle<JSObject> object, 2849 Handle<JSObject> object,
2869 Handle<JSObject> holder, 2850 Handle<JSObject> holder,
2870 Handle<Name> name, 2851 Handle<Name> name,
2871 Handle<ExecutableAccessorInfo> callback) { 2852 Handle<ExecutableAccessorInfo> callback) {
2872 HandlerFrontend(object, receiver(), holder, name); 2853 HandlerFrontend(IC::CurrentTypeOf(object, isolate()),
2854 receiver(), holder, name);
2873 2855
2874 __ PopReturnAddressTo(scratch1()); 2856 __ PopReturnAddressTo(scratch1());
2875 __ push(receiver()); 2857 __ push(receiver());
2876 __ Push(callback); // callback info 2858 __ Push(callback); // callback info
2877 __ Push(name); 2859 __ Push(name);
2878 __ push(value()); 2860 __ push(value());
2879 __ PushReturnAddressFrom(scratch1()); 2861 __ PushReturnAddressFrom(scratch1());
2880 2862
2881 // Do tail-call to the runtime system. 2863 // Do tail-call to the runtime system.
2882 ExternalReference store_callback_property = 2864 ExternalReference store_callback_property =
2883 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 2865 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
2884 __ TailCallExternalReference(store_callback_property, 4, 1); 2866 __ TailCallExternalReference(store_callback_property, 4, 1);
2885 2867
2886 // Return the generated code. 2868 // Return the generated code.
2887 return GetCode(kind(), Code::FAST, name); 2869 return GetCode(kind(), Code::FAST, name);
2888 } 2870 }
2889 2871
2890 2872
2891 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2873 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2892 Handle<JSObject> object, 2874 Handle<JSObject> object,
2893 Handle<JSObject> holder, 2875 Handle<JSObject> holder,
2894 Handle<Name> name, 2876 Handle<Name> name,
2895 const CallOptimization& call_optimization) { 2877 const CallOptimization& call_optimization) {
2896 HandlerFrontend(object, receiver(), holder, name); 2878 HandlerFrontend(IC::CurrentTypeOf(object, isolate()),
2879 receiver(), holder, name);
2897 2880
2898 Register values[] = { value() }; 2881 Register values[] = { value() };
2899 GenerateFastApiCall( 2882 GenerateFastApiCall(
2900 masm(), call_optimization, receiver(), scratch1(), 2883 masm(), call_optimization, receiver(), scratch1(),
2901 scratch2(), this->name(), 1, values); 2884 scratch2(), this->name(), 1, values);
2902 2885
2903 // Return the generated code. 2886 // Return the generated code.
2904 return GetCode(kind(), Code::FAST, name); 2887 return GetCode(kind(), Code::FAST, name);
2905 } 2888 }
2906 2889
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
3000 __ bind(&miss); 2983 __ bind(&miss);
3001 2984
3002 TailCallBuiltin(masm(), MissBuiltin(kind())); 2985 TailCallBuiltin(masm(), MissBuiltin(kind()));
3003 2986
3004 // Return the generated code. 2987 // Return the generated code.
3005 return GetICCode( 2988 return GetICCode(
3006 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 2989 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
3007 } 2990 }
3008 2991
3009 2992
3010 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( 2993 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<Type> type,
3011 Handle<Object> object, 2994 Handle<JSObject> last,
3012 Handle<JSObject> last, 2995 Handle<Name> name) {
3013 Handle<Name> name, 2996 NonexistentHandlerFrontend(type, last, name);
3014 Handle<JSGlobalObject> global) {
3015 NonexistentHandlerFrontend(object, last, name, global);
3016 2997
3017 // Return undefined if maps of the full prototype chain are still the 2998 // Return undefined if maps of the full prototype chain are still the
3018 // same and no global property with this name contains a value. 2999 // same and no global property with this name contains a value.
3019 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 3000 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
3020 __ ret(0); 3001 __ ret(0);
3021 3002
3022 // Return the generated code. 3003 // Return the generated code.
3023 return GetCode(kind(), Code::FAST, name); 3004 return GetCode(kind(), Code::FAST, name);
3024 } 3005 }
3025 3006
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
3101 } 3082 }
3102 __ ret(0); 3083 __ ret(0);
3103 } 3084 }
3104 3085
3105 3086
3106 #undef __ 3087 #undef __
3107 #define __ ACCESS_MASM(masm()) 3088 #define __ ACCESS_MASM(masm())
3108 3089
3109 3090
3110 Handle<Code> LoadStubCompiler::CompileLoadGlobal( 3091 Handle<Code> LoadStubCompiler::CompileLoadGlobal(
3111 Handle<Object> object, 3092 Handle<Type> type,
3112 Handle<GlobalObject> global, 3093 Handle<GlobalObject> global,
3113 Handle<PropertyCell> cell, 3094 Handle<PropertyCell> cell,
3114 Handle<Name> name, 3095 Handle<Name> name,
3115 bool is_dont_delete) { 3096 bool is_dont_delete) {
3116 Label miss; 3097 Label miss;
3117 // TODO(verwaest): Directly store to rax. Currently we cannot do this, since 3098 // TODO(verwaest): Directly store to rax. Currently we cannot do this, since
3118 // rax is used as receiver(), which we would otherwise clobber before a 3099 // rax is used as receiver(), which we would otherwise clobber before a
3119 // potential miss. 3100 // potential miss.
3120 HandlerFrontendHeader(object, receiver(), global, name, &miss); 3101 HandlerFrontendHeader(type, receiver(), global, name, &miss);
3121 3102
3122 // Get the value from the cell. 3103 // Get the value from the cell.
3123 __ Move(rbx, cell); 3104 __ Move(rbx, cell);
3124 __ movq(rbx, FieldOperand(rbx, PropertyCell::kValueOffset)); 3105 __ movq(rbx, FieldOperand(rbx, PropertyCell::kValueOffset));
3125 3106
3126 // Check for deleted property if property can actually be deleted. 3107 // Check for deleted property if property can actually be deleted.
3127 if (!is_dont_delete) { 3108 if (!is_dont_delete) {
3128 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); 3109 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex);
3129 __ j(equal, &miss); 3110 __ j(equal, &miss);
3130 } else if (FLAG_debug_code) { 3111 } else if (FLAG_debug_code) {
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
3234 // ----------------------------------- 3215 // -----------------------------------
3235 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 3216 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
3236 } 3217 }
3237 3218
3238 3219
3239 #undef __ 3220 #undef __
3240 3221
3241 } } // namespace v8::internal 3222 } } // namespace v8::internal
3242 3223
3243 #endif // V8_TARGET_ARCH_X64 3224 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/simulator-x64.cc ('k') | test/benchmarks/testcfg.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698