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

Side by Side Diff: src/ic/s390/handler-compiler-s390.cc

Issue 1743263003: S390: Initial impl of debug and ic (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix s390 files under correct target in BUILD.gn Created 4 years, 9 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/access-compiler-s390.cc ('k') | src/ic/s390/ic-compiler-s390.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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2015 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_PPC 5 #if V8_TARGET_ARCH_S390
6 6
7 #include "src/ic/handler-compiler.h" 7 #include "src/ic/handler-compiler.h"
8 8
9 #include "src/field-type.h" 9 #include "src/field-type.h"
10 #include "src/ic/call-optimization.h" 10 #include "src/ic/call-optimization.h"
11 #include "src/ic/ic.h" 11 #include "src/ic/ic.h"
12 #include "src/isolate-inl.h" 12 #include "src/isolate-inl.h"
13 13
14 namespace v8 { 14 namespace v8 {
15 namespace internal { 15 namespace internal {
16 16
17 #define __ ACCESS_MASM(masm) 17 #define __ ACCESS_MASM(masm)
18 18
19
20 void NamedLoadHandlerCompiler::GenerateLoadViaGetter( 19 void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
21 MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder, 20 MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
22 int accessor_index, int expected_arguments, Register scratch) { 21 int accessor_index, int expected_arguments, Register scratch) {
23 // ----------- S t a t e ------------- 22 // ----------- S t a t e -------------
24 // -- r3 : receiver 23 // -- r2 : receiver
25 // -- r5 : name 24 // -- r4 : name
26 // -- lr : return address 25 // -- lr : return address
27 // ----------------------------------- 26 // -----------------------------------
28 { 27 {
29 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); 28 FrameScope scope(masm, StackFrame::INTERNAL);
30 29
31 if (accessor_index >= 0) { 30 if (accessor_index >= 0) {
32 DCHECK(!holder.is(scratch)); 31 DCHECK(!holder.is(scratch));
33 DCHECK(!receiver.is(scratch)); 32 DCHECK(!receiver.is(scratch));
34 // Call the JavaScript getter with the receiver on the stack. 33 // Call the JavaScript getter with the receiver on the stack.
35 if (map->IsJSGlobalObjectMap()) { 34 if (map->IsJSGlobalObjectMap()) {
36 // Swap in the global receiver. 35 // Swap in the global receiver.
37 __ LoadP(scratch, 36 __ LoadP(scratch,
38 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); 37 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
39 receiver = scratch; 38 receiver = scratch;
40 } 39 }
41 __ push(receiver); 40 __ Push(receiver);
42 ParameterCount actual(0); 41 ParameterCount actual(0);
43 ParameterCount expected(expected_arguments); 42 ParameterCount expected(expected_arguments);
44 __ LoadAccessor(r4, holder, accessor_index, ACCESSOR_GETTER); 43 __ LoadAccessor(r3, holder, accessor_index, ACCESSOR_GETTER);
45 __ InvokeFunction(r4, expected, actual, CALL_FUNCTION, 44 __ InvokeFunction(r3, expected, actual, CALL_FUNCTION,
46 CheckDebugStepCallWrapper()); 45 CheckDebugStepCallWrapper());
47 } else { 46 } else {
48 // If we generate a global code snippet for deoptimization only, remember 47 // If we generate a global code snippet for deoptimization only, remember
49 // the place to continue after deoptimization. 48 // the place to continue after deoptimization.
50 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset()); 49 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
51 } 50 }
52 51
53 // Restore context register. 52 // Restore context register.
54 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 53 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
55 } 54 }
56 __ Ret(); 55 __ Ret();
57 } 56 }
58 57
59
60 void NamedStoreHandlerCompiler::GenerateStoreViaSetter( 58 void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
61 MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder, 59 MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
62 int accessor_index, int expected_arguments, Register scratch) { 60 int accessor_index, int expected_arguments, Register scratch) {
63 // ----------- S t a t e ------------- 61 // ----------- S t a t e -------------
64 // -- lr : return address 62 // -- lr : return address
65 // ----------------------------------- 63 // -----------------------------------
66 { 64 {
67 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); 65 FrameScope scope(masm, StackFrame::INTERNAL);
68 66
69 // Save value register, so we can restore it later. 67 // Save value register, so we can restore it later.
70 __ push(value()); 68 __ Push(value());
71 69
72 if (accessor_index >= 0) { 70 if (accessor_index >= 0) {
73 DCHECK(!holder.is(scratch)); 71 DCHECK(!holder.is(scratch));
74 DCHECK(!receiver.is(scratch)); 72 DCHECK(!receiver.is(scratch));
75 DCHECK(!value().is(scratch)); 73 DCHECK(!value().is(scratch));
76 // Call the JavaScript setter with receiver and value on the stack. 74 // Call the JavaScript setter with receiver and value on the stack.
77 if (map->IsJSGlobalObjectMap()) { 75 if (map->IsJSGlobalObjectMap()) {
78 // Swap in the global receiver. 76 // Swap in the global receiver.
79 __ LoadP(scratch, 77 __ LoadP(scratch,
80 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); 78 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
81 receiver = scratch; 79 receiver = scratch;
82 } 80 }
83 __ Push(receiver, value()); 81 __ Push(receiver, value());
84 ParameterCount actual(1); 82 ParameterCount actual(1);
85 ParameterCount expected(expected_arguments); 83 ParameterCount expected(expected_arguments);
86 __ LoadAccessor(r4, holder, accessor_index, ACCESSOR_SETTER); 84 __ LoadAccessor(r3, holder, accessor_index, ACCESSOR_SETTER);
87 __ InvokeFunction(r4, expected, actual, CALL_FUNCTION, 85 __ InvokeFunction(r3, expected, actual, CALL_FUNCTION,
88 CheckDebugStepCallWrapper()); 86 CheckDebugStepCallWrapper());
89 } else { 87 } else {
90 // If we generate a global code snippet for deoptimization only, remember 88 // If we generate a global code snippet for deoptimization only, remember
91 // the place to continue after deoptimization. 89 // the place to continue after deoptimization.
92 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); 90 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
93 } 91 }
94 92
95 // We have to return the passed value, not the return value of the setter. 93 // We have to return the passed value, not the return value of the setter.
96 __ pop(r3); 94 __ Pop(r2);
97 95
98 // Restore context register. 96 // Restore context register.
99 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 97 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
100 } 98 }
101 __ Ret(); 99 __ Ret();
102 } 100 }
103 101
104
105 void PropertyHandlerCompiler::PushVectorAndSlot(Register vector, 102 void PropertyHandlerCompiler::PushVectorAndSlot(Register vector,
106 Register slot) { 103 Register slot) {
107 MacroAssembler* masm = this->masm(); 104 MacroAssembler* masm = this->masm();
108 __ Push(vector, slot); 105 __ Push(vector, slot);
109 } 106 }
110 107
111
112 void PropertyHandlerCompiler::PopVectorAndSlot(Register vector, Register slot) { 108 void PropertyHandlerCompiler::PopVectorAndSlot(Register vector, Register slot) {
113 MacroAssembler* masm = this->masm(); 109 MacroAssembler* masm = this->masm();
114 __ Pop(vector, slot); 110 __ Pop(vector, slot);
115 } 111 }
116 112
117
118 void PropertyHandlerCompiler::DiscardVectorAndSlot() { 113 void PropertyHandlerCompiler::DiscardVectorAndSlot() {
119 MacroAssembler* masm = this->masm(); 114 MacroAssembler* masm = this->masm();
120 // Remove vector and slot. 115 // Remove vector and slot.
121 __ addi(sp, sp, Operand(2 * kPointerSize)); 116 __ la(sp, MemOperand(sp, 2 * kPointerSize));
122 } 117 }
123 118
124
125 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( 119 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
126 MacroAssembler* masm, Label* miss_label, Register receiver, 120 MacroAssembler* masm, Label* miss_label, Register receiver,
127 Handle<Name> name, Register scratch0, Register scratch1) { 121 Handle<Name> name, Register scratch0, Register scratch1) {
128 DCHECK(name->IsUniqueName()); 122 DCHECK(name->IsUniqueName());
129 DCHECK(!receiver.is(scratch0)); 123 DCHECK(!receiver.is(scratch0));
130 Counters* counters = masm->isolate()->counters(); 124 Counters* counters = masm->isolate()->counters();
131 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); 125 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
132 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 126 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
133 127
134 Label done; 128 Label done;
135 129
136 const int kInterceptorOrAccessCheckNeededMask = 130 const int kInterceptorOrAccessCheckNeededMask =
137 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); 131 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
138 132
139 // Bail out if the receiver has a named interceptor or requires access checks. 133 // Bail out if the receiver has a named interceptor or requires access checks.
140 Register map = scratch1; 134 Register map = scratch1;
141 __ LoadP(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); 135 __ LoadP(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
142 __ lbz(scratch0, FieldMemOperand(map, Map::kBitFieldOffset)); 136 __ LoadlB(scratch0, FieldMemOperand(map, Map::kBitFieldOffset));
143 __ andi(r0, scratch0, Operand(kInterceptorOrAccessCheckNeededMask)); 137 __ AndP(r0, scratch0, Operand(kInterceptorOrAccessCheckNeededMask));
144 __ bne(miss_label, cr0); 138 __ bne(miss_label);
145 139
146 // Check that receiver is a JSObject. 140 // Check that receiver is a JSObject.
147 __ lbz(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset)); 141 // TODO(joransiu): Merge into SI compare
148 __ cmpi(scratch0, Operand(FIRST_JS_RECEIVER_TYPE)); 142 __ LoadlB(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset));
143 __ CmpP(scratch0, Operand(FIRST_JS_RECEIVER_TYPE));
149 __ blt(miss_label); 144 __ blt(miss_label);
150 145
151 // Load properties array. 146 // Load properties array.
152 Register properties = scratch0; 147 Register properties = scratch0;
153 __ LoadP(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 148 __ LoadP(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
154 // Check that the properties array is a dictionary. 149 // Check that the properties array is a dictionary.
155 __ LoadP(map, FieldMemOperand(properties, HeapObject::kMapOffset)); 150 __ LoadP(map, FieldMemOperand(properties, HeapObject::kMapOffset));
156 Register tmp = properties; 151 __ CompareRoot(map, Heap::kHashTableMapRootIndex);
157 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex);
158 __ cmp(map, tmp);
159 __ bne(miss_label); 152 __ bne(miss_label);
160 153
161 // Restore the temporarily used register. 154 // Restore the temporarily used register.
162 __ LoadP(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 155 __ LoadP(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
163 156
164
165 NameDictionaryLookupStub::GenerateNegativeLookup( 157 NameDictionaryLookupStub::GenerateNegativeLookup(
166 masm, miss_label, &done, receiver, properties, name, scratch1); 158 masm, miss_label, &done, receiver, properties, name, scratch1);
167 __ bind(&done); 159 __ bind(&done);
168 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 160 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
169 } 161 }
170 162
171
172 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype( 163 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
173 MacroAssembler* masm, int index, Register result, Label* miss) { 164 MacroAssembler* masm, int index, Register result, Label* miss) {
174 __ LoadNativeContextSlot(index, result); 165 __ LoadNativeContextSlot(index, result);
175 // Load its initial map. The global functions all have initial maps. 166 // Load its initial map. The global functions all have initial maps.
176 __ LoadP(result, 167 __ LoadP(result,
177 FieldMemOperand(result, JSFunction::kPrototypeOrInitialMapOffset)); 168 FieldMemOperand(result, JSFunction::kPrototypeOrInitialMapOffset));
178 // Load the prototype from the initial map. 169 // Load the prototype from the initial map.
179 __ LoadP(result, FieldMemOperand(result, Map::kPrototypeOffset)); 170 __ LoadP(result, FieldMemOperand(result, Map::kPrototypeOffset));
180 } 171 }
181 172
182
183 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype( 173 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
184 MacroAssembler* masm, Register receiver, Register scratch1, 174 MacroAssembler* masm, Register receiver, Register scratch1,
185 Register scratch2, Label* miss_label) { 175 Register scratch2, Label* miss_label) {
186 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); 176 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
187 __ mr(r3, scratch1); 177 __ LoadRR(r2, scratch1);
188 __ Ret(); 178 __ Ret();
189 } 179 }
190 180
191
192 // Generate code to check that a global property cell is empty. Create 181 // Generate code to check that a global property cell is empty. Create
193 // the property cell at compilation time if no cell exists for the 182 // the property cell at compilation time if no cell exists for the
194 // property. 183 // property.
195 void PropertyHandlerCompiler::GenerateCheckPropertyCell( 184 void PropertyHandlerCompiler::GenerateCheckPropertyCell(
196 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name, 185 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
197 Register scratch, Label* miss) { 186 Register scratch, Label* miss) {
198 Handle<PropertyCell> cell = JSGlobalObject::EnsurePropertyCell(global, name); 187 Handle<PropertyCell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
199 DCHECK(cell->value()->IsTheHole()); 188 DCHECK(cell->value()->IsTheHole());
200 Handle<WeakCell> weak_cell = masm->isolate()->factory()->NewWeakCell(cell); 189 Handle<WeakCell> weak_cell = masm->isolate()->factory()->NewWeakCell(cell);
201 __ LoadWeakValue(scratch, weak_cell, miss); 190 __ LoadWeakValue(scratch, weak_cell, miss);
202 __ LoadP(scratch, FieldMemOperand(scratch, PropertyCell::kValueOffset)); 191 __ LoadP(scratch, FieldMemOperand(scratch, PropertyCell::kValueOffset));
203 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 192 __ CompareRoot(scratch, Heap::kTheHoleValueRootIndex);
204 __ cmp(scratch, ip);
205 __ bne(miss); 193 __ bne(miss);
206 } 194 }
207 195
208
209 static void PushInterceptorArguments(MacroAssembler* masm, Register receiver, 196 static void PushInterceptorArguments(MacroAssembler* masm, Register receiver,
210 Register holder, Register name, 197 Register holder, Register name,
211 Handle<JSObject> holder_obj) { 198 Handle<JSObject> holder_obj) {
212 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0); 199 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
213 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 1); 200 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 1);
214 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 2); 201 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 2);
215 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 3); 202 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 3);
216 __ push(name); 203 __ Push(name);
217 __ push(receiver); 204 __ Push(receiver);
218 __ push(holder); 205 __ Push(holder);
219 } 206 }
220 207
221
222 static void CompileCallLoadPropertyWithInterceptor( 208 static void CompileCallLoadPropertyWithInterceptor(
223 MacroAssembler* masm, Register receiver, Register holder, Register name, 209 MacroAssembler* masm, Register receiver, Register holder, Register name,
224 Handle<JSObject> holder_obj, Runtime::FunctionId id) { 210 Handle<JSObject> holder_obj, Runtime::FunctionId id) {
225 DCHECK(NamedLoadHandlerCompiler::kInterceptorArgsLength == 211 DCHECK(NamedLoadHandlerCompiler::kInterceptorArgsLength ==
226 Runtime::FunctionForId(id)->nargs); 212 Runtime::FunctionForId(id)->nargs);
227 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 213 PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
228 __ CallRuntime(id); 214 __ CallRuntime(id);
229 } 215 }
230 216
231
232 // Generate call to api function. 217 // Generate call to api function.
233 void PropertyHandlerCompiler::GenerateApiAccessorCall( 218 void PropertyHandlerCompiler::GenerateApiAccessorCall(
234 MacroAssembler* masm, const CallOptimization& optimization, 219 MacroAssembler* masm, const CallOptimization& optimization,
235 Handle<Map> receiver_map, Register receiver, Register scratch_in, 220 Handle<Map> receiver_map, Register receiver, Register scratch_in,
236 bool is_store, Register store_parameter, Register accessor_holder, 221 bool is_store, Register store_parameter, Register accessor_holder,
237 int accessor_index) { 222 int accessor_index) {
238 DCHECK(!accessor_holder.is(scratch_in)); 223 DCHECK(!accessor_holder.is(scratch_in));
239 DCHECK(!receiver.is(scratch_in)); 224 DCHECK(!receiver.is(scratch_in));
240 __ push(receiver); 225 __ Push(receiver);
241 // Write the arguments to stack frame. 226 // Write the arguments to stack frame.
242 if (is_store) { 227 if (is_store) {
243 DCHECK(!receiver.is(store_parameter)); 228 DCHECK(!receiver.is(store_parameter));
244 DCHECK(!scratch_in.is(store_parameter)); 229 DCHECK(!scratch_in.is(store_parameter));
245 __ push(store_parameter); 230 __ Push(store_parameter);
246 } 231 }
247 DCHECK(optimization.is_simple_api_call()); 232 DCHECK(optimization.is_simple_api_call());
248 233
249 // Abi for CallApiFunctionStub. 234 // Abi for CallApiFunctionStub.
250 Register callee = r3; 235 Register callee = r2;
251 Register data = r7; 236 Register data = r6;
252 Register holder = r5; 237 Register holder = r4;
253 Register api_function_address = r4; 238 Register api_function_address = r3;
254 239
255 // Put callee in place. 240 // Put callee in place.
256 __ LoadAccessor(callee, accessor_holder, accessor_index, 241 __ LoadAccessor(callee, accessor_holder, accessor_index,
257 is_store ? ACCESSOR_SETTER : ACCESSOR_GETTER); 242 is_store ? ACCESSOR_SETTER : ACCESSOR_GETTER);
258 243
259 // Put holder in place. 244 // Put holder in place.
260 CallOptimization::HolderLookup holder_lookup; 245 CallOptimization::HolderLookup holder_lookup;
261 int holder_depth = 0; 246 int holder_depth = 0;
262 optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup, 247 optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup,
263 &holder_depth); 248 &holder_depth);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 ExternalReference::Type type = ExternalReference::DIRECT_API_CALL; 298 ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
314 ExternalReference ref = ExternalReference(&fun, type, masm->isolate()); 299 ExternalReference ref = ExternalReference(&fun, type, masm->isolate());
315 __ mov(api_function_address, Operand(ref)); 300 __ mov(api_function_address, Operand(ref));
316 301
317 // Jump to stub. 302 // Jump to stub.
318 CallApiAccessorStub stub(isolate, is_store, call_data_undefined, 303 CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
319 !optimization.is_constant_call()); 304 !optimization.is_constant_call());
320 __ TailCallStub(&stub); 305 __ TailCallStub(&stub);
321 } 306 }
322 307
323
324 static void StoreIC_PushArgs(MacroAssembler* masm) { 308 static void StoreIC_PushArgs(MacroAssembler* masm) {
325 __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(), 309 __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(),
326 StoreDescriptor::ValueRegister(), 310 StoreDescriptor::ValueRegister(),
327 VectorStoreICDescriptor::SlotRegister(), 311 VectorStoreICDescriptor::SlotRegister(),
328 VectorStoreICDescriptor::VectorRegister()); 312 VectorStoreICDescriptor::VectorRegister());
329 } 313 }
330 314
331
332 void NamedStoreHandlerCompiler::GenerateSlow(MacroAssembler* masm) { 315 void NamedStoreHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
333 StoreIC_PushArgs(masm); 316 StoreIC_PushArgs(masm);
334 317
335 // The slow case calls into the runtime to complete the store without causing 318 // The slow case calls into the runtime to complete the store without causing
336 // an IC miss that would otherwise cause a transition to the generic stub. 319 // an IC miss that would otherwise cause a transition to the generic stub.
337 __ TailCallRuntime(Runtime::kStoreIC_Slow); 320 __ TailCallRuntime(Runtime::kStoreIC_Slow);
338 } 321 }
339 322
340
341 void ElementHandlerCompiler::GenerateStoreSlow(MacroAssembler* masm) { 323 void ElementHandlerCompiler::GenerateStoreSlow(MacroAssembler* masm) {
342 StoreIC_PushArgs(masm); 324 StoreIC_PushArgs(masm);
343 325
344 // The slow case calls into the runtime to complete the store without causing 326 // The slow case calls into the runtime to complete the store without causing
345 // an IC miss that would otherwise cause a transition to the generic stub. 327 // an IC miss that would otherwise cause a transition to the generic stub.
346 __ TailCallRuntime(Runtime::kKeyedStoreIC_Slow); 328 __ TailCallRuntime(Runtime::kKeyedStoreIC_Slow);
347 } 329 }
348 330
349
350 #undef __ 331 #undef __
351 #define __ ACCESS_MASM(masm()) 332 #define __ ACCESS_MASM(masm())
352 333
353
354 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, 334 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
355 Handle<Name> name) { 335 Handle<Name> name) {
356 if (!label->is_unused()) { 336 if (!label->is_unused()) {
357 __ bind(label); 337 __ bind(label);
358 __ mov(this->name(), Operand(name)); 338 __ mov(this->name(), Operand(name));
359 } 339 }
360 } 340 }
361 341
362
363 void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) { 342 void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) {
364 __ mov(this->name(), Operand(name)); 343 __ mov(this->name(), Operand(name));
365 } 344 }
366 345
367
368 void NamedStoreHandlerCompiler::RearrangeVectorAndSlot( 346 void NamedStoreHandlerCompiler::RearrangeVectorAndSlot(
369 Register current_map, Register destination_map) { 347 Register current_map, Register destination_map) {
370 DCHECK(false); // Not implemented. 348 DCHECK(false); // Not implemented.
371 } 349 }
372 350
373
374 void NamedStoreHandlerCompiler::GenerateRestoreMap(Handle<Map> transition, 351 void NamedStoreHandlerCompiler::GenerateRestoreMap(Handle<Map> transition,
375 Register map_reg, 352 Register map_reg,
376 Register scratch, 353 Register scratch,
377 Label* miss) { 354 Label* miss) {
378 Handle<WeakCell> cell = Map::WeakCellForMap(transition); 355 Handle<WeakCell> cell = Map::WeakCellForMap(transition);
379 DCHECK(!map_reg.is(scratch)); 356 DCHECK(!map_reg.is(scratch));
380 __ LoadWeakValue(map_reg, cell, miss); 357 __ LoadWeakValue(map_reg, cell, miss);
381 if (transition->CanBeDeprecated()) { 358 if (transition->CanBeDeprecated()) {
382 __ lwz(scratch, FieldMemOperand(map_reg, Map::kBitField3Offset)); 359 __ LoadlW(scratch, FieldMemOperand(map_reg, Map::kBitField3Offset));
383 __ DecodeField<Map::Deprecated>(r0, scratch, SetRC); 360 __ DecodeField<Map::Deprecated>(r0, scratch);
384 __ bne(miss, cr0); 361 __ bne(miss);
385 } 362 }
386 } 363 }
387 364
388
389 void NamedStoreHandlerCompiler::GenerateConstantCheck(Register map_reg, 365 void NamedStoreHandlerCompiler::GenerateConstantCheck(Register map_reg,
390 int descriptor, 366 int descriptor,
391 Register value_reg, 367 Register value_reg,
392 Register scratch, 368 Register scratch,
393 Label* miss_label) { 369 Label* miss_label) {
394 DCHECK(!map_reg.is(scratch)); 370 DCHECK(!map_reg.is(scratch));
395 DCHECK(!map_reg.is(value_reg)); 371 DCHECK(!map_reg.is(value_reg));
396 DCHECK(!value_reg.is(scratch)); 372 DCHECK(!value_reg.is(scratch));
397 __ LoadInstanceDescriptors(map_reg, scratch); 373 __ LoadInstanceDescriptors(map_reg, scratch);
398 __ LoadP(scratch, FieldMemOperand( 374 __ CmpP(value_reg, FieldMemOperand(
399 scratch, DescriptorArray::GetValueOffset(descriptor))); 375 scratch, DescriptorArray::GetValueOffset(descriptor)));
400 __ cmp(value_reg, scratch);
401 __ bne(miss_label); 376 __ bne(miss_label);
402 } 377 }
403 378
404 void NamedStoreHandlerCompiler::GenerateFieldTypeChecks(FieldType* field_type, 379 void NamedStoreHandlerCompiler::GenerateFieldTypeChecks(FieldType* field_type,
405 Register value_reg, 380 Register value_reg,
406 Label* miss_label) { 381 Label* miss_label) {
407 Register map_reg = scratch1(); 382 Register map_reg = scratch1();
408 Register scratch = scratch2(); 383 Register scratch = scratch2();
409 DCHECK(!value_reg.is(map_reg)); 384 DCHECK(!value_reg.is(map_reg));
410 DCHECK(!value_reg.is(scratch)); 385 DCHECK(!value_reg.is(scratch));
411 __ JumpIfSmi(value_reg, miss_label); 386 __ JumpIfSmi(value_reg, miss_label);
412 if (field_type->IsClass()) { 387 if (field_type->IsClass()) {
413 __ LoadP(map_reg, FieldMemOperand(value_reg, HeapObject::kMapOffset)); 388 __ LoadP(map_reg, FieldMemOperand(value_reg, HeapObject::kMapOffset));
414 __ CmpWeakValue(map_reg, Map::WeakCellForMap(field_type->AsClass()), 389 __ CmpWeakValue(map_reg, Map::WeakCellForMap(field_type->AsClass()),
415 scratch); 390 scratch);
416 __ bne(miss_label); 391 __ bne(miss_label);
417 } 392 }
418 } 393 }
419 394
420
421 Register PropertyHandlerCompiler::CheckPrototypes( 395 Register PropertyHandlerCompiler::CheckPrototypes(
422 Register object_reg, Register holder_reg, Register scratch1, 396 Register object_reg, Register holder_reg, Register scratch1,
423 Register scratch2, Handle<Name> name, Label* miss, PrototypeCheckType check, 397 Register scratch2, Handle<Name> name, Label* miss, PrototypeCheckType check,
424 ReturnHolder return_what) { 398 ReturnHolder return_what) {
425 Handle<Map> receiver_map = map(); 399 Handle<Map> receiver_map = map();
426 400
427 // Make sure there's no overlap between holder and object registers. 401 // Make sure there's no overlap between holder and object registers.
428 DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 402 DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
429 DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) && 403 DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
430 !scratch2.is(scratch1)); 404 !scratch2.is(scratch1));
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 521
548 bool return_holder = return_what == RETURN_HOLDER; 522 bool return_holder = return_what == RETURN_HOLDER;
549 if (FLAG_eliminate_prototype_chain_checks && return_holder && depth != 0) { 523 if (FLAG_eliminate_prototype_chain_checks && return_holder && depth != 0) {
550 __ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss); 524 __ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss);
551 } 525 }
552 526
553 // Return the register containing the holder. 527 // Return the register containing the holder.
554 return return_holder ? reg : no_reg; 528 return return_holder ? reg : no_reg;
555 } 529 }
556 530
557
558 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 531 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
559 if (!miss->is_unused()) { 532 if (!miss->is_unused()) {
560 Label success; 533 Label success;
561 __ b(&success); 534 __ b(&success);
562 __ bind(miss); 535 __ bind(miss);
563 if (IC::ICUseVector(kind())) { 536 if (IC::ICUseVector(kind())) {
564 DCHECK(kind() == Code::LOAD_IC); 537 DCHECK(kind() == Code::LOAD_IC);
565 PopVectorAndSlot(); 538 PopVectorAndSlot();
566 } 539 }
567 TailCallBuiltin(masm(), MissBuiltin(kind())); 540 TailCallBuiltin(masm(), MissBuiltin(kind()));
568 __ bind(&success); 541 __ bind(&success);
569 } 542 }
570 } 543 }
571 544
572
573 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 545 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
574 if (!miss->is_unused()) { 546 if (!miss->is_unused()) {
575 Label success; 547 Label success;
576 __ b(&success); 548 __ b(&success);
577 GenerateRestoreName(miss, name); 549 GenerateRestoreName(miss, name);
578 if (IC::ICUseVector(kind())) PopVectorAndSlot(); 550 if (IC::ICUseVector(kind())) PopVectorAndSlot();
579 TailCallBuiltin(masm(), MissBuiltin(kind())); 551 TailCallBuiltin(masm(), MissBuiltin(kind()));
580 __ bind(&success); 552 __ bind(&success);
581 } 553 }
582 } 554 }
583 555
584
585 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { 556 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
586 // Return the constant value. 557 // Return the constant value.
587 __ Move(r3, value); 558 __ Move(r2, value);
588 __ Ret(); 559 __ Ret();
589 } 560 }
590 561
591
592 void NamedLoadHandlerCompiler::GenerateLoadCallback( 562 void NamedLoadHandlerCompiler::GenerateLoadCallback(
593 Register reg, Handle<AccessorInfo> callback) { 563 Register reg, Handle<AccessorInfo> callback) {
594 DCHECK(!AreAliased(scratch2(), scratch3(), scratch4(), receiver())); 564 DCHECK(!AreAliased(scratch2(), scratch3(), scratch4(), receiver()));
595 DCHECK(!AreAliased(scratch2(), scratch3(), scratch4(), reg)); 565 DCHECK(!AreAliased(scratch2(), scratch3(), scratch4(), reg));
596 566
597 // Build v8::PropertyCallbackInfo::args_ array on the stack and push property 567 // Build v8::PropertyCallbackInfo::args_ array on the stack and push property
598 // name below the exit frame to make GC aware of them. 568 // name below the exit frame to make GC aware of them.
599 STATIC_ASSERT(PropertyCallbackArguments::kShouldThrowOnErrorIndex == 0); 569 STATIC_ASSERT(PropertyCallbackArguments::kShouldThrowOnErrorIndex == 0);
600 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 1); 570 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 1);
601 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 2); 571 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 2);
602 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 3); 572 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 3);
603 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 4); 573 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 4);
604 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 5); 574 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 5);
605 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 6); 575 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 6);
606 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 7); 576 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 7);
607 577
608 __ push(receiver()); 578 __ Push(receiver());
609 // Push data from AccessorInfo. 579 // Push data from AccessorInfo.
610 Handle<Object> data(callback->data(), isolate()); 580 Handle<Object> data(callback->data(), isolate());
611 if (data->IsUndefined() || data->IsSmi()) { 581 if (data->IsUndefined() || data->IsSmi()) {
612 __ Move(scratch2(), data); 582 __ Move(scratch2(), data);
613 } else { 583 } else {
614 Handle<WeakCell> cell = 584 Handle<WeakCell> cell =
615 isolate()->factory()->NewWeakCell(Handle<HeapObject>::cast(data)); 585 isolate()->factory()->NewWeakCell(Handle<HeapObject>::cast(data));
616 // The callback is alive if this instruction is executed, 586 // The callback is alive if this instruction is executed,
617 // so the weak cell is not cleared and points to data. 587 // so the weak cell is not cleared and points to data.
618 __ GetWeakValue(scratch2(), cell); 588 __ GetWeakValue(scratch2(), cell);
(...skipping 12 matching lines...) Expand all
631 Address getter_address = v8::ToCData<Address>(callback->getter()); 601 Address getter_address = v8::ToCData<Address>(callback->getter());
632 ApiFunction fun(getter_address); 602 ApiFunction fun(getter_address);
633 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; 603 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
634 ExternalReference ref = ExternalReference(&fun, type, isolate()); 604 ExternalReference ref = ExternalReference(&fun, type, isolate());
635 __ mov(getter_address_reg, Operand(ref)); 605 __ mov(getter_address_reg, Operand(ref));
636 606
637 CallApiGetterStub stub(isolate()); 607 CallApiGetterStub stub(isolate());
638 __ TailCallStub(&stub); 608 __ TailCallStub(&stub);
639 } 609 }
640 610
641
642 void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup( 611 void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup(
643 LookupIterator* it, Register holder_reg) { 612 LookupIterator* it, Register holder_reg) {
644 DCHECK(holder()->HasNamedInterceptor()); 613 DCHECK(holder()->HasNamedInterceptor());
645 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined()); 614 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
646 615
647 // Compile the interceptor call, followed by inline code to load the 616 // Compile the interceptor call, followed by inline code to load the
648 // property from further up the prototype chain if the call fails. 617 // property from further up the prototype chain if the call fails.
649 // Check that the maps haven't changed. 618 // Check that the maps haven't changed.
650 DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1())); 619 DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
651 620
652 // Preserve the receiver register explicitly whenever it is different from the 621 // Preserve the receiver register explicitly whenever it is different from the
653 // holder and it is needed should the interceptor return without any result. 622 // holder and it is needed should the interceptor return without any result.
654 // The ACCESSOR case needs the receiver to be passed into C++ code, the FIELD 623 // The ACCESSOR case needs the receiver to be passed into C++ code, the FIELD
655 // case might cause a miss during the prototype check. 624 // case might cause a miss during the prototype check.
656 bool must_perform_prototype_check = 625 bool must_perform_prototype_check =
657 !holder().is_identical_to(it->GetHolder<JSObject>()); 626 !holder().is_identical_to(it->GetHolder<JSObject>());
658 bool must_preserve_receiver_reg = 627 bool must_preserve_receiver_reg =
659 !receiver().is(holder_reg) && 628 !receiver().is(holder_reg) &&
660 (it->state() == LookupIterator::ACCESSOR || must_perform_prototype_check); 629 (it->state() == LookupIterator::ACCESSOR || must_perform_prototype_check);
661 630
662 // Save necessary data before invoking an interceptor. 631 // Save necessary data before invoking an interceptor.
663 // Requires a frame to make GC aware of pushed pointers. 632 // Requires a frame to make GC aware of pushed pointers.
664 { 633 {
665 FrameAndConstantPoolScope frame_scope(masm(), StackFrame::INTERNAL); 634 FrameScope frame_scope(masm(), StackFrame::INTERNAL);
666 if (must_preserve_receiver_reg) { 635 if (must_preserve_receiver_reg) {
667 __ Push(receiver(), holder_reg, this->name()); 636 __ Push(receiver(), holder_reg, this->name());
668 } else { 637 } else {
669 __ Push(holder_reg, this->name()); 638 __ Push(holder_reg, this->name());
670 } 639 }
671 InterceptorVectorSlotPush(holder_reg); 640 InterceptorVectorSlotPush(holder_reg);
672 // Invoke an interceptor. Note: map checks from receiver to 641 // Invoke an interceptor. Note: map checks from receiver to
673 // interceptor's holder has been compiled before (see a caller 642 // interceptor's holder has been compiled before (see a caller
674 // of this method.) 643 // of this method.)
675 CompileCallLoadPropertyWithInterceptor( 644 CompileCallLoadPropertyWithInterceptor(
676 masm(), receiver(), holder_reg, this->name(), holder(), 645 masm(), receiver(), holder_reg, this->name(), holder(),
677 Runtime::kLoadPropertyWithInterceptorOnly); 646 Runtime::kLoadPropertyWithInterceptorOnly);
678 647
679 // Check if interceptor provided a value for property. If it's 648 // Check if interceptor provided a value for property. If it's
680 // the case, return immediately. 649 // the case, return immediately.
681 Label interceptor_failed; 650 Label interceptor_failed;
682 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex); 651 __ CompareRoot(r2, Heap::kNoInterceptorResultSentinelRootIndex);
683 __ cmp(r3, scratch1()); 652 __ beq(&interceptor_failed, Label::kNear);
684 __ beq(&interceptor_failed);
685 frame_scope.GenerateLeaveFrame(); 653 frame_scope.GenerateLeaveFrame();
686 __ Ret(); 654 __ Ret();
687 655
688 __ bind(&interceptor_failed); 656 __ bind(&interceptor_failed);
689 InterceptorVectorSlotPop(holder_reg); 657 InterceptorVectorSlotPop(holder_reg);
690 __ pop(this->name()); 658 __ Pop(this->name());
691 __ pop(holder_reg); 659 __ Pop(holder_reg);
692 if (must_preserve_receiver_reg) { 660 if (must_preserve_receiver_reg) {
693 __ pop(receiver()); 661 __ Pop(receiver());
694 } 662 }
695 // Leave the internal frame. 663 // Leave the internal frame.
696 } 664 }
697 665
698 GenerateLoadPostInterceptor(it, holder_reg); 666 GenerateLoadPostInterceptor(it, holder_reg);
699 } 667 }
700 668
701
702 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) { 669 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
703 // Call the runtime system to load the interceptor. 670 // Call the runtime system to load the interceptor.
704 DCHECK(holder()->HasNamedInterceptor()); 671 DCHECK(holder()->HasNamedInterceptor());
705 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined()); 672 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
706 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(), 673 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
707 holder()); 674 holder());
708 675
709 __ TailCallRuntime(Runtime::kLoadPropertyWithInterceptor); 676 __ TailCallRuntime(Runtime::kLoadPropertyWithInterceptor);
710 } 677 }
711 678
712
713 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 679 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
714 Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback, 680 Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback,
715 LanguageMode language_mode) { 681 LanguageMode language_mode) {
716 Register holder_reg = Frontend(name); 682 Register holder_reg = Frontend(name);
717 683
718 __ Push(receiver(), holder_reg); // receiver 684 __ Push(receiver(), holder_reg); // receiver
719 685
720 // If the callback cannot leak, then push the callback directly, 686 // If the callback cannot leak, then push the callback directly,
721 // otherwise wrap it in a weak cell. 687 // otherwise wrap it in a weak cell.
722 if (callback->data()->IsUndefined() || callback->data()->IsSmi()) { 688 if (callback->data()->IsUndefined() || callback->data()->IsSmi()) {
723 __ mov(ip, Operand(callback)); 689 __ mov(ip, Operand(callback));
724 } else { 690 } else {
725 Handle<WeakCell> cell = isolate()->factory()->NewWeakCell(callback); 691 Handle<WeakCell> cell = isolate()->factory()->NewWeakCell(callback);
726 __ mov(ip, Operand(cell)); 692 __ mov(ip, Operand(cell));
727 } 693 }
728 __ push(ip); 694 __ Push(ip);
729 __ mov(ip, Operand(name)); 695 __ mov(ip, Operand(name));
730 __ Push(ip, value()); 696 __ Push(ip, value());
731 __ Push(Smi::FromInt(language_mode)); 697 __ Push(Smi::FromInt(language_mode));
732 698
733 // Do tail-call to the runtime system. 699 // Do tail-call to the runtime system.
734 __ TailCallRuntime(Runtime::kStoreCallbackProperty); 700 __ TailCallRuntime(Runtime::kStoreCallbackProperty);
735 701
736 // Return the generated code. 702 // Return the generated code.
737 return GetCode(kind(), Code::FAST, name); 703 return GetCode(kind(), Code::FAST, name);
738 } 704 }
739 705
740
741 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor( 706 Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
742 Handle<Name> name) { 707 Handle<Name> name) {
743 __ Push(receiver(), this->name(), value()); 708 __ Push(receiver(), this->name(), value());
744 709
745 // Do tail-call to the runtime system. 710 // Do tail-call to the runtime system.
746 __ TailCallRuntime(Runtime::kStorePropertyWithInterceptor); 711 __ TailCallRuntime(Runtime::kStorePropertyWithInterceptor);
747 712
748 // Return the generated code. 713 // Return the generated code.
749 return GetCode(kind(), Code::FAST, name); 714 return GetCode(kind(), Code::FAST, name);
750 } 715 }
751 716
752
753 Register NamedStoreHandlerCompiler::value() { 717 Register NamedStoreHandlerCompiler::value() {
754 return StoreDescriptor::ValueRegister(); 718 return StoreDescriptor::ValueRegister();
755 } 719 }
756 720
757
758 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 721 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
759 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { 722 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
760 Label miss; 723 Label miss;
761 if (IC::ICUseVector(kind())) { 724 if (IC::ICUseVector(kind())) {
762 PushVectorAndSlot(); 725 PushVectorAndSlot();
763 } 726 }
764 FrontendHeader(receiver(), name, &miss, DONT_RETURN_ANYTHING); 727 FrontendHeader(receiver(), name, &miss, DONT_RETURN_ANYTHING);
765 728
766 // Get the value from the cell. 729 // Get the value from the cell.
767 Register result = StoreDescriptor::ValueRegister(); 730 Register result = StoreDescriptor::ValueRegister();
768 Handle<WeakCell> weak_cell = factory()->NewWeakCell(cell); 731 Handle<WeakCell> weak_cell = factory()->NewWeakCell(cell);
769 __ LoadWeakValue(result, weak_cell, &miss); 732 __ LoadWeakValue(result, weak_cell, &miss);
770 __ LoadP(result, FieldMemOperand(result, PropertyCell::kValueOffset)); 733 __ LoadP(result, FieldMemOperand(result, PropertyCell::kValueOffset));
771 734
772 // Check for deleted property if property can actually be deleted. 735 // Check for deleted property if property can actually be deleted.
773 if (is_configurable) { 736 if (is_configurable) {
774 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 737 __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
775 __ cmp(result, ip);
776 __ beq(&miss); 738 __ beq(&miss);
777 } 739 }
778 740
779 Counters* counters = isolate()->counters(); 741 Counters* counters = isolate()->counters();
780 __ IncrementCounter(counters->ic_named_load_global_stub(), 1, r4, r6); 742 __ IncrementCounter(counters->ic_named_load_global_stub(), 1, r3, r5);
781 if (IC::ICUseVector(kind())) { 743 if (IC::ICUseVector(kind())) {
782 DiscardVectorAndSlot(); 744 DiscardVectorAndSlot();
783 } 745 }
784 __ Ret(); 746 __ Ret();
785 747
786 FrontendFooter(name, &miss); 748 FrontendFooter(name, &miss);
787 749
788 // Return the generated code. 750 // Return the generated code.
789 return GetCode(kind(), Code::NORMAL, name); 751 return GetCode(kind(), Code::NORMAL, name);
790 } 752 }
791 753
792
793 #undef __ 754 #undef __
794 } // namespace internal 755 } // namespace internal
795 } // namespace v8 756 } // namespace v8
796 757
797 #endif // V8_TARGET_ARCH_ARM 758 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/ic/s390/access-compiler-s390.cc ('k') | src/ic/s390/ic-compiler-s390.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698