Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: src/ic/x64/ic-x64.cc

Issue 2622003004: [ic] Port {Load,Store}IC_Normal to TF (Closed)
Patch Set: fix nit Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ic/s390/ic-s390.cc ('k') | src/ic/x87/ic-x87.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #if V8_TARGET_ARCH_X64 5 #if V8_TARGET_ARCH_X64
6 6
7 #include "src/codegen.h" 7 #include "src/codegen.h"
8 #include "src/ic/ic.h" 8 #include "src/ic/ic.h"
9 #include "src/ic/ic-compiler.h" 9 #include "src/ic/ic-compiler.h"
10 #include "src/ic/stub-cache.h" 10 #include "src/ic/stub-cache.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 14
15 // ---------------------------------------------------------------------------- 15 // ----------------------------------------------------------------------------
16 // Static IC stub generators. 16 // Static IC stub generators.
17 // 17 //
18 18
19 #define __ ACCESS_MASM(masm) 19 #define __ ACCESS_MASM(masm)
20 20
21 // Helper function used to load a property from a dictionary backing storage.
22 // This function may return false negatives, so miss_label
23 // must always call a backup property load that is complete.
24 // This function is safe to call if name is not an internalized string,
25 // and will jump to the miss_label in that case.
26 // The generated code assumes that the receiver has slow properties,
27 // is not a global object and does not have interceptors.
28 static void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss_label,
29 Register elements, Register name,
30 Register r0, Register r1, Register result) {
31 // Register use:
32 //
33 // elements - holds the property dictionary on entry and is unchanged.
34 //
35 // name - holds the name of the property on entry and is unchanged.
36 //
37 // r0 - used to hold the capacity of the property dictionary.
38 //
39 // r1 - used to hold the index into the property dictionary.
40 //
41 // result - holds the result on exit if the load succeeded.
42
43 Label done;
44
45 // Probe the dictionary.
46 NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss_label, &done,
47 elements, name, r0, r1);
48
49 // If probing finds an entry in the dictionary, r1 contains the
50 // index into the dictionary. Check that the value is a normal
51 // property.
52 __ bind(&done);
53 const int kElementsStartOffset =
54 NameDictionary::kHeaderSize +
55 NameDictionary::kElementsStartIndex * kPointerSize;
56 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
57 __ Test(Operand(elements, r1, times_pointer_size,
58 kDetailsOffset - kHeapObjectTag),
59 Smi::FromInt(PropertyDetails::TypeField::kMask));
60 __ j(not_zero, miss_label);
61
62 // Get the value at the masked, scaled index.
63 const int kValueOffset = kElementsStartOffset + kPointerSize;
64 __ movp(result, Operand(elements, r1, times_pointer_size,
65 kValueOffset - kHeapObjectTag));
66 }
67
68
69 // Helper function used to store a property to a dictionary backing
70 // storage. This function may fail to store a property even though it
71 // is in the dictionary, so code at miss_label must always call a
72 // backup property store that is complete. This function is safe to
73 // call if name is not an internalized string, and will jump to the miss_label
74 // in that case. The generated code assumes that the receiver has slow
75 // properties, is not a global object and does not have interceptors.
76 static void GenerateDictionaryStore(MacroAssembler* masm, Label* miss_label,
77 Register elements, Register name,
78 Register value, Register scratch0,
79 Register scratch1) {
80 // Register use:
81 //
82 // elements - holds the property dictionary on entry and is clobbered.
83 //
84 // name - holds the name of the property on entry and is unchanged.
85 //
86 // value - holds the value to store and is unchanged.
87 //
88 // scratch0 - used during the positive dictionary lookup and is clobbered.
89 //
90 // scratch1 - used for index into the property dictionary and is clobbered.
91 Label done;
92
93 // Probe the dictionary.
94 NameDictionaryLookupStub::GeneratePositiveLookup(
95 masm, miss_label, &done, elements, name, scratch0, scratch1);
96
97 // If probing finds an entry in the dictionary, scratch0 contains the
98 // index into the dictionary. Check that the value is a normal
99 // property that is not read only.
100 __ bind(&done);
101 const int kElementsStartOffset =
102 NameDictionary::kHeaderSize +
103 NameDictionary::kElementsStartIndex * kPointerSize;
104 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
105 const int kTypeAndReadOnlyMask =
106 PropertyDetails::TypeField::kMask |
107 PropertyDetails::AttributesField::encode(READ_ONLY);
108 __ Test(Operand(elements, scratch1, times_pointer_size,
109 kDetailsOffset - kHeapObjectTag),
110 Smi::FromInt(kTypeAndReadOnlyMask));
111 __ j(not_zero, miss_label);
112
113 // Store the value at the masked, scaled index.
114 const int kValueOffset = kElementsStartOffset + kPointerSize;
115 __ leap(scratch1, Operand(elements, scratch1, times_pointer_size,
116 kValueOffset - kHeapObjectTag));
117 __ movp(Operand(scratch1, 0), value);
118
119 // Update write barrier. Make sure not to clobber the value.
120 __ movp(scratch0, value);
121 __ RecordWrite(elements, scratch1, scratch0, kDontSaveFPRegs);
122 }
123
124 void LoadIC::GenerateNormal(MacroAssembler* masm) {
125 Register dictionary = rax;
126 DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister()));
127 DCHECK(!dictionary.is(LoadDescriptor::NameRegister()));
128
129 Label slow;
130
131 __ movp(dictionary, FieldOperand(LoadDescriptor::ReceiverRegister(),
132 JSObject::kPropertiesOffset));
133 GenerateDictionaryLoad(masm, &slow, dictionary,
134 LoadDescriptor::NameRegister(), rbx, rdi, rax);
135 __ ret(0);
136
137 // Dictionary load failed, go slow (but don't miss).
138 __ bind(&slow);
139 LoadIC::GenerateRuntimeGetProperty(masm);
140 }
141
142 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
143 // The return address is on the stack.
144 Register receiver = LoadDescriptor::ReceiverRegister();
145 Register name = LoadDescriptor::NameRegister();
146
147 DCHECK(!rbx.is(receiver) && !rbx.is(name));
148
149 __ PopReturnAddressTo(rbx);
150 __ Push(receiver);
151 __ Push(name);
152 __ PushReturnAddressFrom(rbx);
153
154 // Do tail-call to runtime routine.
155 __ TailCallRuntime(Runtime::kGetProperty);
156 }
157
158 static void StoreIC_PushArgs(MacroAssembler* masm) { 21 static void StoreIC_PushArgs(MacroAssembler* masm) {
159 Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); 22 Register receiver = StoreWithVectorDescriptor::ReceiverRegister();
160 Register name = StoreWithVectorDescriptor::NameRegister(); 23 Register name = StoreWithVectorDescriptor::NameRegister();
161 Register value = StoreWithVectorDescriptor::ValueRegister(); 24 Register value = StoreWithVectorDescriptor::ValueRegister();
162 Register slot = StoreWithVectorDescriptor::SlotRegister(); 25 Register slot = StoreWithVectorDescriptor::SlotRegister();
163 Register vector = StoreWithVectorDescriptor::VectorRegister(); 26 Register vector = StoreWithVectorDescriptor::VectorRegister();
164 Register temp = r11; 27 Register temp = r11;
165 DCHECK(!AreAliased(receiver, name, value, slot, vector, temp)); 28 DCHECK(!AreAliased(receiver, name, value, slot, vector, temp));
166 29
167 __ PopReturnAddressTo(temp); 30 __ PopReturnAddressTo(temp);
168 __ Push(value); 31 __ Push(value);
169 __ Push(slot); 32 __ Push(slot);
170 __ Push(vector); 33 __ Push(vector);
171 __ Push(receiver); 34 __ Push(receiver);
172 __ Push(name); 35 __ Push(name);
173 __ PushReturnAddressFrom(temp); 36 __ PushReturnAddressFrom(temp);
174 } 37 }
175 38
176
177 void StoreIC::GenerateMiss(MacroAssembler* masm) {
178 // Return address is on the stack.
179 StoreIC_PushArgs(masm);
180
181 // Perform tail call to the entry.
182 __ TailCallRuntime(Runtime::kStoreIC_Miss);
183 }
184
185
186 void StoreIC::GenerateNormal(MacroAssembler* masm) {
187 Register receiver = StoreDescriptor::ReceiverRegister();
188 Register name = StoreDescriptor::NameRegister();
189 Register value = StoreDescriptor::ValueRegister();
190 Register dictionary = r11;
191 DCHECK(!AreAliased(dictionary, StoreWithVectorDescriptor::VectorRegister(),
192 StoreWithVectorDescriptor::SlotRegister()));
193
194 Label miss;
195
196 __ movp(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset));
197 GenerateDictionaryStore(masm, &miss, dictionary, name, value, r8, r9);
198 Counters* counters = masm->isolate()->counters();
199 __ IncrementCounter(counters->ic_store_normal_hit(), 1);
200 __ ret(0);
201
202 __ bind(&miss);
203 __ IncrementCounter(counters->ic_store_normal_miss(), 1);
204 GenerateMiss(masm);
205 }
206
207
208 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { 39 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
209 // Return address is on the stack. 40 // Return address is on the stack.
210 StoreIC_PushArgs(masm); 41 StoreIC_PushArgs(masm);
211 42
212 // Do tail-call to runtime routine. 43 // Do tail-call to runtime routine.
213 __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss); 44 __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss);
214 } 45 }
215 46
216 void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) { 47 void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
217 // Return address is on the stack. 48 // Return address is on the stack.
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 Condition cc = 121 Condition cc =
291 (check == ENABLE_INLINED_SMI_CHECK) 122 (check == ENABLE_INLINED_SMI_CHECK)
292 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) 123 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero)
293 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); 124 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry);
294 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); 125 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
295 } 126 }
296 } // namespace internal 127 } // namespace internal
297 } // namespace v8 128 } // namespace v8
298 129
299 #endif // V8_TARGET_ARCH_X64 130 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/ic/s390/ic-s390.cc ('k') | src/ic/x87/ic-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698