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

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

Issue 26873002: Remove BaseLoad/StoreStub compilers, and the stub-cache interface duplication. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 2 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
« src/stub-cache.cc ('K') | « src/stub-cache.cc ('k') | no next file » | 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 749 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 __ j(not_equal, interceptor_succeeded); 760 __ j(not_equal, interceptor_succeeded);
761 } 761 }
762 762
763 StubCompiler* stub_compiler_; 763 StubCompiler* stub_compiler_;
764 const ParameterCount& arguments_; 764 const ParameterCount& arguments_;
765 Register name_; 765 Register name_;
766 Code::ExtraICState extra_ic_state_; 766 Code::ExtraICState extra_ic_state_;
767 }; 767 };
768 768
769 769
770 void BaseStoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, 770 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
771 Label* label, 771 Label* label,
772 Handle<Name> name) { 772 Handle<Name> name) {
773 if (!label->is_unused()) { 773 if (!label->is_unused()) {
774 __ bind(label); 774 __ bind(label);
775 __ Move(this->name(), name); 775 __ Move(this->name(), name);
776 } 776 }
777 } 777 }
778 778
779 779
780 // Generate code to check that a global property cell is empty. Create 780 // Generate code to check that a global property cell is empty. Create
781 // the property cell at compilation time if no cell exists for the 781 // the property cell at compilation time if no cell exists for the
782 // property. 782 // property.
783 static void GenerateCheckPropertyCell(MacroAssembler* masm, 783 static void GenerateCheckPropertyCell(MacroAssembler* masm,
784 Handle<GlobalObject> global, 784 Handle<GlobalObject> global,
785 Handle<Name> name, 785 Handle<Name> name,
786 Register scratch, 786 Register scratch,
787 Label* miss) { 787 Label* miss) {
788 Handle<PropertyCell> cell = 788 Handle<PropertyCell> cell =
789 GlobalObject::EnsurePropertyCell(global, name); 789 GlobalObject::EnsurePropertyCell(global, name);
790 ASSERT(cell->value()->IsTheHole()); 790 ASSERT(cell->value()->IsTheHole());
791 __ Move(scratch, cell); 791 __ Move(scratch, cell);
792 __ Cmp(FieldOperand(scratch, Cell::kValueOffset), 792 __ Cmp(FieldOperand(scratch, Cell::kValueOffset),
793 masm->isolate()->factory()->the_hole_value()); 793 masm->isolate()->factory()->the_hole_value());
794 __ j(not_equal, miss); 794 __ j(not_equal, miss);
795 } 795 }
796 796
797 797
798 void BaseStoreStubCompiler::GenerateNegativeHolderLookup( 798 void StoreStubCompiler::GenerateNegativeHolderLookup(
799 MacroAssembler* masm, 799 MacroAssembler* masm,
800 Handle<JSObject> holder, 800 Handle<JSObject> holder,
801 Register holder_reg, 801 Register holder_reg,
802 Handle<Name> name, 802 Handle<Name> name,
803 Label* miss) { 803 Label* miss) {
804 if (holder->IsJSGlobalObject()) { 804 if (holder->IsJSGlobalObject()) {
805 GenerateCheckPropertyCell( 805 GenerateCheckPropertyCell(
806 masm, Handle<GlobalObject>::cast(holder), name, scratch1(), miss); 806 masm, Handle<GlobalObject>::cast(holder), name, scratch1(), miss);
807 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { 807 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
808 GenerateDictionaryNegativeLookup( 808 GenerateDictionaryNegativeLookup(
809 masm, miss, holder_reg, name, scratch1(), scratch2()); 809 masm, miss, holder_reg, name, scratch1(), scratch2());
810 } 810 }
811 } 811 }
812 812
813 813
814 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if 814 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if
815 // store is successful. 815 // store is successful.
816 void BaseStoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, 816 void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
817 Handle<JSObject> object, 817 Handle<JSObject> object,
818 LookupResult* lookup, 818 LookupResult* lookup,
819 Handle<Map> transition, 819 Handle<Map> transition,
820 Handle<Name> name, 820 Handle<Name> name,
821 Register receiver_reg, 821 Register receiver_reg,
822 Register storage_reg, 822 Register storage_reg,
823 Register value_reg, 823 Register value_reg,
824 Register scratch1, 824 Register scratch1,
825 Register scratch2, 825 Register scratch2,
826 Register unused, 826 Register unused,
827 Label* miss_label, 827 Label* miss_label,
828 Label* slow) { 828 Label* slow) {
829 int descriptor = transition->LastAdded(); 829 int descriptor = transition->LastAdded();
830 DescriptorArray* descriptors = transition->instance_descriptors(); 830 DescriptorArray* descriptors = transition->instance_descriptors();
831 PropertyDetails details = descriptors->GetDetails(descriptor); 831 PropertyDetails details = descriptors->GetDetails(descriptor);
832 Representation representation = details.representation(); 832 Representation representation = details.representation();
833 ASSERT(!representation.IsNone()); 833 ASSERT(!representation.IsNone());
834 834
835 if (details.type() == CONSTANT) { 835 if (details.type() == CONSTANT) {
836 Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate()); 836 Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate());
837 __ CmpObject(value_reg, constant); 837 __ CmpObject(value_reg, constant);
838 __ j(not_equal, miss_label); 838 __ j(not_equal, miss_label);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 } 951 }
952 952
953 // Return the value (register rax). 953 // Return the value (register rax).
954 ASSERT(value_reg.is(rax)); 954 ASSERT(value_reg.is(rax));
955 __ ret(0); 955 __ ret(0);
956 } 956 }
957 957
958 958
959 // Both name_reg and receiver_reg are preserved on jumps to miss_label, 959 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
960 // but may be destroyed if store is successful. 960 // but may be destroyed if store is successful.
961 void BaseStoreStubCompiler::GenerateStoreField(MacroAssembler* masm, 961 void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
962 Handle<JSObject> object, 962 Handle<JSObject> object,
963 LookupResult* lookup, 963 LookupResult* lookup,
964 Register receiver_reg, 964 Register receiver_reg,
965 Register name_reg, 965 Register name_reg,
966 Register value_reg, 966 Register value_reg,
967 Register scratch1, 967 Register scratch1,
968 Register scratch2, 968 Register scratch2,
969 Label* miss_label) { 969 Label* miss_label) {
970 // Stub never generated for non-global objects that require access 970 // Stub never generated for non-global objects that require access
971 // checks. 971 // checks.
972 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 972 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
973 973
974 int index = lookup->GetFieldIndex().field_index(); 974 int index = lookup->GetFieldIndex().field_index();
975 975
976 // Adjust for the number of properties stored in the object. Even in the 976 // Adjust for the number of properties stored in the object. Even in the
977 // face of a transition we can use the old map here because the size of the 977 // face of a transition we can use the old map here because the size of the
978 // object and the number of in-object properties is not going to change. 978 // object and the number of in-object properties is not going to change.
979 index -= object->map()->inobject_properties(); 979 index -= object->map()->inobject_properties();
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1202 // If we've skipped any global objects, it's not enough to verify that 1202 // If we've skipped any global objects, it's not enough to verify that
1203 // their maps haven't changed. We also need to check that the property 1203 // their maps haven't changed. We also need to check that the property
1204 // cell for the property is still empty. 1204 // cell for the property is still empty.
1205 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); 1205 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss);
1206 1206
1207 // Return the register containing the holder. 1207 // Return the register containing the holder.
1208 return reg; 1208 return reg;
1209 } 1209 }
1210 1210
1211 1211
1212 void BaseLoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, 1212 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name,
1213 Label* success, 1213 Label* success,
1214 Label* miss) { 1214 Label* miss) {
1215 if (!miss->is_unused()) { 1215 if (!miss->is_unused()) {
1216 __ jmp(success); 1216 __ jmp(success);
1217 __ bind(miss); 1217 __ bind(miss);
1218 TailCallBuiltin(masm(), MissBuiltin(kind())); 1218 TailCallBuiltin(masm(), MissBuiltin(kind()));
1219 } 1219 }
1220 } 1220 }
1221 1221
1222 1222
1223 void BaseStoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, 1223 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name,
1224 Label* success, 1224 Label* success,
1225 Label* miss) { 1225 Label* miss) {
1226 if (!miss->is_unused()) { 1226 if (!miss->is_unused()) {
1227 __ jmp(success); 1227 __ jmp(success);
1228 GenerateRestoreName(masm(), miss, name); 1228 GenerateRestoreName(masm(), miss, name);
1229 TailCallBuiltin(masm(), MissBuiltin(kind())); 1229 TailCallBuiltin(masm(), MissBuiltin(kind()));
1230 } 1230 }
1231 } 1231 }
1232 1232
1233 1233
1234 Register BaseLoadStubCompiler::CallbackHandlerFrontend( 1234 Register LoadStubCompiler::CallbackHandlerFrontend(
1235 Handle<JSObject> object, 1235 Handle<JSObject> object,
1236 Register object_reg, 1236 Register object_reg,
1237 Handle<JSObject> holder, 1237 Handle<JSObject> holder,
1238 Handle<Name> name, 1238 Handle<Name> name,
1239 Label* success, 1239 Label* success,
1240 Handle<Object> callback) { 1240 Handle<Object> callback) {
1241 Label miss; 1241 Label miss;
1242 1242
1243 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); 1243 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss);
1244 1244
(...skipping 30 matching lines...) Expand all
1275 __ movq(scratch3(), callback, RelocInfo::EMBEDDED_OBJECT); 1275 __ movq(scratch3(), callback, RelocInfo::EMBEDDED_OBJECT);
1276 __ cmpq(scratch2(), scratch3()); 1276 __ cmpq(scratch2(), scratch3());
1277 __ j(not_equal, &miss); 1277 __ j(not_equal, &miss);
1278 } 1278 }
1279 1279
1280 HandlerFrontendFooter(name, success, &miss); 1280 HandlerFrontendFooter(name, success, &miss);
1281 return reg; 1281 return reg;
1282 } 1282 }
1283 1283
1284 1284
1285 void BaseLoadStubCompiler::NonexistentHandlerFrontend( 1285 void LoadStubCompiler::NonexistentHandlerFrontend(
1286 Handle<JSObject> object, 1286 Handle<JSObject> object,
1287 Handle<JSObject> last, 1287 Handle<JSObject> last,
1288 Handle<Name> name, 1288 Handle<Name> name,
1289 Label* success, 1289 Label* success,
1290 Handle<GlobalObject> global) { 1290 Handle<GlobalObject> global) {
1291 Label miss; 1291 Label miss;
1292 1292
1293 HandlerFrontendHeader(object, receiver(), last, name, &miss); 1293 HandlerFrontendHeader(object, receiver(), last, name, &miss);
1294 1294
1295 // If the last object in the prototype chain is a global object, 1295 // If the last object in the prototype chain is a global object,
1296 // check that the global property cell is empty. 1296 // check that the global property cell is empty.
1297 if (!global.is_null()) { 1297 if (!global.is_null()) {
1298 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); 1298 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
1299 } 1299 }
1300 1300
1301 HandlerFrontendFooter(name, success, &miss); 1301 HandlerFrontendFooter(name, success, &miss);
1302 } 1302 }
1303 1303
1304 1304
1305 void BaseLoadStubCompiler::GenerateLoadField(Register reg, 1305 void LoadStubCompiler::GenerateLoadField(Register reg,
1306 Handle<JSObject> holder, 1306 Handle<JSObject> holder,
1307 PropertyIndex field, 1307 PropertyIndex field,
1308 Representation representation) { 1308 Representation representation) {
1309 if (!reg.is(receiver())) __ movq(receiver(), reg); 1309 if (!reg.is(receiver())) __ movq(receiver(), reg);
1310 if (kind() == Code::LOAD_IC) { 1310 if (kind() == Code::LOAD_IC) {
1311 LoadFieldStub stub(field.is_inobject(holder), 1311 LoadFieldStub stub(field.is_inobject(holder),
1312 field.translate(holder), 1312 field.translate(holder),
1313 representation); 1313 representation);
1314 GenerateTailCall(masm(), stub.GetCode(isolate())); 1314 GenerateTailCall(masm(), stub.GetCode(isolate()));
1315 } else { 1315 } else {
1316 KeyedLoadFieldStub stub(field.is_inobject(holder), 1316 KeyedLoadFieldStub stub(field.is_inobject(holder),
1317 field.translate(holder), 1317 field.translate(holder),
1318 representation); 1318 representation);
1319 GenerateTailCall(masm(), stub.GetCode(isolate())); 1319 GenerateTailCall(masm(), stub.GetCode(isolate()));
1320 } 1320 }
1321 } 1321 }
1322 1322
1323 1323
1324 void BaseLoadStubCompiler::GenerateLoadCallback( 1324 void LoadStubCompiler::GenerateLoadCallback(
1325 const CallOptimization& call_optimization) { 1325 const CallOptimization& call_optimization) {
1326 GenerateFastApiCall( 1326 GenerateFastApiCall(
1327 masm(), call_optimization, receiver(), scratch3(), 0, NULL); 1327 masm(), call_optimization, receiver(), scratch3(), 0, NULL);
1328 } 1328 }
1329 1329
1330 1330
1331 void BaseLoadStubCompiler::GenerateLoadCallback( 1331 void LoadStubCompiler::GenerateLoadCallback(
1332 Register reg, 1332 Register reg,
1333 Handle<ExecutableAccessorInfo> callback) { 1333 Handle<ExecutableAccessorInfo> callback) {
1334 // Insert additional parameters into the stack frame above return address. 1334 // Insert additional parameters into the stack frame above return address.
1335 ASSERT(!scratch4().is(reg)); 1335 ASSERT(!scratch4().is(reg));
1336 __ PopReturnAddressTo(scratch4()); 1336 __ PopReturnAddressTo(scratch4());
1337 1337
1338 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); 1338 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
1339 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); 1339 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
1340 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); 1340 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
1341 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); 1341 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 PropertyCallbackArguments::kReturnValueOffset); 1402 PropertyCallbackArguments::kReturnValueOffset);
1403 __ CallApiFunctionAndReturn(getter_address, 1403 __ CallApiFunctionAndReturn(getter_address,
1404 thunk_address, 1404 thunk_address,
1405 getter_arg, 1405 getter_arg,
1406 kStackSpace, 1406 kStackSpace,
1407 return_value_operand, 1407 return_value_operand,
1408 NULL); 1408 NULL);
1409 } 1409 }
1410 1410
1411 1411
1412 void BaseLoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { 1412 void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) {
1413 // Return the constant value. 1413 // Return the constant value.
1414 __ LoadObject(rax, value); 1414 __ LoadObject(rax, value);
1415 __ ret(0); 1415 __ ret(0);
1416 } 1416 }
1417 1417
1418 1418
1419 void BaseLoadStubCompiler::GenerateLoadInterceptor( 1419 void LoadStubCompiler::GenerateLoadInterceptor(
1420 Register holder_reg, 1420 Register holder_reg,
1421 Handle<JSObject> object, 1421 Handle<JSObject> object,
1422 Handle<JSObject> interceptor_holder, 1422 Handle<JSObject> interceptor_holder,
1423 LookupResult* lookup, 1423 LookupResult* lookup,
1424 Handle<Name> name) { 1424 Handle<Name> name) {
1425 ASSERT(interceptor_holder->HasNamedInterceptor()); 1425 ASSERT(interceptor_holder->HasNamedInterceptor());
1426 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); 1426 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined());
1427 1427
1428 // So far the most popular follow ups for interceptor loads are FIELD 1428 // So far the most popular follow ups for interceptor loads are FIELD
1429 // and CALLBACKS, so inline only them, other cases may be added 1429 // and CALLBACKS, so inline only them, other cases may be added
(...skipping 1585 matching lines...) Expand 10 before | Expand all | Expand 10 after
3015 __ Cmp(name_reg, name); 3015 __ Cmp(name_reg, name);
3016 __ j(not_equal, miss); 3016 __ j(not_equal, miss);
3017 } 3017 }
3018 3018
3019 3019
3020 #undef __ 3020 #undef __
3021 #define __ ACCESS_MASM(masm) 3021 #define __ ACCESS_MASM(masm)
3022 3022
3023 3023
3024 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, 3024 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
3025 Register receiver,
3025 Handle<JSFunction> getter) { 3026 Handle<JSFunction> getter) {
3026 // ----------- S t a t e ------------- 3027 // ----------- S t a t e -------------
3027 // -- rax : receiver 3028 // -- rax : receiver
3028 // -- rcx : name 3029 // -- rcx : name
3029 // -- rsp[0] : return address 3030 // -- rsp[0] : return address
3030 // ----------------------------------- 3031 // -----------------------------------
3031 { 3032 {
3032 FrameScope scope(masm, StackFrame::INTERNAL); 3033 FrameScope scope(masm, StackFrame::INTERNAL);
3033 3034
3034 if (!getter.is_null()) { 3035 if (!getter.is_null()) {
3035 // Call the JavaScript getter with the receiver on the stack. 3036 // Call the JavaScript getter with the receiver on the stack.
3036 __ push(rax); 3037 __ push(receiver);
3037 ParameterCount actual(0); 3038 ParameterCount actual(0);
3038 ParameterCount expected(getter); 3039 ParameterCount expected(getter);
3039 __ InvokeFunction(getter, expected, actual, 3040 __ InvokeFunction(getter, expected, actual,
3040 CALL_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 3041 CALL_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
3041 } else { 3042 } else {
3042 // If we generate a global code snippet for deoptimization only, remember 3043 // If we generate a global code snippet for deoptimization only, remember
3043 // the place to continue after deoptimization. 3044 // the place to continue after deoptimization.
3044 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset()); 3045 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
3045 } 3046 }
3046 3047
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
3178 // ----------------------------------- 3179 // -----------------------------------
3179 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); 3180 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
3180 } 3181 }
3181 3182
3182 3183
3183 #undef __ 3184 #undef __
3184 3185
3185 } } // namespace v8::internal 3186 } } // namespace v8::internal
3186 3187
3187 #endif // V8_TARGET_ARCH_X64 3188 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/stub-cache.cc ('K') | « src/stub-cache.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698