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

Side by Side Diff: src/ic/mips/ic-mips.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/ic.h ('k') | src/ic/mips64/ic-mips64.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_MIPS 5 #if V8_TARGET_ARCH_MIPS
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 // ---------------------------------------------------------------------------- 16 // ----------------------------------------------------------------------------
17 // Static IC stub generators. 17 // Static IC stub generators.
18 // 18 //
19 19
20 #define __ ACCESS_MASM(masm) 20 #define __ ACCESS_MASM(masm)
21 21
22 // Helper function used from LoadIC GenerateNormal.
23 //
24 // elements: Property dictionary. It is not clobbered if a jump to the miss
25 // label is done.
26 // name: Property name. It is not clobbered if a jump to the miss label is
27 // done
28 // result: Register for the result. It is only updated if a jump to the miss
29 // label is not done. Can be the same as elements or name clobbering
30 // one of these in the case of not jumping to the miss label.
31 // The two scratch registers need to be different from elements, name and
32 // result.
33 // The generated code assumes that the receiver has slow properties,
34 // is not a global object and does not have interceptors.
35 // The address returned from GenerateStringDictionaryProbes() in scratch2
36 // is used.
37 static void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss,
38 Register elements, Register name,
39 Register result, Register scratch1,
40 Register scratch2) {
41 // Main use of the scratch registers.
42 // scratch1: Used as temporary and to hold the capacity of the property
43 // dictionary.
44 // scratch2: Used as temporary.
45 Label done;
46
47 // Probe the dictionary.
48 NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements,
49 name, scratch1, scratch2);
50
51 // If probing finds an entry check that the value is a normal
52 // property.
53 __ bind(&done); // scratch2 == elements + 4 * index.
54 const int kElementsStartOffset =
55 NameDictionary::kHeaderSize +
56 NameDictionary::kElementsStartIndex * kPointerSize;
57 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
58 __ lw(scratch1, FieldMemOperand(scratch2, kDetailsOffset));
59 __ And(at, scratch1,
60 Operand(PropertyDetails::TypeField::kMask << kSmiTagSize));
61 __ Branch(miss, ne, at, Operand(zero_reg));
62
63 // Get the value at the masked, scaled index and return.
64 __ lw(result,
65 FieldMemOperand(scratch2, kElementsStartOffset + 1 * kPointerSize));
66 }
67
68
69 // Helper function used from StoreIC::GenerateNormal.
70 //
71 // elements: Property dictionary. It is not clobbered if a jump to the miss
72 // label is done.
73 // name: Property name. It is not clobbered if a jump to the miss label is
74 // done
75 // value: The value to store.
76 // The two scratch registers need to be different from elements, name and
77 // result.
78 // The generated code assumes that the receiver has slow properties,
79 // is not a global object and does not have interceptors.
80 // The address returned from GenerateStringDictionaryProbes() in scratch2
81 // is used.
82 static void GenerateDictionaryStore(MacroAssembler* masm, Label* miss,
83 Register elements, Register name,
84 Register value, Register scratch1,
85 Register scratch2) {
86 // Main use of the scratch registers.
87 // scratch1: Used as temporary and to hold the capacity of the property
88 // dictionary.
89 // scratch2: Used as temporary.
90 Label done;
91
92 // Probe the dictionary.
93 NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements,
94 name, scratch1, scratch2);
95
96 // If probing finds an entry in the dictionary check that the value
97 // is a normal property that is not read only.
98 __ bind(&done); // scratch2 == elements + 4 * index.
99 const int kElementsStartOffset =
100 NameDictionary::kHeaderSize +
101 NameDictionary::kElementsStartIndex * kPointerSize;
102 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
103 const int kTypeAndReadOnlyMask =
104 (PropertyDetails::TypeField::kMask |
105 PropertyDetails::AttributesField::encode(READ_ONLY))
106 << kSmiTagSize;
107 __ lw(scratch1, FieldMemOperand(scratch2, kDetailsOffset));
108 __ And(at, scratch1, Operand(kTypeAndReadOnlyMask));
109 __ Branch(miss, ne, at, Operand(zero_reg));
110
111 // Store the value at the masked, scaled index and return.
112 const int kValueOffset = kElementsStartOffset + kPointerSize;
113 __ Addu(scratch2, scratch2, Operand(kValueOffset - kHeapObjectTag));
114 __ sw(value, MemOperand(scratch2));
115
116 // Update the write barrier. Make sure not to clobber the value.
117 __ mov(scratch1, value);
118 __ RecordWrite(elements, scratch2, scratch1, kRAHasNotBeenSaved,
119 kDontSaveFPRegs);
120 }
121
122 void LoadIC::GenerateNormal(MacroAssembler* masm) {
123 Register dictionary = a0;
124 DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister()));
125 DCHECK(!dictionary.is(LoadDescriptor::NameRegister()));
126
127 Label slow;
128
129 __ lw(dictionary, FieldMemOperand(LoadDescriptor::ReceiverRegister(),
130 JSObject::kPropertiesOffset));
131 GenerateDictionaryLoad(masm, &slow, dictionary,
132 LoadDescriptor::NameRegister(), v0, a3, t0);
133 __ Ret();
134
135 // Dictionary load failed, go slow (but don't miss).
136 __ bind(&slow);
137 GenerateRuntimeGetProperty(masm);
138 }
139
140
141 // A register that isn't one of the parameters to the load ic.
142 static const Register LoadIC_TempRegister() { return a3; }
143
144 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
145 // The return address is in ra.
146
147 __ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister());
148 __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister());
149
150 // Do tail-call to runtime routine.
151 __ TailCallRuntime(Runtime::kGetProperty);
152 }
153
154 static void StoreIC_PushArgs(MacroAssembler* masm) { 22 static void StoreIC_PushArgs(MacroAssembler* masm) {
155 __ Push(StoreWithVectorDescriptor::ValueRegister(), 23 __ Push(StoreWithVectorDescriptor::ValueRegister(),
156 StoreWithVectorDescriptor::SlotRegister(), 24 StoreWithVectorDescriptor::SlotRegister(),
157 StoreWithVectorDescriptor::VectorRegister(), 25 StoreWithVectorDescriptor::VectorRegister(),
158 StoreWithVectorDescriptor::ReceiverRegister(), 26 StoreWithVectorDescriptor::ReceiverRegister(),
159 StoreWithVectorDescriptor::NameRegister()); 27 StoreWithVectorDescriptor::NameRegister());
160 } 28 }
161 29
162 30
163 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { 31 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
164 StoreIC_PushArgs(masm); 32 StoreIC_PushArgs(masm);
165 33
166 __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss); 34 __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss);
167 } 35 }
168 36
169 void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) { 37 void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
170 StoreIC_PushArgs(masm); 38 StoreIC_PushArgs(masm);
171 39
172 // The slow case calls into the runtime to complete the store without causing 40 // The slow case calls into the runtime to complete the store without causing
173 // an IC miss that would otherwise cause a transition to the generic stub. 41 // an IC miss that would otherwise cause a transition to the generic stub.
174 __ TailCallRuntime(Runtime::kKeyedStoreIC_Slow); 42 __ TailCallRuntime(Runtime::kKeyedStoreIC_Slow);
175 } 43 }
176 44
177 void StoreIC::GenerateMiss(MacroAssembler* masm) {
178 StoreIC_PushArgs(masm);
179
180 // Perform tail call to the entry.
181 __ TailCallRuntime(Runtime::kStoreIC_Miss);
182 }
183
184
185 void StoreIC::GenerateNormal(MacroAssembler* masm) {
186 Label miss;
187 Register receiver = StoreDescriptor::ReceiverRegister();
188 Register name = StoreDescriptor::NameRegister();
189 Register value = StoreDescriptor::ValueRegister();
190 Register dictionary = t1;
191 DCHECK(receiver.is(a1));
192 DCHECK(name.is(a2));
193 DCHECK(value.is(a0));
194 DCHECK(StoreWithVectorDescriptor::VectorRegister().is(a3));
195 DCHECK(StoreWithVectorDescriptor::SlotRegister().is(t0));
196
197 __ lw(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
198
199 GenerateDictionaryStore(masm, &miss, dictionary, name, value, t2, t5);
200 Counters* counters = masm->isolate()->counters();
201 __ IncrementCounter(counters->ic_store_normal_hit(), 1, t2, t5);
202 __ Ret(USE_DELAY_SLOT);
203 __ Move(v0, value); // Ensure the stub returns correct value.
204
205 __ bind(&miss);
206 __ IncrementCounter(counters->ic_store_normal_miss(), 1, t2, t5);
207 GenerateMiss(masm);
208 }
209
210
211 #undef __ 45 #undef __
212 46
213 47
214 Condition CompareIC::ComputeCondition(Token::Value op) { 48 Condition CompareIC::ComputeCondition(Token::Value op) {
215 switch (op) { 49 switch (op) {
216 case Token::EQ_STRICT: 50 case Token::EQ_STRICT:
217 case Token::EQ: 51 case Token::EQ:
218 return eq; 52 return eq;
219 case Token::LT: 53 case Token::LT:
220 return lt; 54 return lt;
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 break; 165 break;
332 default: 166 default:
333 UNIMPLEMENTED(); 167 UNIMPLEMENTED();
334 } 168 }
335 patcher.ChangeBranchCondition(branch_instr, opcode); 169 patcher.ChangeBranchCondition(branch_instr, opcode);
336 } 170 }
337 } // namespace internal 171 } // namespace internal
338 } // namespace v8 172 } // namespace v8
339 173
340 #endif // V8_TARGET_ARCH_MIPS 174 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/ic/ic.h ('k') | src/ic/mips64/ic-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698