| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_X87 | 7 #if V8_TARGET_ARCH_X87 |
| 8 | 8 |
| 9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
| 10 #include "src/ic-inl.h" | 10 #include "src/ic-inl.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 // type: holds the receiver instance type on entry. | 28 // type: holds the receiver instance type on entry. |
| 29 __ cmp(type, JS_GLOBAL_OBJECT_TYPE); | 29 __ cmp(type, JS_GLOBAL_OBJECT_TYPE); |
| 30 __ j(equal, global_object); | 30 __ j(equal, global_object); |
| 31 __ cmp(type, JS_BUILTINS_OBJECT_TYPE); | 31 __ cmp(type, JS_BUILTINS_OBJECT_TYPE); |
| 32 __ j(equal, global_object); | 32 __ j(equal, global_object); |
| 33 __ cmp(type, JS_GLOBAL_PROXY_TYPE); | 33 __ cmp(type, JS_GLOBAL_PROXY_TYPE); |
| 34 __ j(equal, global_object); | 34 __ j(equal, global_object); |
| 35 } | 35 } |
| 36 | 36 |
| 37 | 37 |
| 38 // Generated code falls through if the receiver is a regular non-global | |
| 39 // JS object with slow properties and no interceptors. | |
| 40 static void GenerateNameDictionaryReceiverCheck(MacroAssembler* masm, | |
| 41 Register receiver, | |
| 42 Register r0, | |
| 43 Register r1, | |
| 44 Label* miss) { | |
| 45 // Register usage: | |
| 46 // receiver: holds the receiver on entry and is unchanged. | |
| 47 // r0: used to hold receiver instance type. | |
| 48 // Holds the property dictionary on fall through. | |
| 49 // r1: used to hold receivers map. | |
| 50 | |
| 51 // Check that the receiver isn't a smi. | |
| 52 __ JumpIfSmi(receiver, miss); | |
| 53 | |
| 54 // Check that the receiver is a valid JS object. | |
| 55 __ mov(r1, FieldOperand(receiver, HeapObject::kMapOffset)); | |
| 56 __ movzx_b(r0, FieldOperand(r1, Map::kInstanceTypeOffset)); | |
| 57 __ cmp(r0, FIRST_SPEC_OBJECT_TYPE); | |
| 58 __ j(below, miss); | |
| 59 | |
| 60 // If this assert fails, we have to check upper bound too. | |
| 61 STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE); | |
| 62 | |
| 63 GenerateGlobalInstanceTypeCheck(masm, r0, miss); | |
| 64 | |
| 65 // Check for non-global object that requires access check. | |
| 66 __ test_b(FieldOperand(r1, Map::kBitFieldOffset), | |
| 67 (1 << Map::kIsAccessCheckNeeded) | | |
| 68 (1 << Map::kHasNamedInterceptor)); | |
| 69 __ j(not_zero, miss); | |
| 70 | |
| 71 __ mov(r0, FieldOperand(receiver, JSObject::kPropertiesOffset)); | |
| 72 __ CheckMap(r0, masm->isolate()->factory()->hash_table_map(), miss, | |
| 73 DONT_DO_SMI_CHECK); | |
| 74 } | |
| 75 | |
| 76 | |
| 77 // Helper function used to load a property from a dictionary backing | 38 // Helper function used to load a property from a dictionary backing |
| 78 // storage. This function may fail to load a property even though it is | 39 // storage. This function may fail to load a property even though it is |
| 79 // in the dictionary, so code at miss_label must always call a backup | 40 // in the dictionary, so code at miss_label must always call a backup |
| 80 // property load that is complete. This function is safe to call if | 41 // property load that is complete. This function is safe to call if |
| 81 // name is not internalized, and will jump to the miss_label in that | 42 // name is not internalized, and will jump to the miss_label in that |
| 82 // case. The generated code assumes that the receiver has slow | 43 // case. The generated code assumes that the receiver has slow |
| 83 // properties, is not a global object and does not have interceptors. | 44 // properties, is not a global object and does not have interceptors. |
| 84 static void GenerateDictionaryLoad(MacroAssembler* masm, | 45 static void GenerateDictionaryLoad(MacroAssembler* masm, |
| 85 Label* miss_label, | 46 Label* miss_label, |
| 86 Register elements, | 47 Register elements, |
| (...skipping 848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); | 896 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); |
| 936 masm->isolate()->stub_cache()->GenerateProbe( | 897 masm->isolate()->stub_cache()->GenerateProbe( |
| 937 masm, flags, receiver, name, ebx, eax); | 898 masm, flags, receiver, name, ebx, eax); |
| 938 | 899 |
| 939 // Cache miss: Jump to runtime. | 900 // Cache miss: Jump to runtime. |
| 940 GenerateMiss(masm); | 901 GenerateMiss(masm); |
| 941 } | 902 } |
| 942 | 903 |
| 943 | 904 |
| 944 void LoadIC::GenerateNormal(MacroAssembler* masm) { | 905 void LoadIC::GenerateNormal(MacroAssembler* masm) { |
| 945 // ----------- S t a t e ------------- | 906 Register dictionary = eax; |
| 946 // -- ecx : name | 907 ASSERT(!dictionary.is(ReceiverRegister())); |
| 947 // -- edx : receiver | 908 ASSERT(!dictionary.is(NameRegister())); |
| 948 // -- esp[0] : return address | |
| 949 // ----------------------------------- | |
| 950 ASSERT(edx.is(ReceiverRegister())); | |
| 951 ASSERT(ecx.is(NameRegister())); | |
| 952 | 909 |
| 953 Label miss, slow; | 910 Label slow; |
| 954 | 911 |
| 955 GenerateNameDictionaryReceiverCheck(masm, edx, eax, ebx, &miss); | 912 __ mov(dictionary, |
| 956 | 913 FieldOperand(ReceiverRegister(), JSObject::kPropertiesOffset)); |
| 957 // eax: elements | 914 GenerateDictionaryLoad(masm, &slow, dictionary, NameRegister(), edi, ebx, |
| 958 // Search the dictionary placing the result in eax. | 915 eax); |
| 959 GenerateDictionaryLoad(masm, &slow, eax, ecx, edi, ebx, eax); | |
| 960 __ ret(0); | 916 __ ret(0); |
| 961 | 917 |
| 962 // Dictionary load failed, go slow (but don't miss). | 918 // Dictionary load failed, go slow (but don't miss). |
| 963 __ bind(&slow); | 919 __ bind(&slow); |
| 964 GenerateRuntimeGetProperty(masm); | 920 GenerateRuntimeGetProperty(masm); |
| 965 | |
| 966 // Cache miss: Jump to runtime. | |
| 967 __ bind(&miss); | |
| 968 GenerateMiss(masm); | |
| 969 } | 921 } |
| 970 | 922 |
| 971 | 923 |
| 972 static void LoadIC_PushArgs(MacroAssembler* masm) { | 924 static void LoadIC_PushArgs(MacroAssembler* masm) { |
| 973 Register receiver = LoadIC::ReceiverRegister(); | 925 Register receiver = LoadIC::ReceiverRegister(); |
| 974 Register name = LoadIC::NameRegister(); | 926 Register name = LoadIC::NameRegister(); |
| 975 ASSERT(!ebx.is(receiver) && !ebx.is(name)); | 927 ASSERT(!ebx.is(receiver) && !ebx.is(name)); |
| 976 | 928 |
| 977 __ pop(ebx); | 929 __ pop(ebx); |
| 978 __ push(receiver); | 930 __ push(receiver); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1087 StoreIC_PushArgs(masm); | 1039 StoreIC_PushArgs(masm); |
| 1088 | 1040 |
| 1089 // Perform tail call to the entry. | 1041 // Perform tail call to the entry. |
| 1090 ExternalReference ref = | 1042 ExternalReference ref = |
| 1091 ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate()); | 1043 ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate()); |
| 1092 __ TailCallExternalReference(ref, 3, 1); | 1044 __ TailCallExternalReference(ref, 3, 1); |
| 1093 } | 1045 } |
| 1094 | 1046 |
| 1095 | 1047 |
| 1096 void StoreIC::GenerateNormal(MacroAssembler* masm) { | 1048 void StoreIC::GenerateNormal(MacroAssembler* masm) { |
| 1097 // Return address is on the stack. | 1049 Label restore_miss; |
| 1098 Label miss, restore_miss; | |
| 1099 Register receiver = ReceiverRegister(); | 1050 Register receiver = ReceiverRegister(); |
| 1100 Register name = NameRegister(); | 1051 Register name = NameRegister(); |
| 1101 Register value = ValueRegister(); | 1052 Register value = ValueRegister(); |
| 1053 Register dictionary = ebx; |
| 1102 | 1054 |
| 1103 GenerateNameDictionaryReceiverCheck(masm, receiver, ebx, edi, &miss); | 1055 __ mov(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); |
| 1104 | 1056 |
| 1105 // A lot of registers are needed for storing to slow case | 1057 // A lot of registers are needed for storing to slow case |
| 1106 // objects. Push and restore receiver but rely on | 1058 // objects. Push and restore receiver but rely on |
| 1107 // GenerateDictionaryStore preserving the value and name. | 1059 // GenerateDictionaryStore preserving the value and name. |
| 1108 __ push(receiver); | 1060 __ push(receiver); |
| 1109 GenerateDictionaryStore(masm, &restore_miss, ebx, name, value, receiver, edi); | 1061 GenerateDictionaryStore(masm, &restore_miss, dictionary, name, value, |
| 1062 receiver, edi); |
| 1110 __ Drop(1); | 1063 __ Drop(1); |
| 1111 Counters* counters = masm->isolate()->counters(); | 1064 Counters* counters = masm->isolate()->counters(); |
| 1112 __ IncrementCounter(counters->store_normal_hit(), 1); | 1065 __ IncrementCounter(counters->store_normal_hit(), 1); |
| 1113 __ ret(0); | 1066 __ ret(0); |
| 1114 | 1067 |
| 1115 __ bind(&restore_miss); | 1068 __ bind(&restore_miss); |
| 1116 __ pop(receiver); | 1069 __ pop(receiver); |
| 1117 | |
| 1118 __ bind(&miss); | |
| 1119 __ IncrementCounter(counters->store_normal_miss(), 1); | 1070 __ IncrementCounter(counters->store_normal_miss(), 1); |
| 1120 GenerateMiss(masm); | 1071 GenerateMiss(masm); |
| 1121 } | 1072 } |
| 1122 | 1073 |
| 1123 | 1074 |
| 1124 void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, | 1075 void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, |
| 1125 StrictMode strict_mode) { | 1076 StrictMode strict_mode) { |
| 1126 // Return address is on the stack. | 1077 // Return address is on the stack. |
| 1127 ASSERT(!ebx.is(ReceiverRegister()) && !ebx.is(NameRegister()) && | 1078 ASSERT(!ebx.is(ReceiverRegister()) && !ebx.is(NameRegister()) && |
| 1128 !ebx.is(ValueRegister())); | 1079 !ebx.is(ValueRegister())); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1253 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) | 1204 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) |
| 1254 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) | 1205 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) |
| 1255 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); | 1206 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); |
| 1256 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1207 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
| 1257 } | 1208 } |
| 1258 | 1209 |
| 1259 | 1210 |
| 1260 } } // namespace v8::internal | 1211 } } // namespace v8::internal |
| 1261 | 1212 |
| 1262 #endif // V8_TARGET_ARCH_X87 | 1213 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |