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

Side by Side Diff: src/ic/arm/ic-arm.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/ia32/code-stubs-ia32.cc ('k') | src/ic/arm64/ic-arm64.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_ARM 5 #if V8_TARGET_ARCH_ARM
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 static void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss,
36 Register elements, Register name,
37 Register result, Register scratch1,
38 Register scratch2) {
39 // Main use of the scratch registers.
40 // scratch1: Used as temporary and to hold the capacity of the property
41 // dictionary.
42 // scratch2: Used as temporary.
43 Label done;
44
45 // Probe the dictionary.
46 NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements,
47 name, scratch1, scratch2);
48
49 // If probing finds an entry check that the value is a normal
50 // property.
51 __ bind(&done); // scratch2 == elements + 4 * index
52 const int kElementsStartOffset =
53 NameDictionary::kHeaderSize +
54 NameDictionary::kElementsStartIndex * kPointerSize;
55 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
56 __ ldr(scratch1, FieldMemOperand(scratch2, kDetailsOffset));
57 __ tst(scratch1, Operand(PropertyDetails::TypeField::kMask << kSmiTagSize));
58 __ b(ne, miss);
59
60 // Get the value at the masked, scaled index and return.
61 __ ldr(result,
62 FieldMemOperand(scratch2, kElementsStartOffset + 1 * kPointerSize));
63 }
64
65
66 // Helper function used from StoreIC::GenerateNormal.
67 //
68 // elements: Property dictionary. It is not clobbered if a jump to the miss
69 // label is done.
70 // name: Property name. It is not clobbered if a jump to the miss label is
71 // done
72 // value: The value to store.
73 // The two scratch registers need to be different from elements, name and
74 // result.
75 // The generated code assumes that the receiver has slow properties,
76 // is not a global object and does not have interceptors.
77 static void GenerateDictionaryStore(MacroAssembler* masm, Label* miss,
78 Register elements, Register name,
79 Register value, Register scratch1,
80 Register scratch2) {
81 // Main use of the scratch registers.
82 // scratch1: Used as temporary and to hold the capacity of the property
83 // dictionary.
84 // scratch2: Used as temporary.
85 Label done;
86
87 // Probe the dictionary.
88 NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements,
89 name, scratch1, scratch2);
90
91 // If probing finds an entry in the dictionary check that the value
92 // is a normal property that is not read only.
93 __ bind(&done); // scratch2 == elements + 4 * index
94 const int kElementsStartOffset =
95 NameDictionary::kHeaderSize +
96 NameDictionary::kElementsStartIndex * kPointerSize;
97 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
98 const int kTypeAndReadOnlyMask =
99 (PropertyDetails::TypeField::kMask |
100 PropertyDetails::AttributesField::encode(READ_ONLY))
101 << kSmiTagSize;
102 __ ldr(scratch1, FieldMemOperand(scratch2, kDetailsOffset));
103 __ tst(scratch1, Operand(kTypeAndReadOnlyMask));
104 __ b(ne, miss);
105
106 // Store the value at the masked, scaled index and return.
107 const int kValueOffset = kElementsStartOffset + kPointerSize;
108 __ add(scratch2, scratch2, Operand(kValueOffset - kHeapObjectTag));
109 __ str(value, MemOperand(scratch2));
110
111 // Update the write barrier. Make sure not to clobber the value.
112 __ mov(scratch1, value);
113 __ RecordWrite(elements, scratch2, scratch1, kLRHasNotBeenSaved,
114 kDontSaveFPRegs);
115 }
116
117 void LoadIC::GenerateNormal(MacroAssembler* masm) {
118 Register dictionary = r0;
119 DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister()));
120 DCHECK(!dictionary.is(LoadDescriptor::NameRegister()));
121
122 Label slow;
123
124 __ ldr(dictionary, FieldMemOperand(LoadDescriptor::ReceiverRegister(),
125 JSObject::kPropertiesOffset));
126 GenerateDictionaryLoad(masm, &slow, dictionary,
127 LoadDescriptor::NameRegister(), r0, r3, r4);
128 __ Ret();
129
130 // Dictionary load failed, go slow (but don't miss).
131 __ bind(&slow);
132 GenerateRuntimeGetProperty(masm);
133 }
134
135
136 // A register that isn't one of the parameters to the load ic.
137 static const Register LoadIC_TempRegister() { return r3; }
138
139 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
140 // The return address is in lr.
141
142 __ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister());
143 __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister());
144
145 // Do tail-call to runtime routine.
146 __ TailCallRuntime(Runtime::kGetProperty);
147 }
148
149 static void StoreIC_PushArgs(MacroAssembler* masm) { 22 static void StoreIC_PushArgs(MacroAssembler* masm) {
150 __ Push(StoreWithVectorDescriptor::ValueRegister(), 23 __ Push(StoreWithVectorDescriptor::ValueRegister(),
151 StoreWithVectorDescriptor::SlotRegister(), 24 StoreWithVectorDescriptor::SlotRegister(),
152 StoreWithVectorDescriptor::VectorRegister(), 25 StoreWithVectorDescriptor::VectorRegister(),
153 StoreWithVectorDescriptor::ReceiverRegister(), 26 StoreWithVectorDescriptor::ReceiverRegister(),
154 StoreWithVectorDescriptor::NameRegister()); 27 StoreWithVectorDescriptor::NameRegister());
155 } 28 }
156 29
157 30
158 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { 31 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
159 StoreIC_PushArgs(masm); 32 StoreIC_PushArgs(masm);
160 33
161 __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss); 34 __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss);
162 } 35 }
163 36
164 void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) { 37 void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
165 StoreIC_PushArgs(masm); 38 StoreIC_PushArgs(masm);
166 39
167 // 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
168 // 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.
169 __ TailCallRuntime(Runtime::kKeyedStoreIC_Slow); 42 __ TailCallRuntime(Runtime::kKeyedStoreIC_Slow);
170 } 43 }
171 44
172 void StoreIC::GenerateMiss(MacroAssembler* masm) {
173 StoreIC_PushArgs(masm);
174
175 // Perform tail call to the entry.
176 __ TailCallRuntime(Runtime::kStoreIC_Miss);
177 }
178
179
180 void StoreIC::GenerateNormal(MacroAssembler* masm) {
181 Label miss;
182 Register receiver = StoreDescriptor::ReceiverRegister();
183 Register name = StoreDescriptor::NameRegister();
184 Register value = StoreDescriptor::ValueRegister();
185 Register dictionary = r5;
186 DCHECK(receiver.is(r1));
187 DCHECK(name.is(r2));
188 DCHECK(value.is(r0));
189 DCHECK(StoreWithVectorDescriptor::VectorRegister().is(r3));
190 DCHECK(StoreWithVectorDescriptor::SlotRegister().is(r4));
191
192 __ ldr(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
193
194 GenerateDictionaryStore(masm, &miss, dictionary, name, value, r6, r9);
195 Counters* counters = masm->isolate()->counters();
196 __ IncrementCounter(counters->ic_store_normal_hit(), 1, r6, r9);
197 __ Ret();
198
199 __ bind(&miss);
200 __ IncrementCounter(counters->ic_store_normal_miss(), 1, r6, r9);
201 GenerateMiss(masm);
202 }
203
204
205 #undef __ 45 #undef __
206 46
207 47
208 Condition CompareIC::ComputeCondition(Token::Value op) { 48 Condition CompareIC::ComputeCondition(Token::Value op) {
209 switch (op) { 49 switch (op) {
210 case Token::EQ_STRICT: 50 case Token::EQ_STRICT:
211 case Token::EQ: 51 case Token::EQ:
212 return eq; 52 return eq;
213 case Token::LT: 53 case Token::LT:
214 return lt; 54 return lt;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 patcher.EmitCondition(ne); 135 patcher.EmitCondition(ne);
296 } else { 136 } else {
297 DCHECK(Assembler::GetCondition(branch_instr) == ne); 137 DCHECK(Assembler::GetCondition(branch_instr) == ne);
298 patcher.EmitCondition(eq); 138 patcher.EmitCondition(eq);
299 } 139 }
300 } 140 }
301 } // namespace internal 141 } // namespace internal
302 } // namespace v8 142 } // namespace v8
303 143
304 #endif // V8_TARGET_ARCH_ARM 144 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ic/arm64/ic-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698