Chromium Code Reviews| 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 // The return address is on the stack. |
|
Toon Verwaest
2014/07/14 15:11:58
That comment is a bit superfluous given that that'
Jakob Kummerow
2014/07/14 15:27:13
Done.
| |
| 961 // -- rdx : receiver | |
| 962 // -- rcx : name | |
| 963 // -- rsp[0] : return address | |
| 964 // ----------------------------------- | |
| 965 ASSERT(rdx.is(ReceiverRegister())); | |
| 966 ASSERT(rcx.is(NameRegister())); | |
| 967 Label miss, slow; | |
| 968 | 921 |
| 969 GenerateNameDictionaryReceiverCheck(masm, rdx, rax, rbx, &miss); | 922 Register dictionary = rax; |
| 923 ASSERT(!dictionary.is(ReceiverRegister())); | |
| 924 ASSERT(!dictionary.is(NameRegister())); | |
| 970 | 925 |
| 971 // rax: elements | 926 Label slow; |
| 972 // Search the dictionary placing the result in rax. | 927 |
| 973 GenerateDictionaryLoad(masm, &slow, rax, rcx, rbx, rdi, rax); | 928 __ movp(dictionary, |
| 929 FieldOperand(ReceiverRegister(), JSObject::kPropertiesOffset)); | |
| 930 GenerateDictionaryLoad(masm, &slow, dictionary, NameRegister(), rbx, rdi, | |
| 931 rax); | |
| 974 __ ret(0); | 932 __ ret(0); |
| 975 | 933 |
| 976 // Dictionary load failed, go slow (but don't miss). | 934 // Dictionary load failed, go slow (but don't miss). |
| 977 __ bind(&slow); | 935 __ bind(&slow); |
| 978 GenerateRuntimeGetProperty(masm); | 936 GenerateRuntimeGetProperty(masm); |
| 979 | |
| 980 // Cache miss: Jump to runtime. | |
| 981 __ bind(&miss); | |
| 982 GenerateMiss(masm); | |
| 983 } | 937 } |
| 984 | 938 |
| 985 | 939 |
| 986 // A register that isn't one of the parameters to the load ic. | 940 // A register that isn't one of the parameters to the load ic. |
| 987 static const Register LoadIC_TempRegister() { return rbx; } | 941 static const Register LoadIC_TempRegister() { return rbx; } |
| 988 | 942 |
| 989 | 943 |
| 990 static const Register KeyedLoadIC_TempRegister() { | 944 static const Register KeyedLoadIC_TempRegister() { |
| 991 return rbx; | 945 return rbx; |
| 992 } | 946 } |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1115 ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate()); | 1069 ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate()); |
| 1116 __ TailCallExternalReference(ref, 3, 1); | 1070 __ TailCallExternalReference(ref, 3, 1); |
| 1117 } | 1071 } |
| 1118 | 1072 |
| 1119 | 1073 |
| 1120 void StoreIC::GenerateNormal(MacroAssembler* masm) { | 1074 void StoreIC::GenerateNormal(MacroAssembler* masm) { |
| 1121 // Return address is on the stack. | 1075 // Return address is on the stack. |
| 1122 Register receiver = ReceiverRegister(); | 1076 Register receiver = ReceiverRegister(); |
| 1123 Register name = NameRegister(); | 1077 Register name = NameRegister(); |
| 1124 Register value = ValueRegister(); | 1078 Register value = ValueRegister(); |
| 1079 Register dictionary = rbx; | |
| 1125 | 1080 |
| 1126 Label miss; | 1081 Label miss; |
| 1127 | 1082 |
| 1128 GenerateNameDictionaryReceiverCheck(masm, receiver, rbx, rdi, &miss); | 1083 __ movp(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); |
| 1129 | 1084 GenerateDictionaryStore(masm, &miss, dictionary, name, value, r8, r9); |
| 1130 GenerateDictionaryStore(masm, &miss, rbx, name, value, r8, r9); | |
| 1131 Counters* counters = masm->isolate()->counters(); | 1085 Counters* counters = masm->isolate()->counters(); |
| 1132 __ IncrementCounter(counters->store_normal_hit(), 1); | 1086 __ IncrementCounter(counters->store_normal_hit(), 1); |
| 1133 __ ret(0); | 1087 __ ret(0); |
| 1134 | 1088 |
| 1135 __ bind(&miss); | 1089 __ bind(&miss); |
| 1136 __ IncrementCounter(counters->store_normal_miss(), 1); | 1090 __ IncrementCounter(counters->store_normal_miss(), 1); |
| 1137 GenerateMiss(masm); | 1091 GenerateMiss(masm); |
| 1138 } | 1092 } |
| 1139 | 1093 |
| 1140 | 1094 |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1272 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) | 1226 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) |
| 1273 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) | 1227 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) |
| 1274 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); | 1228 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); |
| 1275 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1229 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
| 1276 } | 1230 } |
| 1277 | 1231 |
| 1278 | 1232 |
| 1279 } } // namespace v8::internal | 1233 } } // namespace v8::internal |
| 1280 | 1234 |
| 1281 #endif // V8_TARGET_ARCH_X64 | 1235 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |