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_X64 | 7 #if V8_TARGET_ARCH_X64 |
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 __ cmpb(type, Immediate(JS_GLOBAL_OBJECT_TYPE)); | 29 __ cmpb(type, Immediate(JS_GLOBAL_OBJECT_TYPE)); |
30 __ j(equal, global_object); | 30 __ j(equal, global_object); |
31 __ cmpb(type, Immediate(JS_BUILTINS_OBJECT_TYPE)); | 31 __ cmpb(type, Immediate(JS_BUILTINS_OBJECT_TYPE)); |
32 __ j(equal, global_object); | 32 __ j(equal, global_object); |
33 __ cmpb(type, Immediate(JS_GLOBAL_PROXY_TYPE)); | 33 __ cmpb(type, Immediate(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 __ JumpIfSmi(receiver, miss); | |
52 | |
53 // Check that the receiver is a valid JS object. | |
54 __ movp(r1, FieldOperand(receiver, HeapObject::kMapOffset)); | |
55 __ movb(r0, FieldOperand(r1, Map::kInstanceTypeOffset)); | |
56 __ cmpb(r0, Immediate(FIRST_SPEC_OBJECT_TYPE)); | |
57 __ j(below, miss); | |
58 | |
59 // If this assert fails, we have to check upper bound too. | |
60 STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE); | |
61 | |
62 GenerateGlobalInstanceTypeCheck(masm, r0, miss); | |
63 | |
64 // Check for non-global object that requires access check. | |
65 __ testb(FieldOperand(r1, Map::kBitFieldOffset), | |
66 Immediate((1 << Map::kIsAccessCheckNeeded) | | |
67 (1 << Map::kHasNamedInterceptor))); | |
68 __ j(not_zero, miss); | |
69 | |
70 __ movp(r0, FieldOperand(receiver, JSObject::kPropertiesOffset)); | |
71 __ CompareRoot(FieldOperand(r0, HeapObject::kMapOffset), | |
72 Heap::kHashTableMapRootIndex); | |
73 __ j(not_equal, miss); | |
74 } | |
75 | |
76 | |
77 | |
78 // Helper function used to load a property from a dictionary backing storage. | 38 // Helper function used to load a property from a dictionary backing storage. |
79 // This function may return false negatives, so miss_label | 39 // This function may return false negatives, so miss_label |
80 // must always call a backup property load that is complete. | 40 // must always call a backup property load that is complete. |
81 // This function is safe to call if name is not an internalized string, | 41 // This function is safe to call if name is not an internalized string, |
82 // and will jump to the miss_label in that case. | 42 // and will jump to the miss_label in that case. |
83 // The generated code assumes that the receiver has slow properties, | 43 // The generated code assumes that the receiver has slow properties, |
84 // is not a global object and does not have interceptors. | 44 // is not a global object and does not have interceptors. |
85 static void GenerateDictionaryLoad(MacroAssembler* masm, | 45 static void GenerateDictionaryLoad(MacroAssembler* masm, |
86 Label* miss_label, | 46 Label* miss_label, |
87 Register elements, | 47 Register elements, |
(...skipping 862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
950 // Probe the stub cache. | 910 // Probe the stub cache. |
951 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); | 911 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); |
952 masm->isolate()->stub_cache()->GenerateProbe( | 912 masm->isolate()->stub_cache()->GenerateProbe( |
953 masm, flags, receiver, name, rbx, rax); | 913 masm, flags, receiver, name, rbx, rax); |
954 | 914 |
955 GenerateMiss(masm); | 915 GenerateMiss(masm); |
956 } | 916 } |
957 | 917 |
958 | 918 |
959 void LoadIC::GenerateNormal(MacroAssembler* masm) { | 919 void LoadIC::GenerateNormal(MacroAssembler* masm) { |
960 // ----------- S t a t e ------------- | 920 Register dictionary = rax; |
961 // -- rdx : receiver | 921 ASSERT(!dictionary.is(ReceiverRegister())); |
962 // -- rcx : name | 922 ASSERT(!dictionary.is(NameRegister())); |
963 // -- rsp[0] : return address | |
964 // ----------------------------------- | |
965 ASSERT(rdx.is(ReceiverRegister())); | |
966 ASSERT(rcx.is(NameRegister())); | |
967 Label miss, slow; | |
968 | 923 |
969 GenerateNameDictionaryReceiverCheck(masm, rdx, rax, rbx, &miss); | 924 Label slow; |
970 | 925 |
971 // rax: elements | 926 __ movp(dictionary, |
972 // Search the dictionary placing the result in rax. | 927 FieldOperand(ReceiverRegister(), JSObject::kPropertiesOffset)); |
973 GenerateDictionaryLoad(masm, &slow, rax, rcx, rbx, rdi, rax); | 928 GenerateDictionaryLoad(masm, &slow, dictionary, NameRegister(), rbx, rdi, |
| 929 rax); |
974 __ ret(0); | 930 __ ret(0); |
975 | 931 |
976 // Dictionary load failed, go slow (but don't miss). | 932 // Dictionary load failed, go slow (but don't miss). |
977 __ bind(&slow); | 933 __ bind(&slow); |
978 GenerateRuntimeGetProperty(masm); | 934 GenerateRuntimeGetProperty(masm); |
979 | |
980 // Cache miss: Jump to runtime. | |
981 __ bind(&miss); | |
982 GenerateMiss(masm); | |
983 } | 935 } |
984 | 936 |
985 | 937 |
986 // A register that isn't one of the parameters to the load ic. | 938 // A register that isn't one of the parameters to the load ic. |
987 static const Register LoadIC_TempRegister() { return rbx; } | 939 static const Register LoadIC_TempRegister() { return rbx; } |
988 | 940 |
989 | 941 |
990 static const Register KeyedLoadIC_TempRegister() { | 942 static const Register KeyedLoadIC_TempRegister() { |
991 return rbx; | 943 return rbx; |
992 } | 944 } |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1111 StoreIC_PushArgs(masm); | 1063 StoreIC_PushArgs(masm); |
1112 | 1064 |
1113 // Perform tail call to the entry. | 1065 // Perform tail call to the entry. |
1114 ExternalReference ref = | 1066 ExternalReference ref = |
1115 ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate()); | 1067 ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate()); |
1116 __ TailCallExternalReference(ref, 3, 1); | 1068 __ TailCallExternalReference(ref, 3, 1); |
1117 } | 1069 } |
1118 | 1070 |
1119 | 1071 |
1120 void StoreIC::GenerateNormal(MacroAssembler* masm) { | 1072 void StoreIC::GenerateNormal(MacroAssembler* masm) { |
1121 // Return address is on the stack. | |
1122 Register receiver = ReceiverRegister(); | 1073 Register receiver = ReceiverRegister(); |
1123 Register name = NameRegister(); | 1074 Register name = NameRegister(); |
1124 Register value = ValueRegister(); | 1075 Register value = ValueRegister(); |
| 1076 Register dictionary = rbx; |
1125 | 1077 |
1126 Label miss; | 1078 Label miss; |
1127 | 1079 |
1128 GenerateNameDictionaryReceiverCheck(masm, receiver, rbx, rdi, &miss); | 1080 __ movp(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); |
1129 | 1081 GenerateDictionaryStore(masm, &miss, dictionary, name, value, r8, r9); |
1130 GenerateDictionaryStore(masm, &miss, rbx, name, value, r8, r9); | |
1131 Counters* counters = masm->isolate()->counters(); | 1082 Counters* counters = masm->isolate()->counters(); |
1132 __ IncrementCounter(counters->store_normal_hit(), 1); | 1083 __ IncrementCounter(counters->store_normal_hit(), 1); |
1133 __ ret(0); | 1084 __ ret(0); |
1134 | 1085 |
1135 __ bind(&miss); | 1086 __ bind(&miss); |
1136 __ IncrementCounter(counters->store_normal_miss(), 1); | 1087 __ IncrementCounter(counters->store_normal_miss(), 1); |
1137 GenerateMiss(masm); | 1088 GenerateMiss(masm); |
1138 } | 1089 } |
1139 | 1090 |
1140 | 1091 |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1272 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) | 1223 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) |
1273 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) | 1224 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) |
1274 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); | 1225 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); |
1275 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1226 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
1276 } | 1227 } |
1277 | 1228 |
1278 | 1229 |
1279 } } // namespace v8::internal | 1230 } } // namespace v8::internal |
1280 | 1231 |
1281 #endif // V8_TARGET_ARCH_X64 | 1232 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |