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

Side by Side Diff: src/ic/ia32/ic-ia32.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/arm64/ic-arm64.cc ('k') | src/ic/ic.h » ('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_IA32 5 #if V8_TARGET_ARCH_IA32
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
22 // storage. This function may fail to load a property even though it is
23 // in the dictionary, so code at miss_label must always call a backup
24 // property load that is complete. This function is safe to call if
25 // name is not internalized, and will jump to the miss_label in that
26 // case. The generated code assumes that the receiver has slow
27 // properties, 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 // Scratch registers:
38 //
39 // r0 - used for the index into the property dictionary
40 //
41 // r1 - used to hold the capacity of the property dictionary.
42 //
43 // result - holds the result on exit.
44
45 Label done;
46
47 // Probe the dictionary.
48 NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss_label, &done,
49 elements, name, r0, r1);
50
51 // If probing finds an entry in the dictionary, r0 contains the
52 // index into the dictionary. Check that the value is a normal
53 // property.
54 __ bind(&done);
55 const int kElementsStartOffset =
56 NameDictionary::kHeaderSize +
57 NameDictionary::kElementsStartIndex * kPointerSize;
58 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
59 __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag),
60 Immediate(PropertyDetails::TypeField::kMask << kSmiTagSize));
61 __ j(not_zero, miss_label);
62
63 // Get the value at the masked, scaled index.
64 const int kValueOffset = kElementsStartOffset + kPointerSize;
65 __ mov(result, Operand(elements, r0, times_4, 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 eventhough 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 internalized, and will jump to the miss_label in
74 // 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 r0, Register r1) {
79 // Register use:
80 //
81 // elements - holds the property dictionary on entry and is clobbered.
82 //
83 // name - holds the name of the property on entry and is unchanged.
84 //
85 // value - holds the value to store and is unchanged.
86 //
87 // r0 - used for index into the property dictionary and is clobbered.
88 //
89 // r1 - used to hold the capacity of the property dictionary and is clobbered.
90 Label done;
91
92
93 // Probe the dictionary.
94 NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss_label, &done,
95 elements, name, r0, r1);
96
97 // If probing finds an entry in the dictionary, r0 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 << kSmiTagSize;
109 __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag),
110 Immediate(kTypeAndReadOnlyMask));
111 __ j(not_zero, miss_label);
112
113 // Store the value at the masked, scaled index.
114 const int kValueOffset = kElementsStartOffset + kPointerSize;
115 __ lea(r0, Operand(elements, r0, times_4, kValueOffset - kHeapObjectTag));
116 __ mov(Operand(r0, 0), value);
117
118 // Update write barrier. Make sure not to clobber the value.
119 __ mov(r1, value);
120 __ RecordWrite(elements, r0, r1, kDontSaveFPRegs);
121 }
122
123 void LoadIC::GenerateNormal(MacroAssembler* masm) {
124 Register dictionary = eax;
125 DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister()));
126 DCHECK(!dictionary.is(LoadDescriptor::NameRegister()));
127
128 Label slow;
129
130 __ mov(dictionary, FieldOperand(LoadDescriptor::ReceiverRegister(),
131 JSObject::kPropertiesOffset));
132 GenerateDictionaryLoad(masm, &slow, dictionary,
133 LoadDescriptor::NameRegister(), edi, ebx, eax);
134 __ ret(0);
135
136 // Dictionary load failed, go slow (but don't miss).
137 __ bind(&slow);
138 GenerateRuntimeGetProperty(masm);
139 }
140
141 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
142 // Return address is on the stack.
143 Register receiver = LoadDescriptor::ReceiverRegister();
144 Register name = LoadDescriptor::NameRegister();
145 DCHECK(!ebx.is(receiver) && !ebx.is(name));
146
147 __ pop(ebx);
148 __ push(receiver);
149 __ push(name);
150 __ push(ebx);
151
152 // Do tail-call to runtime routine.
153 __ TailCallRuntime(Runtime::kGetProperty);
154 }
155
156 static void StoreIC_PushArgs(MacroAssembler* masm) { 21 static void StoreIC_PushArgs(MacroAssembler* masm) {
157 Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); 22 Register receiver = StoreWithVectorDescriptor::ReceiverRegister();
158 Register name = StoreWithVectorDescriptor::NameRegister(); 23 Register name = StoreWithVectorDescriptor::NameRegister();
159 24
160 STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3); 25 STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3);
161 // Current stack layout: 26 // Current stack layout:
162 // - esp[12] -- value 27 // - esp[12] -- value
163 // - esp[8] -- slot 28 // - esp[8] -- slot
164 // - esp[4] -- vector 29 // - esp[4] -- vector
165 // - esp[0] -- return address 30 // - esp[0] -- return address
166 31
167 Register return_address = StoreWithVectorDescriptor::SlotRegister(); 32 Register return_address = StoreWithVectorDescriptor::SlotRegister();
168 __ pop(return_address); 33 __ pop(return_address);
169 __ push(receiver); 34 __ push(receiver);
170 __ push(name); 35 __ push(name);
171 __ push(return_address); 36 __ push(return_address);
172 } 37 }
173 38
174
175 void StoreIC::GenerateMiss(MacroAssembler* masm) {
176 // Return address is on the stack.
177 StoreIC_PushArgs(masm);
178
179 // Perform tail call to the entry.
180 __ TailCallRuntime(Runtime::kStoreIC_Miss);
181 }
182
183
184 void StoreIC::GenerateNormal(MacroAssembler* masm) {
185 typedef StoreWithVectorDescriptor Descriptor;
186 Label restore_miss;
187 Register receiver = Descriptor::ReceiverRegister();
188 Register name = Descriptor::NameRegister();
189 Register value = Descriptor::ValueRegister();
190 // Since the slot and vector values are passed on the stack we can use
191 // respective registers as scratch registers.
192 Register scratch1 = Descriptor::VectorRegister();
193 Register scratch2 = Descriptor::SlotRegister();
194
195 __ LoadParameterFromStack<Descriptor>(value, Descriptor::kValue);
196
197 // A lot of registers are needed for storing to slow case objects.
198 // Push and restore receiver but rely on GenerateDictionaryStore preserving
199 // the value and name.
200 __ push(receiver);
201
202 Register dictionary = receiver;
203 __ mov(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset));
204 GenerateDictionaryStore(masm, &restore_miss, dictionary, name, value,
205 scratch1, scratch2);
206 __ Drop(1);
207 Counters* counters = masm->isolate()->counters();
208 __ IncrementCounter(counters->ic_store_normal_hit(), 1);
209 __ ret(Descriptor::kStackArgumentsCount * kPointerSize);
210
211 __ bind(&restore_miss);
212 __ pop(receiver);
213 __ IncrementCounter(counters->ic_store_normal_miss(), 1);
214 GenerateMiss(masm);
215 }
216
217
218 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { 39 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
219 // Return address is on the stack. 40 // Return address is on the stack.
220 StoreIC_PushArgs(masm); 41 StoreIC_PushArgs(masm);
221 42
222 // Do tail-call to runtime routine. 43 // Do tail-call to runtime routine.
223 __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss); 44 __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss);
224 } 45 }
225 46
226 void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) { 47 void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
227 // 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
300 Condition cc = 121 Condition cc =
301 (check == ENABLE_INLINED_SMI_CHECK) 122 (check == ENABLE_INLINED_SMI_CHECK)
302 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) 123 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero)
303 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); 124 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry);
304 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); 125 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
305 } 126 }
306 } // namespace internal 127 } // namespace internal
307 } // namespace v8 128 } // namespace v8
308 129
309 #endif // V8_TARGET_ARCH_IA32 130 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ic/arm64/ic-arm64.cc ('k') | src/ic/ic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698