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

Side by Side Diff: src/ia32/ic-ia32.cc

Issue 502028: Streamline the calling convention of the call ICs by passing the... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years 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/fast-codegen-ia32.cc ('k') | src/ia32/stub-cache-ia32.cc » ('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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 870 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 __ bind(&slow); 881 __ bind(&slow);
882 Generate(masm, ExternalReference(Runtime::kSetProperty)); 882 Generate(masm, ExternalReference(Runtime::kSetProperty));
883 } 883 }
884 884
885 885
886 // Defined in ic.cc. 886 // Defined in ic.cc.
887 Object* CallIC_Miss(Arguments args); 887 Object* CallIC_Miss(Arguments args);
888 888
889 void CallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) { 889 void CallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
890 // ----------- S t a t e ------------- 890 // ----------- S t a t e -------------
891 // -- ecx : name
892 // -- esp[0] : return address
893 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
894 // -- ...
895 // -- esp[(argc + 1) * 4] : receiver
891 // ----------------------------------- 896 // -----------------------------------
892 Label number, non_number, non_string, boolean, probe, miss; 897 Label number, non_number, non_string, boolean, probe, miss;
893 898
894 // Get the receiver of the function from the stack; 1 ~ return address. 899 // Get the receiver of the function from the stack; 1 ~ return address.
895 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 900 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
896 // Get the name of the function from the stack; 2 ~ return address, receiver
897 __ mov(ecx, Operand(esp, (argc + 2) * kPointerSize));
898 901
899 // Probe the stub cache. 902 // Probe the stub cache.
900 Code::Flags flags = 903 Code::Flags flags =
901 Code::ComputeFlags(Code::CALL_IC, NOT_IN_LOOP, MONOMORPHIC, NORMAL, argc); 904 Code::ComputeFlags(Code::CALL_IC, NOT_IN_LOOP, MONOMORPHIC, NORMAL, argc);
902 StubCache::GenerateProbe(masm, flags, edx, ecx, ebx, eax); 905 StubCache::GenerateProbe(masm, flags, edx, ecx, ebx, eax);
903 906
904 // If the stub cache probing failed, the receiver might be a value. 907 // If the stub cache probing failed, the receiver might be a value.
905 // For value objects, we use the map of the prototype objects for 908 // For value objects, we use the map of the prototype objects for
906 // the corresponding JSValue for the cache and that is what we need 909 // the corresponding JSValue for the cache and that is what we need
907 // to probe. 910 // to probe.
(...skipping 25 matching lines...) Expand all
933 __ bind(&boolean); 936 __ bind(&boolean);
934 StubCompiler::GenerateLoadGlobalFunctionPrototype( 937 StubCompiler::GenerateLoadGlobalFunctionPrototype(
935 masm, Context::BOOLEAN_FUNCTION_INDEX, edx); 938 masm, Context::BOOLEAN_FUNCTION_INDEX, edx);
936 939
937 // Probe the stub cache for the value object. 940 // Probe the stub cache for the value object.
938 __ bind(&probe); 941 __ bind(&probe);
939 StubCache::GenerateProbe(masm, flags, edx, ecx, ebx, no_reg); 942 StubCache::GenerateProbe(masm, flags, edx, ecx, ebx, no_reg);
940 943
941 // Cache miss: Jump to runtime. 944 // Cache miss: Jump to runtime.
942 __ bind(&miss); 945 __ bind(&miss);
943 Generate(masm, argc, ExternalReference(IC_Utility(kCallIC_Miss))); 946 GenerateMiss(masm, argc);
944 } 947 }
945 948
946 949
947 static void GenerateNormalHelper(MacroAssembler* masm, 950 static void GenerateNormalHelper(MacroAssembler* masm,
948 int argc, 951 int argc,
949 bool is_global_object, 952 bool is_global_object,
950 Label* miss) { 953 Label* miss) {
951 // Search dictionary - put result in register edx. 954 // ----------- S t a t e -------------
952 GenerateDictionaryLoad(masm, miss, eax, edx, ebx, ecx, CHECK_DICTIONARY); 955 // -- ecx : name
956 // -- edx : receiver
957 // -- esp[0] : return address
958 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
959 // -- ...
960 // -- esp[(argc + 1) * 4] : receiver
961 // -----------------------------------
953 962
954 // Move the result to register edi and check that it isn't a smi. 963 // Search dictionary - put result in register edi.
955 __ mov(edi, Operand(edx)); 964 __ mov(edi, edx);
956 __ test(edx, Immediate(kSmiTagMask)); 965 GenerateDictionaryLoad(masm, miss, eax, edi, ebx, ecx, CHECK_DICTIONARY);
966
967 // Check that the result is not a smi.
968 __ test(edi, Immediate(kSmiTagMask));
957 __ j(zero, miss, not_taken); 969 __ j(zero, miss, not_taken);
958 970
959 // Check that the value is a JavaScript function. 971 // Check that the value is a JavaScript function, fetching its map into eax.
960 __ CmpObjectType(edx, JS_FUNCTION_TYPE, edx); 972 __ CmpObjectType(edi, JS_FUNCTION_TYPE, eax);
961 __ j(not_equal, miss, not_taken); 973 __ j(not_equal, miss, not_taken);
962 974
963 // Check that the function has been loaded. 975 // Check that the function has been loaded. eax holds function's map.
964 __ mov(edx, FieldOperand(edi, JSFunction::kMapOffset)); 976 __ mov(eax, FieldOperand(eax, Map::kBitField2Offset));
965 __ mov(edx, FieldOperand(edx, Map::kBitField2Offset)); 977 __ test(eax, Immediate(1 << Map::kNeedsLoading));
966 __ test(edx, Immediate(1 << Map::kNeedsLoading));
967 __ j(not_zero, miss, not_taken); 978 __ j(not_zero, miss, not_taken);
968 979
969 // Patch the receiver with the global proxy if necessary. 980 // Patch the receiver on stack with the global proxy if necessary.
970 if (is_global_object) { 981 if (is_global_object) {
971 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
972 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 982 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
973 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); 983 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
974 } 984 }
975 985
976 // Invoke the function. 986 // Invoke the function.
977 ParameterCount actual(argc); 987 ParameterCount actual(argc);
978 __ InvokeFunction(edi, actual, JUMP_FUNCTION); 988 __ InvokeFunction(edi, actual, JUMP_FUNCTION);
979 } 989 }
980 990
981 991
982 void CallIC::GenerateNormal(MacroAssembler* masm, int argc) { 992 void CallIC::GenerateNormal(MacroAssembler* masm, int argc) {
983 // ----------- S t a t e ------------- 993 // ----------- S t a t e -------------
994 // -- ecx : name
995 // -- esp[0] : return address
996 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
997 // -- ...
998 // -- esp[(argc + 1) * 4] : receiver
984 // ----------------------------------- 999 // -----------------------------------
985 1000
986 Label miss, global_object, non_global_object; 1001 Label miss, global_object, non_global_object;
987 1002
988 // Get the receiver of the function from the stack; 1 ~ return address. 1003 // Get the receiver of the function from the stack; 1 ~ return address.
989 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1004 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
990 // Get the name of the function from the stack; 2 ~ return address, receiver.
991 __ mov(ecx, Operand(esp, (argc + 2) * kPointerSize));
992 1005
993 // Check that the receiver isn't a smi. 1006 // Check that the receiver isn't a smi.
994 __ test(edx, Immediate(kSmiTagMask)); 1007 __ test(edx, Immediate(kSmiTagMask));
995 __ j(zero, &miss, not_taken); 1008 __ j(zero, &miss, not_taken);
996 1009
997 // Check that the receiver is a valid JS object. 1010 // Check that the receiver is a valid JS object.
998 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset)); 1011 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
999 __ movzx_b(eax, FieldOperand(ebx, Map::kInstanceTypeOffset)); 1012 __ movzx_b(eax, FieldOperand(ebx, Map::kInstanceTypeOffset));
1000 __ cmp(eax, FIRST_JS_OBJECT_TYPE); 1013 __ cmp(eax, FIRST_JS_OBJECT_TYPE);
1001 __ j(below, &miss, not_taken); 1014 __ j(below, &miss, not_taken);
(...skipping 28 matching lines...) Expand all
1030 __ bind(&invoke); 1043 __ bind(&invoke);
1031 GenerateNormalHelper(masm, argc, false, &miss); 1044 GenerateNormalHelper(masm, argc, false, &miss);
1032 1045
1033 // Global object proxy access: Check access rights. 1046 // Global object proxy access: Check access rights.
1034 __ bind(&global_proxy); 1047 __ bind(&global_proxy);
1035 __ CheckAccessGlobalProxy(edx, eax, &miss); 1048 __ CheckAccessGlobalProxy(edx, eax, &miss);
1036 __ jmp(&invoke); 1049 __ jmp(&invoke);
1037 1050
1038 // Cache miss: Jump to runtime. 1051 // Cache miss: Jump to runtime.
1039 __ bind(&miss); 1052 __ bind(&miss);
1040 Generate(masm, argc, ExternalReference(IC_Utility(kCallIC_Miss))); 1053 GenerateMiss(masm, argc);
1041 } 1054 }
1042 1055
1043 1056
1044 void CallIC::Generate(MacroAssembler* masm, 1057 void CallIC::GenerateMiss(MacroAssembler* masm, int argc) {
1045 int argc,
1046 const ExternalReference& f) {
1047 // ----------- S t a t e ------------- 1058 // ----------- S t a t e -------------
1059 // -- ecx : name
1060 // -- esp[0] : return address
1061 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1062 // -- ...
1063 // -- esp[(argc + 1) * 4] : receiver
1048 // ----------------------------------- 1064 // -----------------------------------
1049 1065
1050 // Get the receiver of the function from the stack; 1 ~ return address. 1066 // Get the receiver of the function from the stack; 1 ~ return address.
1051 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1067 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1052 // Get the name of the function to call from the stack.
1053 // 2 ~ receiver, return address.
1054 __ mov(ebx, Operand(esp, (argc + 2) * kPointerSize));
1055 1068
1056 // Enter an internal frame. 1069 // Enter an internal frame.
1057 __ EnterInternalFrame(); 1070 __ EnterInternalFrame();
1058 1071
1059 // Push the receiver and the name of the function. 1072 // Push the receiver and the name of the function.
1060 __ push(edx); 1073 __ push(edx);
1061 __ push(ebx); 1074 __ push(ecx);
1062 1075
1063 // Call the entry. 1076 // Call the entry.
1064 CEntryStub stub(1); 1077 CEntryStub stub(1);
1065 __ mov(eax, Immediate(2)); 1078 __ mov(eax, Immediate(2));
1066 __ mov(ebx, Immediate(f)); 1079 __ mov(ebx, Immediate(ExternalReference(IC_Utility(kCallIC_Miss))));
1067 __ CallStub(&stub); 1080 __ CallStub(&stub);
1068 1081
1069 // Move result to edi and exit the internal frame. 1082 // Move result to edi and exit the internal frame.
1070 __ mov(edi, eax); 1083 __ mov(edi, eax);
1071 __ LeaveInternalFrame(); 1084 __ LeaveInternalFrame();
1072 1085
1073 // Check if the receiver is a global object of some sort. 1086 // Check if the receiver is a global object of some sort.
1074 Label invoke, global; 1087 Label invoke, global;
1075 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); // receiver 1088 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); // receiver
1076 __ test(edx, Immediate(kSmiTagMask)); 1089 __ test(edx, Immediate(kSmiTagMask));
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
1426 1439
1427 // Do tail-call to runtime routine. 1440 // Do tail-call to runtime routine.
1428 __ TailCallRuntime( 1441 __ TailCallRuntime(
1429 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1); 1442 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
1430 } 1443 }
1431 1444
1432 #undef __ 1445 #undef __
1433 1446
1434 1447
1435 } } // namespace v8::internal 1448 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/fast-codegen-ia32.cc ('k') | src/ia32/stub-cache-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698