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

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

Issue 571173003: PowerPC specific sub-directories (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Updated ppc sub-dirs to current V8 code levels Created 6 years, 2 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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 //
5 // Copyright IBM Corp. 2012, 2013. All rights reserved.
4 6
5 #include "src/v8.h" 7 #include "src/v8.h"
6 8
7 #if V8_TARGET_ARCH_ARM 9 #if V8_TARGET_ARCH_PPC
8 10
9 #include "src/ic/call-optimization.h" 11 #include "src/ic/call-optimization.h"
10 #include "src/ic/handler-compiler.h" 12 #include "src/ic/handler-compiler.h"
13 #include "src/ic/ic.h"
11 14
12 namespace v8 { 15 namespace v8 {
13 namespace internal { 16 namespace internal {
14 17
15 #define __ ACCESS_MASM(masm) 18 #define __ ACCESS_MASM(masm)
16 19
17 20
18 void NamedLoadHandlerCompiler::GenerateLoadViaGetter( 21 void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
19 MacroAssembler* masm, Handle<HeapType> type, Register receiver, 22 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
20 Handle<JSFunction> getter) { 23 Handle<JSFunction> getter) {
21 // ----------- S t a t e ------------- 24 // ----------- S t a t e -------------
22 // -- r0 : receiver 25 // -- r3 : receiver
23 // -- r2 : name 26 // -- r5 : name
24 // -- lr : return address 27 // -- lr : return address
25 // ----------------------------------- 28 // -----------------------------------
26 { 29 {
27 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); 30 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
28 31
29 if (!getter.is_null()) { 32 if (!getter.is_null()) {
30 // Call the JavaScript getter with the receiver on the stack. 33 // Call the JavaScript getter with the receiver on the stack.
31 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { 34 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
32 // Swap in the global receiver. 35 // Swap in the global receiver.
33 __ ldr(receiver, 36 __ LoadP(receiver,
34 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); 37 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
35 } 38 }
36 __ push(receiver); 39 __ push(receiver);
37 ParameterCount actual(0); 40 ParameterCount actual(0);
38 ParameterCount expected(getter); 41 ParameterCount expected(getter);
39 __ InvokeFunction(getter, expected, actual, CALL_FUNCTION, 42 __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
40 NullCallWrapper()); 43 NullCallWrapper());
41 } else { 44 } else {
42 // If we generate a global code snippet for deoptimization only, remember 45 // If we generate a global code snippet for deoptimization only, remember
43 // the place to continue after deoptimization. 46 // the place to continue after deoptimization.
44 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset()); 47 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
45 } 48 }
46 49
47 // Restore context register. 50 // Restore context register.
48 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 51 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
49 } 52 }
50 __ Ret(); 53 __ Ret();
51 } 54 }
52 55
53 56
54 void NamedStoreHandlerCompiler::GenerateStoreViaSetter( 57 void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
55 MacroAssembler* masm, Handle<HeapType> type, Register receiver, 58 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
56 Handle<JSFunction> setter) { 59 Handle<JSFunction> setter) {
57 // ----------- S t a t e ------------- 60 // ----------- S t a t e -------------
58 // -- lr : return address 61 // -- lr : return address
59 // ----------------------------------- 62 // -----------------------------------
60 { 63 {
61 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); 64 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
62 65
63 // Save value register, so we can restore it later. 66 // Save value register, so we can restore it later.
64 __ push(value()); 67 __ push(value());
65 68
66 if (!setter.is_null()) { 69 if (!setter.is_null()) {
67 // Call the JavaScript setter with receiver and value on the stack. 70 // Call the JavaScript setter with receiver and value on the stack.
68 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { 71 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
69 // Swap in the global receiver. 72 // Swap in the global receiver.
70 __ ldr(receiver, 73 __ LoadP(receiver,
71 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); 74 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
72 } 75 }
73 __ Push(receiver, value()); 76 __ Push(receiver, value());
74 ParameterCount actual(1); 77 ParameterCount actual(1);
75 ParameterCount expected(setter); 78 ParameterCount expected(setter);
76 __ InvokeFunction(setter, expected, actual, CALL_FUNCTION, 79 __ InvokeFunction(setter, expected, actual, CALL_FUNCTION,
77 NullCallWrapper()); 80 NullCallWrapper());
78 } else { 81 } else {
79 // If we generate a global code snippet for deoptimization only, remember 82 // If we generate a global code snippet for deoptimization only, remember
80 // the place to continue after deoptimization. 83 // the place to continue after deoptimization.
81 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); 84 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
82 } 85 }
83 86
84 // We have to return the passed value, not the return value of the setter. 87 // We have to return the passed value, not the return value of the setter.
85 __ pop(r0); 88 __ pop(r3);
86 89
87 // Restore context register. 90 // Restore context register.
88 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 91 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
89 } 92 }
90 __ Ret(); 93 __ Ret();
91 } 94 }
92 95
93 96
94 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( 97 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
95 MacroAssembler* masm, Label* miss_label, Register receiver, 98 MacroAssembler* masm, Label* miss_label, Register receiver,
96 Handle<Name> name, Register scratch0, Register scratch1) { 99 Handle<Name> name, Register scratch0, Register scratch1) {
97 DCHECK(name->IsUniqueName()); 100 DCHECK(name->IsUniqueName());
98 DCHECK(!receiver.is(scratch0)); 101 DCHECK(!receiver.is(scratch0));
99 Counters* counters = masm->isolate()->counters(); 102 Counters* counters = masm->isolate()->counters();
100 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); 103 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
101 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 104 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
102 105
103 Label done; 106 Label done;
104 107
105 const int kInterceptorOrAccessCheckNeededMask = 108 const int kInterceptorOrAccessCheckNeededMask =
106 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); 109 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
107 110
108 // Bail out if the receiver has a named interceptor or requires access checks. 111 // Bail out if the receiver has a named interceptor or requires access checks.
109 Register map = scratch1; 112 Register map = scratch1;
110 __ ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); 113 __ LoadP(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
111 __ ldrb(scratch0, FieldMemOperand(map, Map::kBitFieldOffset)); 114 __ lbz(scratch0, FieldMemOperand(map, Map::kBitFieldOffset));
112 __ tst(scratch0, Operand(kInterceptorOrAccessCheckNeededMask)); 115 __ andi(r0, scratch0, Operand(kInterceptorOrAccessCheckNeededMask));
113 __ b(ne, miss_label); 116 __ bne(miss_label, cr0);
114 117
115 // Check that receiver is a JSObject. 118 // Check that receiver is a JSObject.
116 __ ldrb(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset)); 119 __ lbz(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset));
117 __ cmp(scratch0, Operand(FIRST_SPEC_OBJECT_TYPE)); 120 __ cmpi(scratch0, Operand(FIRST_SPEC_OBJECT_TYPE));
118 __ b(lt, miss_label); 121 __ blt(miss_label);
119 122
120 // Load properties array. 123 // Load properties array.
121 Register properties = scratch0; 124 Register properties = scratch0;
122 __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 125 __ LoadP(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
123 // Check that the properties array is a dictionary. 126 // Check that the properties array is a dictionary.
124 __ ldr(map, FieldMemOperand(properties, HeapObject::kMapOffset)); 127 __ LoadP(map, FieldMemOperand(properties, HeapObject::kMapOffset));
125 Register tmp = properties; 128 Register tmp = properties;
126 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); 129 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex);
127 __ cmp(map, tmp); 130 __ cmp(map, tmp);
128 __ b(ne, miss_label); 131 __ bne(miss_label);
129 132
130 // Restore the temporarily used register. 133 // Restore the temporarily used register.
131 __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 134 __ LoadP(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
132 135
133 136
134 NameDictionaryLookupStub::GenerateNegativeLookup( 137 NameDictionaryLookupStub::GenerateNegativeLookup(
135 masm, miss_label, &done, receiver, properties, name, scratch1); 138 masm, miss_label, &done, receiver, properties, name, scratch1);
136 __ bind(&done); 139 __ bind(&done);
137 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 140 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
138 } 141 }
139 142
140 143
141 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype( 144 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
142 MacroAssembler* masm, int index, Register prototype, Label* miss) { 145 MacroAssembler* masm, int index, Register prototype, Label* miss) {
143 Isolate* isolate = masm->isolate(); 146 Isolate* isolate = masm->isolate();
144 // Get the global function with the given index. 147 // Get the global function with the given index.
145 Handle<JSFunction> function( 148 Handle<JSFunction> function(
146 JSFunction::cast(isolate->native_context()->get(index))); 149 JSFunction::cast(isolate->native_context()->get(index)));
147 150
148 // Check we're still in the same context. 151 // Check we're still in the same context.
149 Register scratch = prototype; 152 Register scratch = prototype;
150 const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX); 153 const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX);
151 __ ldr(scratch, MemOperand(cp, offset)); 154 __ LoadP(scratch, MemOperand(cp, offset));
152 __ ldr(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset)); 155 __ LoadP(scratch,
153 __ ldr(scratch, MemOperand(scratch, Context::SlotOffset(index))); 156 FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
157 __ LoadP(scratch, MemOperand(scratch, Context::SlotOffset(index)));
154 __ Move(ip, function); 158 __ Move(ip, function);
155 __ cmp(ip, scratch); 159 __ cmp(ip, scratch);
156 __ b(ne, miss); 160 __ bne(miss);
157 161
158 // Load its initial map. The global functions all have initial maps. 162 // Load its initial map. The global functions all have initial maps.
159 __ Move(prototype, Handle<Map>(function->initial_map())); 163 __ Move(prototype, Handle<Map>(function->initial_map()));
160 // Load the prototype from the initial map. 164 // Load the prototype from the initial map.
161 __ ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); 165 __ LoadP(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
162 } 166 }
163 167
164 168
165 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype( 169 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
166 MacroAssembler* masm, Register receiver, Register scratch1, 170 MacroAssembler* masm, Register receiver, Register scratch1,
167 Register scratch2, Label* miss_label) { 171 Register scratch2, Label* miss_label) {
168 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); 172 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
169 __ mov(r0, scratch1); 173 __ mr(r3, scratch1);
170 __ Ret(); 174 __ Ret();
171 } 175 }
172 176
173 177
174 // Generate code to check that a global property cell is empty. Create 178 // Generate code to check that a global property cell is empty. Create
175 // the property cell at compilation time if no cell exists for the 179 // the property cell at compilation time if no cell exists for the
176 // property. 180 // property.
177 void PropertyHandlerCompiler::GenerateCheckPropertyCell( 181 void PropertyHandlerCompiler::GenerateCheckPropertyCell(
178 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name, 182 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
179 Register scratch, Label* miss) { 183 Register scratch, Label* miss) {
180 Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name); 184 Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
181 DCHECK(cell->value()->IsTheHole()); 185 DCHECK(cell->value()->IsTheHole());
182 __ mov(scratch, Operand(cell)); 186 __ mov(scratch, Operand(cell));
183 __ ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); 187 __ LoadP(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
184 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 188 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
185 __ cmp(scratch, ip); 189 __ cmp(scratch, ip);
186 __ b(ne, miss); 190 __ bne(miss);
187 } 191 }
188 192
189 193
190 static void PushInterceptorArguments(MacroAssembler* masm, Register receiver, 194 static void PushInterceptorArguments(MacroAssembler* masm, Register receiver,
191 Register holder, Register name, 195 Register holder, Register name,
192 Handle<JSObject> holder_obj) { 196 Handle<JSObject> holder_obj) {
193 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0); 197 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
194 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1); 198 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1);
195 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2); 199 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2);
196 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3); 200 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3);
(...skipping 28 matching lines...) Expand all
225 // Write the arguments to stack frame. 229 // Write the arguments to stack frame.
226 for (int i = 0; i < argc; i++) { 230 for (int i = 0; i < argc; i++) {
227 Register arg = values[argc - 1 - i]; 231 Register arg = values[argc - 1 - i];
228 DCHECK(!receiver.is(arg)); 232 DCHECK(!receiver.is(arg));
229 DCHECK(!scratch_in.is(arg)); 233 DCHECK(!scratch_in.is(arg));
230 __ push(arg); 234 __ push(arg);
231 } 235 }
232 DCHECK(optimization.is_simple_api_call()); 236 DCHECK(optimization.is_simple_api_call());
233 237
234 // Abi for CallApiFunctionStub. 238 // Abi for CallApiFunctionStub.
235 Register callee = r0; 239 Register callee = r3;
236 Register call_data = r4; 240 Register call_data = r7;
237 Register holder = r2; 241 Register holder = r5;
238 Register api_function_address = r1; 242 Register api_function_address = r4;
239 243
240 // Put holder in place. 244 // Put holder in place.
241 CallOptimization::HolderLookup holder_lookup; 245 CallOptimization::HolderLookup holder_lookup;
242 Handle<JSObject> api_holder = 246 Handle<JSObject> api_holder =
243 optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup); 247 optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
244 switch (holder_lookup) { 248 switch (holder_lookup) {
245 case CallOptimization::kHolderIsReceiver: 249 case CallOptimization::kHolderIsReceiver:
246 __ Move(holder, receiver); 250 __ Move(holder, receiver);
247 break; 251 break;
248 case CallOptimization::kHolderFound: 252 case CallOptimization::kHolderFound:
249 __ Move(holder, api_holder); 253 __ Move(holder, api_holder);
250 break; 254 break;
251 case CallOptimization::kHolderNotFound: 255 case CallOptimization::kHolderNotFound:
252 UNREACHABLE(); 256 UNREACHABLE();
253 break; 257 break;
254 } 258 }
255 259
256 Isolate* isolate = masm->isolate(); 260 Isolate* isolate = masm->isolate();
257 Handle<JSFunction> function = optimization.constant_function(); 261 Handle<JSFunction> function = optimization.constant_function();
258 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 262 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
259 Handle<Object> call_data_obj(api_call_info->data(), isolate); 263 Handle<Object> call_data_obj(api_call_info->data(), isolate);
260 264
261 // Put callee in place. 265 // Put callee in place.
262 __ Move(callee, function); 266 __ Move(callee, function);
263 267
264 bool call_data_undefined = false; 268 bool call_data_undefined = false;
265 // Put call_data in place. 269 // Put call_data in place.
266 if (isolate->heap()->InNewSpace(*call_data_obj)) { 270 if (isolate->heap()->InNewSpace(*call_data_obj)) {
267 __ Move(call_data, api_call_info); 271 __ Move(call_data, api_call_info);
268 __ ldr(call_data, FieldMemOperand(call_data, CallHandlerInfo::kDataOffset)); 272 __ LoadP(call_data,
273 FieldMemOperand(call_data, CallHandlerInfo::kDataOffset));
269 } else if (call_data_obj->IsUndefined()) { 274 } else if (call_data_obj->IsUndefined()) {
270 call_data_undefined = true; 275 call_data_undefined = true;
271 __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex); 276 __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
272 } else { 277 } else {
273 __ Move(call_data, call_data_obj); 278 __ Move(call_data, call_data_obj);
274 } 279 }
275 280
276 // Put api_function_address in place. 281 // Put api_function_address in place.
277 Address function_address = v8::ToCData<Address>(api_call_info->callback()); 282 Address function_address = v8::ToCData<Address>(api_call_info->callback());
278 ApiFunction fun(function_address); 283 ApiFunction fun(function_address);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 323
319 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, 324 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
320 Handle<Name> name) { 325 Handle<Name> name) {
321 if (!label->is_unused()) { 326 if (!label->is_unused()) {
322 __ bind(label); 327 __ bind(label);
323 __ mov(this->name(), Operand(name)); 328 __ mov(this->name(), Operand(name));
324 } 329 }
325 } 330 }
326 331
327 332
328 // Generate StoreTransition code, value is passed in r0 register. 333 // Generate StoreTransition code, value is passed in r3 register.
329 // When leaving generated code after success, the receiver_reg and name_reg 334 // When leaving generated code after success, the receiver_reg and name_reg
330 // may be clobbered. Upon branch to miss_label, the receiver and name 335 // may be clobbered. Upon branch to miss_label, the receiver and name
331 // registers have their original values. 336 // registers have their original values.
332 void NamedStoreHandlerCompiler::GenerateStoreTransition( 337 void NamedStoreHandlerCompiler::GenerateStoreTransition(
333 Handle<Map> transition, Handle<Name> name, Register receiver_reg, 338 Handle<Map> transition, Handle<Name> name, Register receiver_reg,
334 Register storage_reg, Register value_reg, Register scratch1, 339 Register storage_reg, Register value_reg, Register scratch1,
335 Register scratch2, Register scratch3, Label* miss_label, Label* slow) { 340 Register scratch2, Register scratch3, Label* miss_label, Label* slow) {
336 // r0 : value 341 // r3 : value
337 Label exit; 342 Label exit;
338 343
339 int descriptor = transition->LastAdded(); 344 int descriptor = transition->LastAdded();
340 DescriptorArray* descriptors = transition->instance_descriptors(); 345 DescriptorArray* descriptors = transition->instance_descriptors();
341 PropertyDetails details = descriptors->GetDetails(descriptor); 346 PropertyDetails details = descriptors->GetDetails(descriptor);
342 Representation representation = details.representation(); 347 Representation representation = details.representation();
343 DCHECK(!representation.IsNone()); 348 DCHECK(!representation.IsNone());
344 349
345 if (details.type() == CONSTANT) { 350 if (details.type() == CONSTANT) {
346 Handle<Object> constant(descriptors->GetValue(descriptor), isolate()); 351 Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
347 __ Move(scratch1, constant); 352 __ Move(scratch1, constant);
348 __ cmp(value_reg, scratch1); 353 __ cmp(value_reg, scratch1);
349 __ b(ne, miss_label); 354 __ bne(miss_label);
350 } else if (representation.IsSmi()) { 355 } else if (representation.IsSmi()) {
351 __ JumpIfNotSmi(value_reg, miss_label); 356 __ JumpIfNotSmi(value_reg, miss_label);
352 } else if (representation.IsHeapObject()) { 357 } else if (representation.IsHeapObject()) {
353 __ JumpIfSmi(value_reg, miss_label); 358 __ JumpIfSmi(value_reg, miss_label);
354 HeapType* field_type = descriptors->GetFieldType(descriptor); 359 HeapType* field_type = descriptors->GetFieldType(descriptor);
355 HeapType::Iterator<Map> it = field_type->Classes(); 360 HeapType::Iterator<Map> it = field_type->Classes();
356 if (!it.Done()) { 361 if (!it.Done()) {
357 __ ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset)); 362 __ LoadP(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
358 Label do_store; 363 Label do_store;
359 while (true) { 364 while (true) {
360 __ CompareMap(scratch1, it.Current(), &do_store); 365 __ CompareMap(scratch1, it.Current(), &do_store);
361 it.Advance(); 366 it.Advance();
362 if (it.Done()) { 367 if (it.Done()) {
363 __ b(ne, miss_label); 368 __ bne(miss_label);
364 break; 369 break;
365 } 370 }
366 __ b(eq, &do_store); 371 __ beq(&do_store);
367 } 372 }
368 __ bind(&do_store); 373 __ bind(&do_store);
369 } 374 }
370 } else if (representation.IsDouble()) { 375 } else if (representation.IsDouble()) {
371 Label do_store, heap_number; 376 Label do_store, heap_number;
372 __ LoadRoot(scratch3, Heap::kMutableHeapNumberMapRootIndex); 377 __ LoadRoot(scratch3, Heap::kMutableHeapNumberMapRootIndex);
373 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow, 378 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow,
374 TAG_RESULT, MUTABLE); 379 TAG_RESULT, MUTABLE);
375 380
376 __ JumpIfNotSmi(value_reg, &heap_number); 381 __ JumpIfNotSmi(value_reg, &heap_number);
377 __ SmiUntag(scratch1, value_reg); 382 __ SmiUntag(scratch1, value_reg);
378 __ vmov(s0, scratch1); 383 __ ConvertIntToDouble(scratch1, d0);
379 __ vcvt_f64_s32(d0, s0);
380 __ jmp(&do_store); 384 __ jmp(&do_store);
381 385
382 __ bind(&heap_number); 386 __ bind(&heap_number);
383 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, miss_label, 387 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, miss_label,
384 DONT_DO_SMI_CHECK); 388 DONT_DO_SMI_CHECK);
385 __ vldr(d0, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); 389 __ lfd(d0, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
386 390
387 __ bind(&do_store); 391 __ bind(&do_store);
388 __ vstr(d0, FieldMemOperand(storage_reg, HeapNumber::kValueOffset)); 392 __ stfd(d0, FieldMemOperand(storage_reg, HeapNumber::kValueOffset));
389 } 393 }
390 394
391 // Stub never generated for objects that require access checks. 395 // Stub never generated for objects that require access checks.
392 DCHECK(!transition->is_access_check_needed()); 396 DCHECK(!transition->is_access_check_needed());
393 397
394 // Perform map transition for the receiver if necessary. 398 // Perform map transition for the receiver if necessary.
395 if (details.type() == FIELD && 399 if (details.type() == FIELD &&
396 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) { 400 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
397 // The properties must be extended before we can store the value. 401 // The properties must be extended before we can store the value.
398 // We jump to a runtime call that extends the properties array. 402 // We jump to a runtime call that extends the properties array.
399 __ push(receiver_reg); 403 __ push(receiver_reg);
400 __ mov(r2, Operand(transition)); 404 __ mov(r5, Operand(transition));
401 __ Push(r2, r0); 405 __ Push(r5, r3);
402 __ TailCallExternalReference( 406 __ TailCallExternalReference(
403 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 407 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
404 isolate()), 408 isolate()),
405 3, 1); 409 3, 1);
406 return; 410 return;
407 } 411 }
408 412
409 // Update the map of the object. 413 // Update the map of the object.
410 __ mov(scratch1, Operand(transition)); 414 __ mov(scratch1, Operand(transition));
411 __ str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); 415 __ StoreP(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset),
416 r0);
412 417
413 // Update the write barrier for the map field. 418 // Update the write barrier for the map field.
414 __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2, 419 __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
415 kLRHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET, 420 kLRHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET,
416 OMIT_SMI_CHECK); 421 OMIT_SMI_CHECK);
417 422
418 if (details.type() == CONSTANT) { 423 if (details.type() == CONSTANT) {
419 DCHECK(value_reg.is(r0)); 424 DCHECK(value_reg.is(r3));
420 __ Ret(); 425 __ Ret();
421 return; 426 return;
422 } 427 }
423 428
424 int index = transition->instance_descriptors()->GetFieldIndex( 429 int index = transition->instance_descriptors()->GetFieldIndex(
425 transition->LastAdded()); 430 transition->LastAdded());
426 431
427 // Adjust for the number of properties stored in the object. Even in the 432 // Adjust for the number of properties stored in the object. Even in the
428 // face of a transition we can use the old map here because the size of the 433 // face of a transition we can use the old map here because the size of the
429 // object and the number of in-object properties is not going to change. 434 // object and the number of in-object properties is not going to change.
430 index -= transition->inobject_properties(); 435 index -= transition->inobject_properties();
431 436
432 // TODO(verwaest): Share this code as a code stub. 437 // TODO(verwaest): Share this code as a code stub.
433 SmiCheck smi_check = 438 SmiCheck smi_check =
434 representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; 439 representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
435 if (index < 0) { 440 if (index < 0) {
436 // Set the property straight into the object. 441 // Set the property straight into the object.
437 int offset = transition->instance_size() + (index * kPointerSize); 442 int offset = transition->instance_size() + (index * kPointerSize);
438 if (representation.IsDouble()) { 443 if (representation.IsDouble()) {
439 __ str(storage_reg, FieldMemOperand(receiver_reg, offset)); 444 __ StoreP(storage_reg, FieldMemOperand(receiver_reg, offset), r0);
440 } else { 445 } else {
441 __ str(value_reg, FieldMemOperand(receiver_reg, offset)); 446 __ StoreP(value_reg, FieldMemOperand(receiver_reg, offset), r0);
442 } 447 }
443 448
444 if (!representation.IsSmi()) { 449 if (!representation.IsSmi()) {
445 // Update the write barrier for the array address. 450 // Update the write barrier for the array address.
446 if (!representation.IsDouble()) { 451 if (!representation.IsDouble()) {
447 __ mov(storage_reg, value_reg); 452 __ mr(storage_reg, value_reg);
448 } 453 }
449 __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1, 454 __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
450 kLRHasNotBeenSaved, kDontSaveFPRegs, 455 kLRHasNotBeenSaved, kDontSaveFPRegs,
451 EMIT_REMEMBERED_SET, smi_check); 456 EMIT_REMEMBERED_SET, smi_check);
452 } 457 }
453 } else { 458 } else {
454 // Write to the properties array. 459 // Write to the properties array.
455 int offset = index * kPointerSize + FixedArray::kHeaderSize; 460 int offset = index * kPointerSize + FixedArray::kHeaderSize;
456 // Get the properties array 461 // Get the properties array
457 __ ldr(scratch1, 462 __ LoadP(scratch1,
458 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 463 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
459 if (representation.IsDouble()) { 464 if (representation.IsDouble()) {
460 __ str(storage_reg, FieldMemOperand(scratch1, offset)); 465 __ StoreP(storage_reg, FieldMemOperand(scratch1, offset), r0);
461 } else { 466 } else {
462 __ str(value_reg, FieldMemOperand(scratch1, offset)); 467 __ StoreP(value_reg, FieldMemOperand(scratch1, offset), r0);
463 } 468 }
464 469
465 if (!representation.IsSmi()) { 470 if (!representation.IsSmi()) {
466 // Update the write barrier for the array address. 471 // Update the write barrier for the array address.
467 if (!representation.IsDouble()) { 472 if (!representation.IsDouble()) {
468 __ mov(storage_reg, value_reg); 473 __ mr(storage_reg, value_reg);
469 } 474 }
470 __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg, 475 __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
471 kLRHasNotBeenSaved, kDontSaveFPRegs, 476 kLRHasNotBeenSaved, kDontSaveFPRegs,
472 EMIT_REMEMBERED_SET, smi_check); 477 EMIT_REMEMBERED_SET, smi_check);
473 } 478 }
474 } 479 }
475 480
476 // Return the value (register r0). 481 // Return the value (register r3).
477 DCHECK(value_reg.is(r0)); 482 DCHECK(value_reg.is(r3));
478 __ bind(&exit); 483 __ bind(&exit);
479 __ Ret(); 484 __ Ret();
480 } 485 }
481 486
482 487
483 void NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup, 488 void NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup,
484 Register value_reg, 489 Register value_reg,
485 Label* miss_label) { 490 Label* miss_label) {
486 DCHECK(lookup->representation().IsHeapObject()); 491 DCHECK(lookup->representation().IsHeapObject());
487 __ JumpIfSmi(value_reg, miss_label); 492 __ JumpIfSmi(value_reg, miss_label);
488 HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes(); 493 HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
489 __ ldr(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset)); 494 __ LoadP(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset));
490 Label do_store; 495 Label do_store;
491 while (true) { 496 while (true) {
492 __ CompareMap(scratch1(), it.Current(), &do_store); 497 __ CompareMap(scratch1(), it.Current(), &do_store);
493 it.Advance(); 498 it.Advance();
494 if (it.Done()) { 499 if (it.Done()) {
495 __ b(ne, miss_label); 500 __ bne(miss_label);
496 break; 501 break;
497 } 502 }
498 __ b(eq, &do_store); 503 __ beq(&do_store);
499 } 504 }
500 __ bind(&do_store); 505 __ bind(&do_store);
501 506
502 StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), 507 StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
503 lookup->representation()); 508 lookup->representation());
504 GenerateTailCall(masm(), stub.GetCode()); 509 GenerateTailCall(masm(), stub.GetCode());
505 } 510 }
506 511
507 512
508 Register PropertyHandlerCompiler::CheckPrototypes( 513 Register PropertyHandlerCompiler::CheckPrototypes(
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 DCHECK(name->IsString()); 550 DCHECK(name->IsString());
546 name = factory()->InternalizeString(Handle<String>::cast(name)); 551 name = factory()->InternalizeString(Handle<String>::cast(name));
547 } 552 }
548 DCHECK(current.is_null() || 553 DCHECK(current.is_null() ||
549 current->property_dictionary()->FindEntry(name) == 554 current->property_dictionary()->FindEntry(name) ==
550 NameDictionary::kNotFound); 555 NameDictionary::kNotFound);
551 556
552 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1, 557 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
553 scratch2); 558 scratch2);
554 559
555 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); 560 __ LoadP(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
556 reg = holder_reg; // From now on the object will be in holder_reg. 561 reg = holder_reg; // From now on the object will be in holder_reg.
557 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); 562 __ LoadP(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
558 } else { 563 } else {
559 Register map_reg = scratch1; 564 Register map_reg = scratch1;
560 if (depth != 1 || check == CHECK_ALL_MAPS) { 565 if (depth != 1 || check == CHECK_ALL_MAPS) {
561 // CheckMap implicitly loads the map of |reg| into |map_reg|. 566 // CheckMap implicitly loads the map of |reg| into |map_reg|.
562 __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK); 567 __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK);
563 } else { 568 } else {
564 __ ldr(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); 569 __ LoadP(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
565 } 570 }
566 571
567 // Check access rights to the global object. This has to happen after 572 // Check access rights to the global object. This has to happen after
568 // the map check so that we know that the object is actually a global 573 // the map check so that we know that the object is actually a global
569 // object. 574 // object.
570 // This allows us to install generated handlers for accesses to the 575 // This allows us to install generated handlers for accesses to the
571 // global proxy (as opposed to using slow ICs). See corresponding code 576 // global proxy (as opposed to using slow ICs). See corresponding code
572 // in LookupForRead(). 577 // in LookupForRead().
573 if (current_map->IsJSGlobalProxyMap()) { 578 if (current_map->IsJSGlobalProxyMap()) {
574 __ CheckAccessGlobalProxy(reg, scratch2, miss); 579 __ CheckAccessGlobalProxy(reg, scratch2, miss);
575 } else if (current_map->IsJSGlobalObjectMap()) { 580 } else if (current_map->IsJSGlobalObjectMap()) {
576 GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current), 581 GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
577 name, scratch2, miss); 582 name, scratch2, miss);
578 } 583 }
579 584
580 reg = holder_reg; // From now on the object will be in holder_reg. 585 reg = holder_reg; // From now on the object will be in holder_reg.
581 586
582 // Two possible reasons for loading the prototype from the map: 587 // Two possible reasons for loading the prototype from the map:
583 // (1) Can't store references to new space in code. 588 // (1) Can't store references to new space in code.
584 // (2) Handler is shared for all receivers with the same prototype 589 // (2) Handler is shared for all receivers with the same prototype
585 // map (but not necessarily the same prototype instance). 590 // map (but not necessarily the same prototype instance).
586 bool load_prototype_from_map = 591 bool load_prototype_from_map =
587 heap()->InNewSpace(*prototype) || depth == 1; 592 heap()->InNewSpace(*prototype) || depth == 1;
588 if (load_prototype_from_map) { 593 if (load_prototype_from_map) {
589 __ ldr(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset)); 594 __ LoadP(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
590 } else { 595 } else {
591 __ mov(reg, Operand(prototype)); 596 __ mov(reg, Operand(prototype));
592 } 597 }
593 } 598 }
594 599
595 // Go to the next object in the prototype chain. 600 // Go to the next object in the prototype chain.
596 current = prototype; 601 current = prototype;
597 current_map = handle(current->map()); 602 current_map = handle(current->map());
598 } 603 }
599 604
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 __ b(&success); 639 __ b(&success);
635 GenerateRestoreName(miss, name); 640 GenerateRestoreName(miss, name);
636 TailCallBuiltin(masm(), MissBuiltin(kind())); 641 TailCallBuiltin(masm(), MissBuiltin(kind()));
637 __ bind(&success); 642 __ bind(&success);
638 } 643 }
639 } 644 }
640 645
641 646
642 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { 647 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
643 // Return the constant value. 648 // Return the constant value.
644 __ Move(r0, value); 649 __ Move(r3, value);
645 __ Ret(); 650 __ Ret();
646 } 651 }
647 652
648 653
649 void NamedLoadHandlerCompiler::GenerateLoadCallback( 654 void NamedLoadHandlerCompiler::GenerateLoadCallback(
650 Register reg, Handle<ExecutableAccessorInfo> callback) { 655 Register reg, Handle<ExecutableAccessorInfo> callback) {
651 // Build AccessorInfo::args_ list on the stack and push property name below 656 // Build AccessorInfo::args_ list on the stack and push property name below
652 // the exit frame to make GC aware of them and store pointers to them. 657 // the exit frame to make GC aware of them and store pointers to them.
653 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); 658 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
654 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); 659 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
655 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); 660 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
656 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); 661 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
657 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4); 662 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
658 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5); 663 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
659 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6); 664 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
660 DCHECK(!scratch2().is(reg)); 665 DCHECK(!scratch2().is(reg));
661 DCHECK(!scratch3().is(reg)); 666 DCHECK(!scratch3().is(reg));
662 DCHECK(!scratch4().is(reg)); 667 DCHECK(!scratch4().is(reg));
663 __ push(receiver()); 668 __ push(receiver());
664 if (heap()->InNewSpace(callback->data())) { 669 if (heap()->InNewSpace(callback->data())) {
665 __ Move(scratch3(), callback); 670 __ Move(scratch3(), callback);
666 __ ldr(scratch3(), 671 __ LoadP(scratch3(),
667 FieldMemOperand(scratch3(), ExecutableAccessorInfo::kDataOffset)); 672 FieldMemOperand(scratch3(), ExecutableAccessorInfo::kDataOffset));
668 } else { 673 } else {
669 __ Move(scratch3(), Handle<Object>(callback->data(), isolate())); 674 __ Move(scratch3(), Handle<Object>(callback->data(), isolate()));
670 } 675 }
671 __ push(scratch3()); 676 __ push(scratch3());
672 __ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex); 677 __ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex);
673 __ mov(scratch4(), scratch3()); 678 __ mr(scratch4(), scratch3());
674 __ Push(scratch3(), scratch4()); 679 __ Push(scratch3(), scratch4());
675 __ mov(scratch4(), Operand(ExternalReference::isolate_address(isolate()))); 680 __ mov(scratch4(), Operand(ExternalReference::isolate_address(isolate())));
676 __ Push(scratch4(), reg); 681 __ Push(scratch4(), reg);
677 __ mov(scratch2(), sp); // scratch2 = PropertyAccessorInfo::args_
678 __ push(name()); 682 __ push(name());
679 683
680 // Abi for CallApiGetter 684 // Abi for CallApiGetter
681 Register getter_address_reg = ApiGetterDescriptor::function_address(); 685 Register getter_address_reg = ApiGetterDescriptor::function_address();
682 686
683 Address getter_address = v8::ToCData<Address>(callback->getter()); 687 Address getter_address = v8::ToCData<Address>(callback->getter());
684 ApiFunction fun(getter_address); 688 ApiFunction fun(getter_address);
685 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; 689 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
686 ExternalReference ref = ExternalReference(&fun, type, isolate()); 690 ExternalReference ref = ExternalReference(&fun, type, isolate());
687 __ mov(getter_address_reg, Operand(ref)); 691 __ mov(getter_address_reg, Operand(ref));
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 // interceptor's holder has been compiled before (see a caller 728 // interceptor's holder has been compiled before (see a caller
725 // of this method.) 729 // of this method.)
726 CompileCallLoadPropertyWithInterceptor( 730 CompileCallLoadPropertyWithInterceptor(
727 masm(), receiver(), holder_reg, this->name(), holder(), 731 masm(), receiver(), holder_reg, this->name(), holder(),
728 IC::kLoadPropertyWithInterceptorOnly); 732 IC::kLoadPropertyWithInterceptorOnly);
729 733
730 // Check if interceptor provided a value for property. If it's 734 // Check if interceptor provided a value for property. If it's
731 // the case, return immediately. 735 // the case, return immediately.
732 Label interceptor_failed; 736 Label interceptor_failed;
733 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex); 737 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex);
734 __ cmp(r0, scratch1()); 738 __ cmp(r3, scratch1());
735 __ b(eq, &interceptor_failed); 739 __ beq(&interceptor_failed);
736 frame_scope.GenerateLeaveFrame(); 740 frame_scope.GenerateLeaveFrame();
737 __ Ret(); 741 __ Ret();
738 742
739 __ bind(&interceptor_failed); 743 __ bind(&interceptor_failed);
740 __ pop(this->name()); 744 __ pop(this->name());
741 __ pop(holder_reg); 745 __ pop(holder_reg);
742 if (must_preserve_receiver_reg) { 746 if (must_preserve_receiver_reg) {
743 __ pop(receiver()); 747 __ pop(receiver());
744 } 748 }
745 // Leave the internal frame. 749 // Leave the internal frame.
(...skipping 15 matching lines...) Expand all
761 __ TailCallExternalReference( 765 __ TailCallExternalReference(
762 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); 766 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
763 } 767 }
764 768
765 769
766 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 770 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
767 Handle<JSObject> object, Handle<Name> name, 771 Handle<JSObject> object, Handle<Name> name,
768 Handle<ExecutableAccessorInfo> callback) { 772 Handle<ExecutableAccessorInfo> callback) {
769 Register holder_reg = Frontend(receiver(), name); 773 Register holder_reg = Frontend(receiver(), name);
770 774
771 __ push(receiver()); // receiver 775 __ Push(receiver(), holder_reg); // receiver
772 __ push(holder_reg); 776 __ mov(ip, Operand(callback)); // callback info
773 __ mov(ip, Operand(callback)); // callback info
774 __ push(ip); 777 __ push(ip);
775 __ mov(ip, Operand(name)); 778 __ mov(ip, Operand(name));
776 __ Push(ip, value()); 779 __ Push(ip, value());
777 780
778 // Do tail-call to the runtime system. 781 // Do tail-call to the runtime system.
779 ExternalReference store_callback_property = 782 ExternalReference store_callback_property =
780 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 783 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
781 __ TailCallExternalReference(store_callback_property, 5, 1); 784 __ TailCallExternalReference(store_callback_property, 5, 1);
782 785
783 // Return the generated code. 786 // Return the generated code.
(...skipping 21 matching lines...) Expand all
805 808
806 809
807 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 810 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
808 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { 811 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
809 Label miss; 812 Label miss;
810 FrontendHeader(receiver(), name, &miss); 813 FrontendHeader(receiver(), name, &miss);
811 814
812 // Get the value from the cell. 815 // Get the value from the cell.
813 Register result = StoreDescriptor::ValueRegister(); 816 Register result = StoreDescriptor::ValueRegister();
814 __ mov(result, Operand(cell)); 817 __ mov(result, Operand(cell));
815 __ ldr(result, FieldMemOperand(result, Cell::kValueOffset)); 818 __ LoadP(result, FieldMemOperand(result, Cell::kValueOffset));
816 819
817 // Check for deleted property if property can actually be deleted. 820 // Check for deleted property if property can actually be deleted.
818 if (is_configurable) { 821 if (!is_configurable) {
819 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 822 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
820 __ cmp(result, ip); 823 __ cmp(result, ip);
821 __ b(eq, &miss); 824 __ beq(&miss);
822 } 825 }
823 826
824 Counters* counters = isolate()->counters(); 827 Counters* counters = isolate()->counters();
825 __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3); 828 __ IncrementCounter(counters->named_load_global_stub(), 1, r4, r6);
826 __ Ret(); 829 __ Ret();
827 830
828 FrontendFooter(name, &miss); 831 FrontendFooter(name, &miss);
829 832
830 // Return the generated code. 833 // Return the generated code.
831 return GetCode(kind(), Code::NORMAL, name); 834 return GetCode(kind(), Code::NORMAL, name);
832 } 835 }
833 836
834 837
835 #undef __ 838 #undef __
836 } 839 }
837 } // namespace v8::internal 840 } // namespace v8::internal
838 841
839 #endif // V8_TARGET_ARCH_ARM 842 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698