| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |