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

Side by Side Diff: src/ia32/stub-cache-ia32.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
« no previous file with comments | « src/builtins.cc ('k') | src/ic.h » ('j') | src/ic.h » ('J')
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 761 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 __ j(not_equal, interceptor_succeeded); 772 __ j(not_equal, interceptor_succeeded);
773 } 773 }
774 774
775 StubCompiler* stub_compiler_; 775 StubCompiler* stub_compiler_;
776 const ParameterCount& arguments_; 776 const ParameterCount& arguments_;
777 Register name_; 777 Register name_;
778 Code::ExtraICState extra_state_; 778 Code::ExtraICState extra_state_;
779 }; 779 };
780 780
781 781
782 void BaseStoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, 782 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
783 Label* label, 783 Label* label,
784 Handle<Name> name) { 784 Handle<Name> name) {
785 if (!label->is_unused()) { 785 if (!label->is_unused()) {
786 __ bind(label); 786 __ bind(label);
787 __ mov(this->name(), Immediate(name)); 787 __ mov(this->name(), Immediate(name));
788 } 788 }
789 } 789 }
790 790
791 791
792 // Generate code to check that a global property cell is empty. Create 792 // Generate code to check that a global property cell is empty. Create
793 // the property cell at compilation time if no cell exists for the 793 // the property cell at compilation time if no cell exists for the
794 // property. 794 // property.
(...skipping 10 matching lines...) Expand all
805 __ mov(scratch, Immediate(cell)); 805 __ mov(scratch, Immediate(cell));
806 __ cmp(FieldOperand(scratch, PropertyCell::kValueOffset), 806 __ cmp(FieldOperand(scratch, PropertyCell::kValueOffset),
807 Immediate(the_hole)); 807 Immediate(the_hole));
808 } else { 808 } else {
809 __ cmp(Operand::ForCell(cell), Immediate(the_hole)); 809 __ cmp(Operand::ForCell(cell), Immediate(the_hole));
810 } 810 }
811 __ j(not_equal, miss); 811 __ j(not_equal, miss);
812 } 812 }
813 813
814 814
815 void BaseStoreStubCompiler::GenerateNegativeHolderLookup( 815 void StoreStubCompiler::GenerateNegativeHolderLookup(
816 MacroAssembler* masm, 816 MacroAssembler* masm,
817 Handle<JSObject> holder, 817 Handle<JSObject> holder,
818 Register holder_reg, 818 Register holder_reg,
819 Handle<Name> name, 819 Handle<Name> name,
820 Label* miss) { 820 Label* miss) {
821 if (holder->IsJSGlobalObject()) { 821 if (holder->IsJSGlobalObject()) {
822 GenerateCheckPropertyCell( 822 GenerateCheckPropertyCell(
823 masm, Handle<GlobalObject>::cast(holder), name, scratch1(), miss); 823 masm, Handle<GlobalObject>::cast(holder), name, scratch1(), miss);
824 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { 824 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
825 GenerateDictionaryNegativeLookup( 825 GenerateDictionaryNegativeLookup(
826 masm, miss, holder_reg, name, scratch1(), scratch2()); 826 masm, miss, holder_reg, name, scratch1(), scratch2());
827 } 827 }
828 } 828 }
829 829
830 830
831 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if 831 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if
832 // store is successful. 832 // store is successful.
833 void BaseStoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, 833 void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
834 Handle<JSObject> object, 834 Handle<JSObject> object,
835 LookupResult* lookup, 835 LookupResult* lookup,
836 Handle<Map> transition, 836 Handle<Map> transition,
837 Handle<Name> name, 837 Handle<Name> name,
838 Register receiver_reg, 838 Register receiver_reg,
839 Register storage_reg, 839 Register storage_reg,
840 Register value_reg, 840 Register value_reg,
841 Register scratch1, 841 Register scratch1,
842 Register scratch2, 842 Register scratch2,
843 Register unused, 843 Register unused,
844 Label* miss_label, 844 Label* miss_label,
845 Label* slow) { 845 Label* slow) {
846 int descriptor = transition->LastAdded(); 846 int descriptor = transition->LastAdded();
847 DescriptorArray* descriptors = transition->instance_descriptors(); 847 DescriptorArray* descriptors = transition->instance_descriptors();
848 PropertyDetails details = descriptors->GetDetails(descriptor); 848 PropertyDetails details = descriptors->GetDetails(descriptor);
849 Representation representation = details.representation(); 849 Representation representation = details.representation();
850 ASSERT(!representation.IsNone()); 850 ASSERT(!representation.IsNone());
851 851
852 if (details.type() == CONSTANT) { 852 if (details.type() == CONSTANT) {
853 Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate()); 853 Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate());
854 __ CmpObject(value_reg, constant); 854 __ CmpObject(value_reg, constant);
855 __ j(not_equal, miss_label); 855 __ j(not_equal, miss_label);
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
994 } 994 }
995 995
996 // Return the value (register eax). 996 // Return the value (register eax).
997 ASSERT(value_reg.is(eax)); 997 ASSERT(value_reg.is(eax));
998 __ ret(0); 998 __ ret(0);
999 } 999 }
1000 1000
1001 1001
1002 // Both name_reg and receiver_reg are preserved on jumps to miss_label, 1002 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
1003 // but may be destroyed if store is successful. 1003 // but may be destroyed if store is successful.
1004 void BaseStoreStubCompiler::GenerateStoreField(MacroAssembler* masm, 1004 void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
1005 Handle<JSObject> object, 1005 Handle<JSObject> object,
1006 LookupResult* lookup, 1006 LookupResult* lookup,
1007 Register receiver_reg, 1007 Register receiver_reg,
1008 Register name_reg, 1008 Register name_reg,
1009 Register value_reg, 1009 Register value_reg,
1010 Register scratch1, 1010 Register scratch1,
1011 Register scratch2, 1011 Register scratch2,
1012 Label* miss_label) { 1012 Label* miss_label) {
1013 // Stub never generated for non-global objects that require access 1013 // Stub never generated for non-global objects that require access
1014 // checks. 1014 // checks.
1015 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 1015 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
1016 1016
1017 int index = lookup->GetFieldIndex().field_index(); 1017 int index = lookup->GetFieldIndex().field_index();
1018 1018
1019 // Adjust for the number of properties stored in the object. Even in the 1019 // Adjust for the number of properties stored in the object. Even in the
1020 // face of a transition we can use the old map here because the size of the 1020 // face of a transition we can use the old map here because the size of the
1021 // object and the number of in-object properties is not going to change. 1021 // object and the number of in-object properties is not going to change.
1022 index -= object->map()->inobject_properties(); 1022 index -= object->map()->inobject_properties();
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
1266 // If we've skipped any global objects, it's not enough to verify that 1266 // If we've skipped any global objects, it's not enough to verify that
1267 // their maps haven't changed. We also need to check that the property 1267 // their maps haven't changed. We also need to check that the property
1268 // cell for the property is still empty. 1268 // cell for the property is still empty.
1269 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); 1269 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss);
1270 1270
1271 // Return the register containing the holder. 1271 // Return the register containing the holder.
1272 return reg; 1272 return reg;
1273 } 1273 }
1274 1274
1275 1275
1276 void BaseLoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, 1276 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name,
1277 Label* success, 1277 Label* success,
1278 Label* miss) { 1278 Label* miss) {
1279 if (!miss->is_unused()) { 1279 if (!miss->is_unused()) {
1280 __ jmp(success); 1280 __ jmp(success);
1281 __ bind(miss); 1281 __ bind(miss);
1282 TailCallBuiltin(masm(), MissBuiltin(kind())); 1282 TailCallBuiltin(masm(), MissBuiltin(kind()));
1283 } 1283 }
1284 } 1284 }
1285 1285
1286 1286
1287 void BaseStoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, 1287 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name,
1288 Label* success, 1288 Label* success,
1289 Label* miss) { 1289 Label* miss) {
1290 if (!miss->is_unused()) { 1290 if (!miss->is_unused()) {
1291 __ jmp(success); 1291 __ jmp(success);
1292 GenerateRestoreName(masm(), miss, name); 1292 GenerateRestoreName(masm(), miss, name);
1293 TailCallBuiltin(masm(), MissBuiltin(kind())); 1293 TailCallBuiltin(masm(), MissBuiltin(kind()));
1294 } 1294 }
1295 } 1295 }
1296 1296
1297 1297
1298 Register BaseLoadStubCompiler::CallbackHandlerFrontend( 1298 Register LoadStubCompiler::CallbackHandlerFrontend(
1299 Handle<JSObject> object, 1299 Handle<JSObject> object,
1300 Register object_reg, 1300 Register object_reg,
1301 Handle<JSObject> holder, 1301 Handle<JSObject> holder,
1302 Handle<Name> name, 1302 Handle<Name> name,
1303 Label* success, 1303 Label* success,
1304 Handle<Object> callback) { 1304 Handle<Object> callback) {
1305 Label miss; 1305 Label miss;
1306 1306
1307 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); 1307 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss);
1308 1308
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1348 } 1348 }
1349 __ cmp(scratch3(), callback); 1349 __ cmp(scratch3(), callback);
1350 __ j(not_equal, &miss); 1350 __ j(not_equal, &miss);
1351 } 1351 }
1352 1352
1353 HandlerFrontendFooter(name, success, &miss); 1353 HandlerFrontendFooter(name, success, &miss);
1354 return reg; 1354 return reg;
1355 } 1355 }
1356 1356
1357 1357
1358 void BaseLoadStubCompiler::NonexistentHandlerFrontend( 1358 void LoadStubCompiler::NonexistentHandlerFrontend(
1359 Handle<JSObject> object, 1359 Handle<JSObject> object,
1360 Handle<JSObject> last, 1360 Handle<JSObject> last,
1361 Handle<Name> name, 1361 Handle<Name> name,
1362 Label* success, 1362 Label* success,
1363 Handle<GlobalObject> global) { 1363 Handle<GlobalObject> global) {
1364 Label miss; 1364 Label miss;
1365 1365
1366 HandlerFrontendHeader(object, receiver(), last, name, &miss); 1366 HandlerFrontendHeader(object, receiver(), last, name, &miss);
1367 1367
1368 // If the last object in the prototype chain is a global object, 1368 // If the last object in the prototype chain is a global object,
1369 // check that the global property cell is empty. 1369 // check that the global property cell is empty.
1370 if (!global.is_null()) { 1370 if (!global.is_null()) {
1371 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); 1371 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
1372 } 1372 }
1373 1373
1374 HandlerFrontendFooter(name, success, &miss); 1374 HandlerFrontendFooter(name, success, &miss);
1375 } 1375 }
1376 1376
1377 1377
1378 void BaseLoadStubCompiler::GenerateLoadField(Register reg, 1378 void LoadStubCompiler::GenerateLoadField(Register reg,
1379 Handle<JSObject> holder, 1379 Handle<JSObject> holder,
1380 PropertyIndex field, 1380 PropertyIndex field,
1381 Representation representation) { 1381 Representation representation) {
1382 if (!reg.is(receiver())) __ mov(receiver(), reg); 1382 if (!reg.is(receiver())) __ mov(receiver(), reg);
1383 if (kind() == Code::LOAD_IC) { 1383 if (kind() == Code::LOAD_IC) {
1384 LoadFieldStub stub(field.is_inobject(holder), 1384 LoadFieldStub stub(field.is_inobject(holder),
1385 field.translate(holder), 1385 field.translate(holder),
1386 representation); 1386 representation);
1387 GenerateTailCall(masm(), stub.GetCode(isolate())); 1387 GenerateTailCall(masm(), stub.GetCode(isolate()));
1388 } else { 1388 } else {
1389 KeyedLoadFieldStub stub(field.is_inobject(holder), 1389 KeyedLoadFieldStub stub(field.is_inobject(holder),
1390 field.translate(holder), 1390 field.translate(holder),
1391 representation); 1391 representation);
1392 GenerateTailCall(masm(), stub.GetCode(isolate())); 1392 GenerateTailCall(masm(), stub.GetCode(isolate()));
1393 } 1393 }
1394 } 1394 }
1395 1395
1396 1396
1397 void BaseLoadStubCompiler::GenerateLoadCallback( 1397 void LoadStubCompiler::GenerateLoadCallback(
1398 const CallOptimization& call_optimization) { 1398 const CallOptimization& call_optimization) {
1399 GenerateFastApiCall( 1399 GenerateFastApiCall(
1400 masm(), call_optimization, receiver(), scratch3(), 0, NULL); 1400 masm(), call_optimization, receiver(), scratch3(), 0, NULL);
1401 } 1401 }
1402 1402
1403 1403
1404 void BaseLoadStubCompiler::GenerateLoadCallback( 1404 void LoadStubCompiler::GenerateLoadCallback(
1405 Register reg, 1405 Register reg,
1406 Handle<ExecutableAccessorInfo> callback) { 1406 Handle<ExecutableAccessorInfo> callback) {
1407 // Insert additional parameters into the stack frame above return address. 1407 // Insert additional parameters into the stack frame above return address.
1408 ASSERT(!scratch3().is(reg)); 1408 ASSERT(!scratch3().is(reg));
1409 __ pop(scratch3()); // Get return address to place it below. 1409 __ pop(scratch3()); // Get return address to place it below.
1410 1410
1411 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); 1411 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
1412 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); 1412 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
1413 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); 1413 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
1414 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); 1414 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1460 1460
1461 __ CallApiFunctionAndReturn(getter_address, 1461 __ CallApiFunctionAndReturn(getter_address,
1462 thunk_address, 1462 thunk_address,
1463 ApiParameterOperand(2), 1463 ApiParameterOperand(2),
1464 kStackSpace, 1464 kStackSpace,
1465 Operand(ebp, 7 * kPointerSize), 1465 Operand(ebp, 7 * kPointerSize),
1466 NULL); 1466 NULL);
1467 } 1467 }
1468 1468
1469 1469
1470 void BaseLoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { 1470 void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) {
1471 // Return the constant value. 1471 // Return the constant value.
1472 __ LoadObject(eax, value); 1472 __ LoadObject(eax, value);
1473 __ ret(0); 1473 __ ret(0);
1474 } 1474 }
1475 1475
1476 1476
1477 void BaseLoadStubCompiler::GenerateLoadInterceptor( 1477 void LoadStubCompiler::GenerateLoadInterceptor(
1478 Register holder_reg, 1478 Register holder_reg,
1479 Handle<JSObject> object, 1479 Handle<JSObject> object,
1480 Handle<JSObject> interceptor_holder, 1480 Handle<JSObject> interceptor_holder,
1481 LookupResult* lookup, 1481 LookupResult* lookup,
1482 Handle<Name> name) { 1482 Handle<Name> name) {
1483 ASSERT(interceptor_holder->HasNamedInterceptor()); 1483 ASSERT(interceptor_holder->HasNamedInterceptor());
1484 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); 1484 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined());
1485 1485
1486 // So far the most popular follow ups for interceptor loads are FIELD 1486 // So far the most popular follow ups for interceptor loads are FIELD
1487 // and CALLBACKS, so inline only them, other cases may be added 1487 // and CALLBACKS, so inline only them, other cases may be added
(...skipping 1619 matching lines...) Expand 10 before | Expand all | Expand 10 after
3107 __ cmp(name_reg, Immediate(name)); 3107 __ cmp(name_reg, Immediate(name));
3108 __ j(not_equal, miss); 3108 __ j(not_equal, miss);
3109 } 3109 }
3110 3110
3111 3111
3112 #undef __ 3112 #undef __
3113 #define __ ACCESS_MASM(masm) 3113 #define __ ACCESS_MASM(masm)
3114 3114
3115 3115
3116 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, 3116 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
3117 Register receiver,
3117 Handle<JSFunction> getter) { 3118 Handle<JSFunction> getter) {
3118 // ----------- S t a t e -------------
3119 // -- ecx : name
3120 // -- edx : receiver
3121 // -- esp[0] : return address
3122 // -----------------------------------
3123 { 3119 {
3124 FrameScope scope(masm, StackFrame::INTERNAL); 3120 FrameScope scope(masm, StackFrame::INTERNAL);
3125 3121
3126 if (!getter.is_null()) { 3122 if (!getter.is_null()) {
3127 // Call the JavaScript getter with the receiver on the stack. 3123 // Call the JavaScript getter with the receiver on the stack.
3128 __ push(edx); 3124 __ push(receiver);
3129 ParameterCount actual(0); 3125 ParameterCount actual(0);
3130 ParameterCount expected(getter); 3126 ParameterCount expected(getter);
3131 __ InvokeFunction(getter, expected, actual, 3127 __ InvokeFunction(getter, expected, actual,
3132 CALL_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 3128 CALL_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
3133 } else { 3129 } else {
3134 // If we generate a global code snippet for deoptimization only, remember 3130 // If we generate a global code snippet for deoptimization only, remember
3135 // the place to continue after deoptimization. 3131 // the place to continue after deoptimization.
3136 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset()); 3132 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
3137 } 3133 }
3138 3134
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
3271 // ----------------------------------- 3267 // -----------------------------------
3272 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); 3268 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
3273 } 3269 }
3274 3270
3275 3271
3276 #undef __ 3272 #undef __
3277 3273
3278 } } // namespace v8::internal 3274 } } // namespace v8::internal
3279 3275
3280 #endif // V8_TARGET_ARCH_IA32 3276 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/builtins.cc ('k') | src/ic.h » ('j') | src/ic.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698