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

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: Address comments Created 6 years, 1 month 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
« no previous file with comments | « src/ic/ppc/access-compiler-ppc.cc ('k') | src/ic/ppc/ic-compiler-ppc.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 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 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_ARM 7 #if V8_TARGET_ARCH_PPC
8 8
9 #include "src/ic/call-optimization.h" 9 #include "src/ic/call-optimization.h"
10 #include "src/ic/handler-compiler.h" 10 #include "src/ic/handler-compiler.h"
11 #include "src/ic/ic.h" 11 #include "src/ic/ic.h"
12 12
13 namespace v8 { 13 namespace v8 {
14 namespace internal { 14 namespace internal {
15 15
16 #define __ ACCESS_MASM(masm) 16 #define __ ACCESS_MASM(masm)
17 17
18 18
19 void NamedLoadHandlerCompiler::GenerateLoadViaGetter( 19 void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
20 MacroAssembler* masm, Handle<HeapType> type, Register receiver, 20 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
21 Handle<JSFunction> getter) { 21 Handle<JSFunction> getter) {
22 // ----------- S t a t e ------------- 22 // ----------- S t a t e -------------
23 // -- r0 : receiver 23 // -- r3 : receiver
24 // -- r2 : name 24 // -- r5 : name
25 // -- lr : return address 25 // -- lr : return address
26 // ----------------------------------- 26 // -----------------------------------
27 { 27 {
28 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); 28 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
29 29
30 if (!getter.is_null()) { 30 if (!getter.is_null()) {
31 // Call the JavaScript getter with the receiver on the stack. 31 // Call the JavaScript getter with the receiver on the stack.
32 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { 32 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
33 // Swap in the global receiver. 33 // Swap in the global receiver.
34 __ ldr(receiver, 34 __ LoadP(receiver,
35 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); 35 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
36 } 36 }
37 __ push(receiver); 37 __ push(receiver);
38 ParameterCount actual(0); 38 ParameterCount actual(0);
39 ParameterCount expected(getter); 39 ParameterCount expected(getter);
40 __ InvokeFunction(getter, expected, actual, CALL_FUNCTION, 40 __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
41 NullCallWrapper()); 41 NullCallWrapper());
42 } else { 42 } else {
43 // If we generate a global code snippet for deoptimization only, remember 43 // If we generate a global code snippet for deoptimization only, remember
44 // the place to continue after deoptimization. 44 // the place to continue after deoptimization.
45 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset()); 45 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
46 } 46 }
47 47
48 // Restore context register. 48 // Restore context register.
49 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 49 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
50 } 50 }
51 __ Ret(); 51 __ Ret();
52 } 52 }
53 53
54 54
55 void NamedStoreHandlerCompiler::GenerateStoreViaSetter( 55 void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
56 MacroAssembler* masm, Handle<HeapType> type, Register receiver, 56 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
57 Handle<JSFunction> setter) { 57 Handle<JSFunction> setter) {
58 // ----------- S t a t e ------------- 58 // ----------- S t a t e -------------
59 // -- lr : return address 59 // -- lr : return address
60 // ----------------------------------- 60 // -----------------------------------
61 { 61 {
62 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); 62 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
63 63
64 // Save value register, so we can restore it later. 64 // Save value register, so we can restore it later.
65 __ push(value()); 65 __ push(value());
66 66
67 if (!setter.is_null()) { 67 if (!setter.is_null()) {
68 // Call the JavaScript setter with receiver and value on the stack. 68 // Call the JavaScript setter with receiver and value on the stack.
69 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { 69 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
70 // Swap in the global receiver. 70 // Swap in the global receiver.
71 __ ldr(receiver, 71 __ LoadP(receiver,
72 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); 72 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
73 } 73 }
74 __ Push(receiver, value()); 74 __ Push(receiver, value());
75 ParameterCount actual(1); 75 ParameterCount actual(1);
76 ParameterCount expected(setter); 76 ParameterCount expected(setter);
77 __ InvokeFunction(setter, expected, actual, CALL_FUNCTION, 77 __ InvokeFunction(setter, expected, actual, CALL_FUNCTION,
78 NullCallWrapper()); 78 NullCallWrapper());
79 } else { 79 } else {
80 // If we generate a global code snippet for deoptimization only, remember 80 // If we generate a global code snippet for deoptimization only, remember
81 // the place to continue after deoptimization. 81 // the place to continue after deoptimization.
82 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); 82 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
83 } 83 }
84 84
85 // We have to return the passed value, not the return value of the setter. 85 // We have to return the passed value, not the return value of the setter.
86 __ pop(r0); 86 __ pop(r3);
87 87
88 // Restore context register. 88 // Restore context register.
89 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 89 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
90 } 90 }
91 __ Ret(); 91 __ Ret();
92 } 92 }
93 93
94 94
95 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( 95 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
96 MacroAssembler* masm, Label* miss_label, Register receiver, 96 MacroAssembler* masm, Label* miss_label, Register receiver,
97 Handle<Name> name, Register scratch0, Register scratch1) { 97 Handle<Name> name, Register scratch0, Register scratch1) {
98 DCHECK(name->IsUniqueName()); 98 DCHECK(name->IsUniqueName());
99 DCHECK(!receiver.is(scratch0)); 99 DCHECK(!receiver.is(scratch0));
100 Counters* counters = masm->isolate()->counters(); 100 Counters* counters = masm->isolate()->counters();
101 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); 101 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
102 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 102 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
103 103
104 Label done; 104 Label done;
105 105
106 const int kInterceptorOrAccessCheckNeededMask = 106 const int kInterceptorOrAccessCheckNeededMask =
107 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); 107 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
108 108
109 // Bail out if the receiver has a named interceptor or requires access checks. 109 // Bail out if the receiver has a named interceptor or requires access checks.
110 Register map = scratch1; 110 Register map = scratch1;
111 __ ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); 111 __ LoadP(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
112 __ ldrb(scratch0, FieldMemOperand(map, Map::kBitFieldOffset)); 112 __ lbz(scratch0, FieldMemOperand(map, Map::kBitFieldOffset));
113 __ tst(scratch0, Operand(kInterceptorOrAccessCheckNeededMask)); 113 __ andi(r0, scratch0, Operand(kInterceptorOrAccessCheckNeededMask));
114 __ b(ne, miss_label); 114 __ bne(miss_label, cr0);
115 115
116 // Check that receiver is a JSObject. 116 // Check that receiver is a JSObject.
117 __ ldrb(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset)); 117 __ lbz(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset));
118 __ cmp(scratch0, Operand(FIRST_SPEC_OBJECT_TYPE)); 118 __ cmpi(scratch0, Operand(FIRST_SPEC_OBJECT_TYPE));
119 __ b(lt, miss_label); 119 __ blt(miss_label);
120 120
121 // Load properties array. 121 // Load properties array.
122 Register properties = scratch0; 122 Register properties = scratch0;
123 __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 123 __ LoadP(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
124 // Check that the properties array is a dictionary. 124 // Check that the properties array is a dictionary.
125 __ ldr(map, FieldMemOperand(properties, HeapObject::kMapOffset)); 125 __ LoadP(map, FieldMemOperand(properties, HeapObject::kMapOffset));
126 Register tmp = properties; 126 Register tmp = properties;
127 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); 127 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex);
128 __ cmp(map, tmp); 128 __ cmp(map, tmp);
129 __ b(ne, miss_label); 129 __ bne(miss_label);
130 130
131 // Restore the temporarily used register. 131 // Restore the temporarily used register.
132 __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 132 __ LoadP(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
133 133
134 134
135 NameDictionaryLookupStub::GenerateNegativeLookup( 135 NameDictionaryLookupStub::GenerateNegativeLookup(
136 masm, miss_label, &done, receiver, properties, name, scratch1); 136 masm, miss_label, &done, receiver, properties, name, scratch1);
137 __ bind(&done); 137 __ bind(&done);
138 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 138 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
139 } 139 }
140 140
141 141
142 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype( 142 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
143 MacroAssembler* masm, int index, Register prototype, Label* miss) { 143 MacroAssembler* masm, int index, Register prototype, Label* miss) {
144 Isolate* isolate = masm->isolate(); 144 Isolate* isolate = masm->isolate();
145 // Get the global function with the given index. 145 // Get the global function with the given index.
146 Handle<JSFunction> function( 146 Handle<JSFunction> function(
147 JSFunction::cast(isolate->native_context()->get(index))); 147 JSFunction::cast(isolate->native_context()->get(index)));
148 148
149 // Check we're still in the same context. 149 // Check we're still in the same context.
150 Register scratch = prototype; 150 Register scratch = prototype;
151 const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX); 151 const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX);
152 __ ldr(scratch, MemOperand(cp, offset)); 152 __ LoadP(scratch, MemOperand(cp, offset));
153 __ ldr(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset)); 153 __ LoadP(scratch,
154 __ ldr(scratch, MemOperand(scratch, Context::SlotOffset(index))); 154 FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
155 __ LoadP(scratch, MemOperand(scratch, Context::SlotOffset(index)));
155 __ Move(ip, function); 156 __ Move(ip, function);
156 __ cmp(ip, scratch); 157 __ cmp(ip, scratch);
157 __ b(ne, miss); 158 __ bne(miss);
158 159
159 // Load its initial map. The global functions all have initial maps. 160 // Load its initial map. The global functions all have initial maps.
160 __ Move(prototype, Handle<Map>(function->initial_map())); 161 __ Move(prototype, Handle<Map>(function->initial_map()));
161 // Load the prototype from the initial map. 162 // Load the prototype from the initial map.
162 __ ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); 163 __ LoadP(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
163 } 164 }
164 165
165 166
166 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype( 167 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
167 MacroAssembler* masm, Register receiver, Register scratch1, 168 MacroAssembler* masm, Register receiver, Register scratch1,
168 Register scratch2, Label* miss_label) { 169 Register scratch2, Label* miss_label) {
169 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); 170 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
170 __ mov(r0, scratch1); 171 __ mr(r3, scratch1);
171 __ Ret(); 172 __ Ret();
172 } 173 }
173 174
174 175
175 // Generate code to check that a global property cell is empty. Create 176 // Generate code to check that a global property cell is empty. Create
176 // the property cell at compilation time if no cell exists for the 177 // the property cell at compilation time if no cell exists for the
177 // property. 178 // property.
178 void PropertyHandlerCompiler::GenerateCheckPropertyCell( 179 void PropertyHandlerCompiler::GenerateCheckPropertyCell(
179 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name, 180 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
180 Register scratch, Label* miss) { 181 Register scratch, Label* miss) {
181 Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name); 182 Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
182 DCHECK(cell->value()->IsTheHole()); 183 DCHECK(cell->value()->IsTheHole());
183 __ mov(scratch, Operand(cell)); 184 __ mov(scratch, Operand(cell));
184 __ ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); 185 __ LoadP(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
185 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 186 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
186 __ cmp(scratch, ip); 187 __ cmp(scratch, ip);
187 __ b(ne, miss); 188 __ bne(miss);
188 } 189 }
189 190
190 191
191 static void PushInterceptorArguments(MacroAssembler* masm, Register receiver, 192 static void PushInterceptorArguments(MacroAssembler* masm, Register receiver,
192 Register holder, Register name, 193 Register holder, Register name,
193 Handle<JSObject> holder_obj) { 194 Handle<JSObject> holder_obj) {
194 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0); 195 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
195 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1); 196 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1);
196 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2); 197 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2);
197 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3); 198 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3);
(...skipping 28 matching lines...) Expand all
226 // Write the arguments to stack frame. 227 // Write the arguments to stack frame.
227 for (int i = 0; i < argc; i++) { 228 for (int i = 0; i < argc; i++) {
228 Register arg = values[argc - 1 - i]; 229 Register arg = values[argc - 1 - i];
229 DCHECK(!receiver.is(arg)); 230 DCHECK(!receiver.is(arg));
230 DCHECK(!scratch_in.is(arg)); 231 DCHECK(!scratch_in.is(arg));
231 __ push(arg); 232 __ push(arg);
232 } 233 }
233 DCHECK(optimization.is_simple_api_call()); 234 DCHECK(optimization.is_simple_api_call());
234 235
235 // Abi for CallApiFunctionStub. 236 // Abi for CallApiFunctionStub.
236 Register callee = r0; 237 Register callee = r3;
237 Register call_data = r4; 238 Register call_data = r7;
238 Register holder = r2; 239 Register holder = r5;
239 Register api_function_address = r1; 240 Register api_function_address = r4;
240 241
241 // Put holder in place. 242 // Put holder in place.
242 CallOptimization::HolderLookup holder_lookup; 243 CallOptimization::HolderLookup holder_lookup;
243 Handle<JSObject> api_holder = 244 Handle<JSObject> api_holder =
244 optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup); 245 optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
245 switch (holder_lookup) { 246 switch (holder_lookup) {
246 case CallOptimization::kHolderIsReceiver: 247 case CallOptimization::kHolderIsReceiver:
247 __ Move(holder, receiver); 248 __ Move(holder, receiver);
248 break; 249 break;
249 case CallOptimization::kHolderFound: 250 case CallOptimization::kHolderFound:
250 __ Move(holder, api_holder); 251 __ Move(holder, api_holder);
251 break; 252 break;
252 case CallOptimization::kHolderNotFound: 253 case CallOptimization::kHolderNotFound:
253 UNREACHABLE(); 254 UNREACHABLE();
254 break; 255 break;
255 } 256 }
256 257
257 Isolate* isolate = masm->isolate(); 258 Isolate* isolate = masm->isolate();
258 Handle<JSFunction> function = optimization.constant_function(); 259 Handle<JSFunction> function = optimization.constant_function();
259 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 260 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
260 Handle<Object> call_data_obj(api_call_info->data(), isolate); 261 Handle<Object> call_data_obj(api_call_info->data(), isolate);
261 262
262 // Put callee in place. 263 // Put callee in place.
263 __ Move(callee, function); 264 __ Move(callee, function);
264 265
265 bool call_data_undefined = false; 266 bool call_data_undefined = false;
266 // Put call_data in place. 267 // Put call_data in place.
267 if (isolate->heap()->InNewSpace(*call_data_obj)) { 268 if (isolate->heap()->InNewSpace(*call_data_obj)) {
268 __ Move(call_data, api_call_info); 269 __ Move(call_data, api_call_info);
269 __ ldr(call_data, FieldMemOperand(call_data, CallHandlerInfo::kDataOffset)); 270 __ LoadP(call_data,
271 FieldMemOperand(call_data, CallHandlerInfo::kDataOffset));
270 } else if (call_data_obj->IsUndefined()) { 272 } else if (call_data_obj->IsUndefined()) {
271 call_data_undefined = true; 273 call_data_undefined = true;
272 __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex); 274 __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
273 } else { 275 } else {
274 __ Move(call_data, call_data_obj); 276 __ Move(call_data, call_data_obj);
275 } 277 }
276 278
277 // Put api_function_address in place. 279 // Put api_function_address in place.
278 Address function_address = v8::ToCData<Address>(api_call_info->callback()); 280 Address function_address = v8::ToCData<Address>(api_call_info->callback());
279 ApiFunction fun(function_address); 281 ApiFunction fun(function_address);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 __ mov(this->name(), Operand(name)); 333 __ mov(this->name(), Operand(name));
332 __ mov(StoreTransitionDescriptor::MapRegister(), Operand(transition)); 334 __ mov(StoreTransitionDescriptor::MapRegister(), Operand(transition));
333 } 335 }
334 336
335 337
336 void NamedStoreHandlerCompiler::GenerateConstantCheck(Object* constant, 338 void NamedStoreHandlerCompiler::GenerateConstantCheck(Object* constant,
337 Register value_reg, 339 Register value_reg,
338 Label* miss_label) { 340 Label* miss_label) {
339 __ Move(scratch1(), handle(constant, isolate())); 341 __ Move(scratch1(), handle(constant, isolate()));
340 __ cmp(value_reg, scratch1()); 342 __ cmp(value_reg, scratch1());
341 __ b(ne, miss_label); 343 __ bne(miss_label);
342 } 344 }
343 345
344 346
345 void NamedStoreHandlerCompiler::GenerateFieldTypeChecks(HeapType* field_type, 347 void NamedStoreHandlerCompiler::GenerateFieldTypeChecks(HeapType* field_type,
346 Register value_reg, 348 Register value_reg,
347 Label* miss_label) { 349 Label* miss_label) {
348 __ JumpIfSmi(value_reg, miss_label); 350 __ JumpIfSmi(value_reg, miss_label);
349 HeapType::Iterator<Map> it = field_type->Classes(); 351 HeapType::Iterator<Map> it = field_type->Classes();
350 if (!it.Done()) { 352 if (!it.Done()) {
351 __ ldr(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset)); 353 __ LoadP(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset));
352 Label do_store; 354 Label do_store;
353 while (true) { 355 while (true) {
354 __ CompareMap(scratch1(), it.Current(), &do_store); 356 __ CompareMap(scratch1(), it.Current(), &do_store);
355 it.Advance(); 357 it.Advance();
356 if (it.Done()) { 358 if (it.Done()) {
357 __ b(ne, miss_label); 359 __ bne(miss_label);
358 break; 360 break;
359 } 361 }
360 __ b(eq, &do_store); 362 __ beq(&do_store);
361 } 363 }
362 __ bind(&do_store); 364 __ bind(&do_store);
363 } 365 }
364 } 366 }
365 367
366 368
367 Register PropertyHandlerCompiler::CheckPrototypes( 369 Register PropertyHandlerCompiler::CheckPrototypes(
368 Register object_reg, Register holder_reg, Register scratch1, 370 Register object_reg, Register holder_reg, Register scratch1,
369 Register scratch2, Handle<Name> name, Label* miss, 371 Register scratch2, Handle<Name> name, Label* miss,
370 PrototypeCheckType check) { 372 PrototypeCheckType check) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 DCHECK(name->IsString()); 406 DCHECK(name->IsString());
405 name = factory()->InternalizeString(Handle<String>::cast(name)); 407 name = factory()->InternalizeString(Handle<String>::cast(name));
406 } 408 }
407 DCHECK(current.is_null() || 409 DCHECK(current.is_null() ||
408 current->property_dictionary()->FindEntry(name) == 410 current->property_dictionary()->FindEntry(name) ==
409 NameDictionary::kNotFound); 411 NameDictionary::kNotFound);
410 412
411 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1, 413 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
412 scratch2); 414 scratch2);
413 415
414 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); 416 __ LoadP(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
415 reg = holder_reg; // From now on the object will be in holder_reg. 417 reg = holder_reg; // From now on the object will be in holder_reg.
416 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); 418 __ LoadP(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
417 } else { 419 } else {
418 Register map_reg = scratch1; 420 Register map_reg = scratch1;
419 if (depth != 1 || check == CHECK_ALL_MAPS) { 421 if (depth != 1 || check == CHECK_ALL_MAPS) {
420 // CheckMap implicitly loads the map of |reg| into |map_reg|. 422 // CheckMap implicitly loads the map of |reg| into |map_reg|.
421 __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK); 423 __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK);
422 } else { 424 } else {
423 __ ldr(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); 425 __ LoadP(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
424 } 426 }
425 427
426 // Check access rights to the global object. This has to happen after 428 // Check access rights to the global object. This has to happen after
427 // the map check so that we know that the object is actually a global 429 // the map check so that we know that the object is actually a global
428 // object. 430 // object.
429 // This allows us to install generated handlers for accesses to the 431 // This allows us to install generated handlers for accesses to the
430 // global proxy (as opposed to using slow ICs). See corresponding code 432 // global proxy (as opposed to using slow ICs). See corresponding code
431 // in LookupForRead(). 433 // in LookupForRead().
432 if (current_map->IsJSGlobalProxyMap()) { 434 if (current_map->IsJSGlobalProxyMap()) {
433 __ CheckAccessGlobalProxy(reg, scratch2, miss); 435 __ CheckAccessGlobalProxy(reg, scratch2, miss);
434 } else if (current_map->IsJSGlobalObjectMap()) { 436 } else if (current_map->IsJSGlobalObjectMap()) {
435 GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current), 437 GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
436 name, scratch2, miss); 438 name, scratch2, miss);
437 } 439 }
438 440
439 reg = holder_reg; // From now on the object will be in holder_reg. 441 reg = holder_reg; // From now on the object will be in holder_reg.
440 442
441 // Two possible reasons for loading the prototype from the map: 443 // Two possible reasons for loading the prototype from the map:
442 // (1) Can't store references to new space in code. 444 // (1) Can't store references to new space in code.
443 // (2) Handler is shared for all receivers with the same prototype 445 // (2) Handler is shared for all receivers with the same prototype
444 // map (but not necessarily the same prototype instance). 446 // map (but not necessarily the same prototype instance).
445 bool load_prototype_from_map = 447 bool load_prototype_from_map =
446 heap()->InNewSpace(*prototype) || depth == 1; 448 heap()->InNewSpace(*prototype) || depth == 1;
447 if (load_prototype_from_map) { 449 if (load_prototype_from_map) {
448 __ ldr(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset)); 450 __ LoadP(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
449 } else { 451 } else {
450 __ mov(reg, Operand(prototype)); 452 __ mov(reg, Operand(prototype));
451 } 453 }
452 } 454 }
453 455
454 // Go to the next object in the prototype chain. 456 // Go to the next object in the prototype chain.
455 current = prototype; 457 current = prototype;
456 current_map = handle(current->map()); 458 current_map = handle(current->map());
457 } 459 }
458 460
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 __ b(&success); 495 __ b(&success);
494 GenerateRestoreName(miss, name); 496 GenerateRestoreName(miss, name);
495 TailCallBuiltin(masm(), MissBuiltin(kind())); 497 TailCallBuiltin(masm(), MissBuiltin(kind()));
496 __ bind(&success); 498 __ bind(&success);
497 } 499 }
498 } 500 }
499 501
500 502
501 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { 503 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
502 // Return the constant value. 504 // Return the constant value.
503 __ Move(r0, value); 505 __ Move(r3, value);
504 __ Ret(); 506 __ Ret();
505 } 507 }
506 508
507 509
508 void NamedLoadHandlerCompiler::GenerateLoadCallback( 510 void NamedLoadHandlerCompiler::GenerateLoadCallback(
509 Register reg, Handle<ExecutableAccessorInfo> callback) { 511 Register reg, Handle<ExecutableAccessorInfo> callback) {
510 // Build AccessorInfo::args_ list on the stack and push property name below 512 // Build AccessorInfo::args_ list on the stack and push property name below
511 // the exit frame to make GC aware of them and store pointers to them. 513 // the exit frame to make GC aware of them and store pointers to them.
512 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); 514 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
513 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); 515 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
514 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); 516 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
515 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); 517 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
516 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4); 518 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
517 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5); 519 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
518 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6); 520 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
519 DCHECK(!scratch2().is(reg)); 521 DCHECK(!scratch2().is(reg));
520 DCHECK(!scratch3().is(reg)); 522 DCHECK(!scratch3().is(reg));
521 DCHECK(!scratch4().is(reg)); 523 DCHECK(!scratch4().is(reg));
522 __ push(receiver()); 524 __ push(receiver());
523 if (heap()->InNewSpace(callback->data())) { 525 if (heap()->InNewSpace(callback->data())) {
524 __ Move(scratch3(), callback); 526 __ Move(scratch3(), callback);
525 __ ldr(scratch3(), 527 __ LoadP(scratch3(),
526 FieldMemOperand(scratch3(), ExecutableAccessorInfo::kDataOffset)); 528 FieldMemOperand(scratch3(), ExecutableAccessorInfo::kDataOffset));
527 } else { 529 } else {
528 __ Move(scratch3(), Handle<Object>(callback->data(), isolate())); 530 __ Move(scratch3(), Handle<Object>(callback->data(), isolate()));
529 } 531 }
530 __ push(scratch3()); 532 __ push(scratch3());
531 __ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex); 533 __ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex);
532 __ mov(scratch4(), scratch3()); 534 __ mr(scratch4(), scratch3());
533 __ Push(scratch3(), scratch4()); 535 __ Push(scratch3(), scratch4());
534 __ mov(scratch4(), Operand(ExternalReference::isolate_address(isolate()))); 536 __ mov(scratch4(), Operand(ExternalReference::isolate_address(isolate())));
535 __ Push(scratch4(), reg); 537 __ Push(scratch4(), reg);
536 __ mov(scratch2(), sp); // scratch2 = PropertyAccessorInfo::args_
537 __ push(name()); 538 __ push(name());
538 539
539 // Abi for CallApiGetter 540 // Abi for CallApiGetter
540 Register getter_address_reg = ApiGetterDescriptor::function_address(); 541 Register getter_address_reg = ApiGetterDescriptor::function_address();
541 542
542 Address getter_address = v8::ToCData<Address>(callback->getter()); 543 Address getter_address = v8::ToCData<Address>(callback->getter());
543 ApiFunction fun(getter_address); 544 ApiFunction fun(getter_address);
544 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; 545 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
545 ExternalReference ref = ExternalReference(&fun, type, isolate()); 546 ExternalReference ref = ExternalReference(&fun, type, isolate());
546 __ mov(getter_address_reg, Operand(ref)); 547 __ mov(getter_address_reg, Operand(ref));
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 // interceptor's holder has been compiled before (see a caller 584 // interceptor's holder has been compiled before (see a caller
584 // of this method.) 585 // of this method.)
585 CompileCallLoadPropertyWithInterceptor( 586 CompileCallLoadPropertyWithInterceptor(
586 masm(), receiver(), holder_reg, this->name(), holder(), 587 masm(), receiver(), holder_reg, this->name(), holder(),
587 IC::kLoadPropertyWithInterceptorOnly); 588 IC::kLoadPropertyWithInterceptorOnly);
588 589
589 // Check if interceptor provided a value for property. If it's 590 // Check if interceptor provided a value for property. If it's
590 // the case, return immediately. 591 // the case, return immediately.
591 Label interceptor_failed; 592 Label interceptor_failed;
592 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex); 593 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex);
593 __ cmp(r0, scratch1()); 594 __ cmp(r3, scratch1());
594 __ b(eq, &interceptor_failed); 595 __ beq(&interceptor_failed);
595 frame_scope.GenerateLeaveFrame(); 596 frame_scope.GenerateLeaveFrame();
596 __ Ret(); 597 __ Ret();
597 598
598 __ bind(&interceptor_failed); 599 __ bind(&interceptor_failed);
599 __ pop(this->name()); 600 __ pop(this->name());
600 __ pop(holder_reg); 601 __ pop(holder_reg);
601 if (must_preserve_receiver_reg) { 602 if (must_preserve_receiver_reg) {
602 __ pop(receiver()); 603 __ pop(receiver());
603 } 604 }
604 // Leave the internal frame. 605 // Leave the internal frame.
(...skipping 15 matching lines...) Expand all
620 __ TailCallExternalReference( 621 __ TailCallExternalReference(
621 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); 622 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
622 } 623 }
623 624
624 625
625 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 626 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
626 Handle<JSObject> object, Handle<Name> name, 627 Handle<JSObject> object, Handle<Name> name,
627 Handle<ExecutableAccessorInfo> callback) { 628 Handle<ExecutableAccessorInfo> callback) {
628 Register holder_reg = Frontend(receiver(), name); 629 Register holder_reg = Frontend(receiver(), name);
629 630
630 __ push(receiver()); // receiver 631 __ Push(receiver(), holder_reg); // receiver
631 __ push(holder_reg); 632 __ mov(ip, Operand(callback)); // callback info
632 __ mov(ip, Operand(callback)); // callback info
633 __ push(ip); 633 __ push(ip);
634 __ mov(ip, Operand(name)); 634 __ mov(ip, Operand(name));
635 __ Push(ip, value()); 635 __ Push(ip, value());
636 636
637 // Do tail-call to the runtime system. 637 // Do tail-call to the runtime system.
638 ExternalReference store_callback_property = 638 ExternalReference store_callback_property =
639 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 639 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
640 __ TailCallExternalReference(store_callback_property, 5, 1); 640 __ TailCallExternalReference(store_callback_property, 5, 1);
641 641
642 // Return the generated code. 642 // Return the generated code.
(...skipping 21 matching lines...) Expand all
664 664
665 665
666 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 666 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
667 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { 667 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
668 Label miss; 668 Label miss;
669 FrontendHeader(receiver(), name, &miss); 669 FrontendHeader(receiver(), name, &miss);
670 670
671 // Get the value from the cell. 671 // Get the value from the cell.
672 Register result = StoreDescriptor::ValueRegister(); 672 Register result = StoreDescriptor::ValueRegister();
673 __ mov(result, Operand(cell)); 673 __ mov(result, Operand(cell));
674 __ ldr(result, FieldMemOperand(result, Cell::kValueOffset)); 674 __ LoadP(result, FieldMemOperand(result, Cell::kValueOffset));
675 675
676 // Check for deleted property if property can actually be deleted. 676 // Check for deleted property if property can actually be deleted.
677 if (is_configurable) { 677 if (is_configurable) {
678 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 678 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
679 __ cmp(result, ip); 679 __ cmp(result, ip);
680 __ b(eq, &miss); 680 __ beq(&miss);
681 } 681 }
682 682
683 Counters* counters = isolate()->counters(); 683 Counters* counters = isolate()->counters();
684 __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3); 684 __ IncrementCounter(counters->named_load_global_stub(), 1, r4, r6);
685 __ Ret(); 685 __ Ret();
686 686
687 FrontendFooter(name, &miss); 687 FrontendFooter(name, &miss);
688 688
689 // Return the generated code. 689 // Return the generated code.
690 return GetCode(kind(), Code::NORMAL, name); 690 return GetCode(kind(), Code::NORMAL, name);
691 } 691 }
692 692
693 693
694 #undef __ 694 #undef __
695 } 695 }
696 } // namespace v8::internal 696 } // namespace v8::internal
697 697
698 #endif // V8_TARGET_ARCH_ARM 698 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/ic/ppc/access-compiler-ppc.cc ('k') | src/ic/ppc/ic-compiler-ppc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698