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

Side by Side Diff: src/ic/arm64/ic-arm64.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/arm/ic-arm.cc ('k') | src/ic/ia32/ic-ia32.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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_ARM64 5 #if V8_TARGET_ARCH_ARM64
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 #define __ ACCESS_MASM(masm) 16 #define __ ACCESS_MASM(masm)
17 17
18 // Helper function used from LoadIC GenerateNormal.
19 //
20 // elements: Property dictionary. It is not clobbered if a jump to the miss
21 // label is done.
22 // name: Property name. It is not clobbered if a jump to the miss label is
23 // done
24 // result: Register for the result. It is only updated if a jump to the miss
25 // label is not done.
26 // The scratch registers need to be different from elements, name and result.
27 // The generated code assumes that the receiver has slow properties,
28 // is not a global object and does not have interceptors.
29 static void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss,
30 Register elements, Register name,
31 Register result, Register scratch1,
32 Register scratch2) {
33 DCHECK(!AreAliased(elements, name, scratch1, scratch2));
34 DCHECK(!AreAliased(result, scratch1, scratch2));
35
36 Label done;
37
38 // Probe the dictionary.
39 NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements,
40 name, scratch1, scratch2);
41
42 // If probing finds an entry check that the value is a normal property.
43 __ Bind(&done);
44
45 static const int kElementsStartOffset =
46 NameDictionary::kHeaderSize +
47 NameDictionary::kElementsStartIndex * kPointerSize;
48 static const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
49 __ Ldr(scratch1, FieldMemOperand(scratch2, kDetailsOffset));
50 __ Tst(scratch1, Smi::FromInt(PropertyDetails::TypeField::kMask));
51 __ B(ne, miss);
52
53 // Get the value at the masked, scaled index and return.
54 __ Ldr(result,
55 FieldMemOperand(scratch2, kElementsStartOffset + 1 * kPointerSize));
56 }
57
58
59 // Helper function used from StoreIC::GenerateNormal.
60 //
61 // elements: Property dictionary. It is not clobbered if a jump to the miss
62 // label is done.
63 // name: Property name. It is not clobbered if a jump to the miss label is
64 // done
65 // value: The value to store (never clobbered).
66 //
67 // The generated code assumes that the receiver has slow properties,
68 // is not a global object and does not have interceptors.
69 static void GenerateDictionaryStore(MacroAssembler* masm, Label* miss,
70 Register elements, Register name,
71 Register value, Register scratch1,
72 Register scratch2) {
73 DCHECK(!AreAliased(elements, name, value, scratch1, scratch2));
74
75 Label done;
76
77 // Probe the dictionary.
78 NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements,
79 name, scratch1, scratch2);
80
81 // If probing finds an entry in the dictionary check that the value
82 // is a normal property that is not read only.
83 __ Bind(&done);
84
85 static const int kElementsStartOffset =
86 NameDictionary::kHeaderSize +
87 NameDictionary::kElementsStartIndex * kPointerSize;
88 static const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
89 static const int kTypeAndReadOnlyMask =
90 PropertyDetails::TypeField::kMask |
91 PropertyDetails::AttributesField::encode(READ_ONLY);
92 __ Ldrsw(scratch1, UntagSmiFieldMemOperand(scratch2, kDetailsOffset));
93 __ Tst(scratch1, kTypeAndReadOnlyMask);
94 __ B(ne, miss);
95
96 // Store the value at the masked, scaled index and return.
97 static const int kValueOffset = kElementsStartOffset + kPointerSize;
98 __ Add(scratch2, scratch2, kValueOffset - kHeapObjectTag);
99 __ Str(value, MemOperand(scratch2));
100
101 // Update the write barrier. Make sure not to clobber the value.
102 __ Mov(scratch1, value);
103 __ RecordWrite(elements, scratch2, scratch1, kLRHasNotBeenSaved,
104 kDontSaveFPRegs);
105 }
106
107 void LoadIC::GenerateNormal(MacroAssembler* masm) {
108 Register dictionary = x0;
109 DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister()));
110 DCHECK(!dictionary.is(LoadDescriptor::NameRegister()));
111 Label slow;
112
113 __ Ldr(dictionary, FieldMemOperand(LoadDescriptor::ReceiverRegister(),
114 JSObject::kPropertiesOffset));
115 GenerateDictionaryLoad(masm, &slow, dictionary,
116 LoadDescriptor::NameRegister(), x0, x3, x4);
117 __ Ret();
118
119 // Dictionary load failed, go slow (but don't miss).
120 __ Bind(&slow);
121 GenerateRuntimeGetProperty(masm);
122 }
123
124 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
125 // The return address is in lr.
126 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
127
128 // Do tail-call to runtime routine.
129 __ TailCallRuntime(Runtime::kGetProperty);
130 }
131
132 static void StoreIC_PushArgs(MacroAssembler* masm) { 18 static void StoreIC_PushArgs(MacroAssembler* masm) {
133 __ Push(StoreWithVectorDescriptor::ValueRegister(), 19 __ Push(StoreWithVectorDescriptor::ValueRegister(),
134 StoreWithVectorDescriptor::SlotRegister(), 20 StoreWithVectorDescriptor::SlotRegister(),
135 StoreWithVectorDescriptor::VectorRegister(), 21 StoreWithVectorDescriptor::VectorRegister(),
136 StoreWithVectorDescriptor::ReceiverRegister(), 22 StoreWithVectorDescriptor::ReceiverRegister(),
137 StoreWithVectorDescriptor::NameRegister()); 23 StoreWithVectorDescriptor::NameRegister());
138 } 24 }
139 25
140 26
141 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { 27 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
142 ASM_LOCATION("KeyedStoreIC::GenerateMiss"); 28 ASM_LOCATION("KeyedStoreIC::GenerateMiss");
143 StoreIC_PushArgs(masm); 29 StoreIC_PushArgs(masm);
144 __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss); 30 __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss);
145 } 31 }
146 32
147 void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) { 33 void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
148 ASM_LOCATION("KeyedStoreIC::GenerateSlow"); 34 ASM_LOCATION("KeyedStoreIC::GenerateSlow");
149 StoreIC_PushArgs(masm); 35 StoreIC_PushArgs(masm);
150 36
151 // The slow case calls into the runtime to complete the store without causing 37 // The slow case calls into the runtime to complete the store without causing
152 // an IC miss that would otherwise cause a transition to the generic stub. 38 // an IC miss that would otherwise cause a transition to the generic stub.
153 __ TailCallRuntime(Runtime::kKeyedStoreIC_Slow); 39 __ TailCallRuntime(Runtime::kKeyedStoreIC_Slow);
154 } 40 }
155 41
156 void StoreIC::GenerateMiss(MacroAssembler* masm) {
157 StoreIC_PushArgs(masm);
158
159 // Tail call to the entry.
160 __ TailCallRuntime(Runtime::kStoreIC_Miss);
161 }
162
163
164 void StoreIC::GenerateNormal(MacroAssembler* masm) {
165 Label miss;
166 Register value = StoreDescriptor::ValueRegister();
167 Register receiver = StoreDescriptor::ReceiverRegister();
168 Register name = StoreDescriptor::NameRegister();
169 Register dictionary = x5;
170 DCHECK(!AreAliased(value, receiver, name,
171 StoreWithVectorDescriptor::SlotRegister(),
172 StoreWithVectorDescriptor::VectorRegister(), x5, x6, x7));
173
174 __ Ldr(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
175
176 GenerateDictionaryStore(masm, &miss, dictionary, name, value, x6, x7);
177 Counters* counters = masm->isolate()->counters();
178 __ IncrementCounter(counters->ic_store_normal_hit(), 1, x6, x7);
179 __ Ret();
180
181 // Cache miss: Jump to runtime.
182 __ Bind(&miss);
183 __ IncrementCounter(counters->ic_store_normal_miss(), 1, x6, x7);
184 GenerateMiss(masm);
185 }
186
187
188 Condition CompareIC::ComputeCondition(Token::Value op) { 42 Condition CompareIC::ComputeCondition(Token::Value op) {
189 switch (op) { 43 switch (op) {
190 case Token::EQ_STRICT: 44 case Token::EQ_STRICT:
191 case Token::EQ: 45 case Token::EQ:
192 return eq; 46 return eq;
193 case Token::LT: 47 case Token::LT:
194 return lt; 48 return lt;
195 case Token::GT: 49 case Token::GT:
196 return gt; 50 return gt;
197 case Token::LTE: 51 case Token::LTE:
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 } else { 123 } else {
270 DCHECK(to_patch->Mask(TestBranchMask) == TBNZ); 124 DCHECK(to_patch->Mask(TestBranchMask) == TBNZ);
271 // This is JumpIfSmi(smi_reg, branch_imm). 125 // This is JumpIfSmi(smi_reg, branch_imm).
272 patcher.tbz(smi_reg, 0, branch_imm); 126 patcher.tbz(smi_reg, 0, branch_imm);
273 } 127 }
274 } 128 }
275 } // namespace internal 129 } // namespace internal
276 } // namespace v8 130 } // namespace v8
277 131
278 #endif // V8_TARGET_ARCH_ARM64 132 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/ic/arm/ic-arm.cc ('k') | src/ic/ia32/ic-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698