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

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

Issue 39973003: Merge bleeding_edge. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: again 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/ia32/macro-assembler-ia32.cc ('k') | src/ic.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 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 16 matching lines...) Expand all
872 __ pop(value_reg); 872 __ pop(value_reg);
873 } 873 }
874 __ SmiTag(value_reg); 874 __ SmiTag(value_reg);
875 __ jmp(&do_store); 875 __ jmp(&do_store);
876 876
877 __ bind(&heap_number); 877 __ bind(&heap_number);
878 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), 878 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(),
879 miss_label, DONT_DO_SMI_CHECK); 879 miss_label, DONT_DO_SMI_CHECK);
880 if (CpuFeatures::IsSupported(SSE2)) { 880 if (CpuFeatures::IsSupported(SSE2)) {
881 CpuFeatureScope use_sse2(masm, SSE2); 881 CpuFeatureScope use_sse2(masm, SSE2);
882 __ movdbl(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); 882 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
883 } else { 883 } else {
884 __ fld_d(FieldOperand(value_reg, HeapNumber::kValueOffset)); 884 __ fld_d(FieldOperand(value_reg, HeapNumber::kValueOffset));
885 } 885 }
886 886
887 __ bind(&do_store); 887 __ bind(&do_store);
888 if (CpuFeatures::IsSupported(SSE2)) { 888 if (CpuFeatures::IsSupported(SSE2)) {
889 CpuFeatureScope use_sse2(masm, SSE2); 889 CpuFeatureScope use_sse2(masm, SSE2);
890 __ movdbl(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0); 890 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0);
891 } else { 891 } else {
892 __ fstp_d(FieldOperand(storage_reg, HeapNumber::kValueOffset)); 892 __ fstp_d(FieldOperand(storage_reg, HeapNumber::kValueOffset));
893 } 893 }
894 } 894 }
895 895
896 // Stub never generated for non-global objects that require access 896 // Stub never generated for non-global objects that require access
897 // checks. 897 // checks.
898 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 898 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
899 899
900 // Perform map transition for the receiver if necessary. 900 // Perform map transition for the receiver if necessary.
(...skipping 93 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 27 matching lines...) Expand all
1050 __ fild_s(Operand(esp, 0)); 1050 __ fild_s(Operand(esp, 0));
1051 __ pop(value_reg); 1051 __ pop(value_reg);
1052 } 1052 }
1053 __ SmiTag(value_reg); 1053 __ SmiTag(value_reg);
1054 __ jmp(&do_store); 1054 __ jmp(&do_store);
1055 __ bind(&heap_number); 1055 __ bind(&heap_number);
1056 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), 1056 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(),
1057 miss_label, DONT_DO_SMI_CHECK); 1057 miss_label, DONT_DO_SMI_CHECK);
1058 if (CpuFeatures::IsSupported(SSE2)) { 1058 if (CpuFeatures::IsSupported(SSE2)) {
1059 CpuFeatureScope use_sse2(masm, SSE2); 1059 CpuFeatureScope use_sse2(masm, SSE2);
1060 __ movdbl(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); 1060 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
1061 } else { 1061 } else {
1062 __ fld_d(FieldOperand(value_reg, HeapNumber::kValueOffset)); 1062 __ fld_d(FieldOperand(value_reg, HeapNumber::kValueOffset));
1063 } 1063 }
1064 __ bind(&do_store); 1064 __ bind(&do_store);
1065 if (CpuFeatures::IsSupported(SSE2)) { 1065 if (CpuFeatures::IsSupported(SSE2)) {
1066 CpuFeatureScope use_sse2(masm, SSE2); 1066 CpuFeatureScope use_sse2(masm, SSE2);
1067 __ movdbl(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0); 1067 __ movsd(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0);
1068 } else { 1068 } else {
1069 __ fstp_d(FieldOperand(scratch1, HeapNumber::kValueOffset)); 1069 __ fstp_d(FieldOperand(scratch1, HeapNumber::kValueOffset));
1070 } 1070 }
1071 // Return the value (register eax). 1071 // Return the value (register eax).
1072 ASSERT(value_reg.is(eax)); 1072 ASSERT(value_reg.is(eax));
1073 __ ret(0); 1073 __ ret(0);
1074 return; 1074 return;
1075 } 1075 }
1076 1076
1077 ASSERT(!FLAG_track_double_fields || !representation.IsDouble()); 1077 ASSERT(!FLAG_track_double_fields || !representation.IsDouble());
(...skipping 188 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 902 matching lines...) Expand 10 before | Expand all | Expand 10 after
2390 __ mov(eax, Operand(esp, 1 * kPointerSize)); 2390 __ mov(eax, Operand(esp, 1 * kPointerSize));
2391 2391
2392 // Check if the argument is a smi. 2392 // Check if the argument is a smi.
2393 Label smi; 2393 Label smi;
2394 STATIC_ASSERT(kSmiTag == 0); 2394 STATIC_ASSERT(kSmiTag == 0);
2395 __ JumpIfSmi(eax, &smi); 2395 __ JumpIfSmi(eax, &smi);
2396 2396
2397 // Check if the argument is a heap number and load its value into xmm0. 2397 // Check if the argument is a heap number and load its value into xmm0.
2398 Label slow; 2398 Label slow;
2399 __ CheckMap(eax, factory()->heap_number_map(), &slow, DONT_DO_SMI_CHECK); 2399 __ CheckMap(eax, factory()->heap_number_map(), &slow, DONT_DO_SMI_CHECK);
2400 __ movdbl(xmm0, FieldOperand(eax, HeapNumber::kValueOffset)); 2400 __ movsd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset));
2401 2401
2402 // Check if the argument is strictly positive. Note this also 2402 // Check if the argument is strictly positive. Note this also
2403 // discards NaN. 2403 // discards NaN.
2404 __ xorpd(xmm1, xmm1); 2404 __ xorpd(xmm1, xmm1);
2405 __ ucomisd(xmm0, xmm1); 2405 __ ucomisd(xmm0, xmm1);
2406 __ j(below_equal, &slow); 2406 __ j(below_equal, &slow);
2407 2407
2408 // Do a truncating conversion. 2408 // Do a truncating conversion.
2409 __ cvttsd2si(eax, Operand(xmm0)); 2409 __ cvttsd2si(eax, Operand(xmm0));
2410 2410
(...skipping 29 matching lines...) Expand all
2440 // xmm2 = 0...0 2440 // xmm2 = 0...0
2441 __ cmpltsd(xmm2, xmm0); 2441 __ cmpltsd(xmm2, xmm0);
2442 2442
2443 // Subtract 1 if the argument was less than the tentative result. 2443 // Subtract 1 if the argument was less than the tentative result.
2444 __ LoadPowerOf2(xmm1, ebx, 0); 2444 __ LoadPowerOf2(xmm1, ebx, 0);
2445 __ andpd(xmm1, xmm2); 2445 __ andpd(xmm1, xmm2);
2446 __ subsd(xmm0, xmm1); 2446 __ subsd(xmm0, xmm1);
2447 2447
2448 // Return a new heap number. 2448 // Return a new heap number.
2449 __ AllocateHeapNumber(eax, ebx, edx, &slow); 2449 __ AllocateHeapNumber(eax, ebx, edx, &slow);
2450 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); 2450 __ movsd(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
2451 __ ret(2 * kPointerSize); 2451 __ ret(2 * kPointerSize);
2452 2452
2453 // Return the argument (when it's an already round heap number). 2453 // Return the argument (when it's an already round heap number).
2454 __ bind(&already_round); 2454 __ bind(&already_round);
2455 __ mov(eax, Operand(esp, 1 * kPointerSize)); 2455 __ mov(eax, Operand(esp, 1 * kPointerSize));
2456 __ ret(2 * kPointerSize); 2456 __ ret(2 * kPointerSize);
2457 2457
2458 // Tail call the full function. We do not have to patch the receiver 2458 // Tail call the full function. We do not have to patch the receiver
2459 // because the function makes no use of it. 2459 // because the function makes no use of it.
2460 __ bind(&slow); 2460 __ bind(&slow);
(...skipping 646 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/ia32/macro-assembler-ia32.cc ('k') | src/ic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698