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 |