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

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

Issue 901083004: Contribution of PowerPC port (continuation of 422063005) - PPC dir update (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Contribution of PowerPC port (continuation of 422063005) - PPC dir update -comments and rebase Created 5 years, 10 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/compiler/ppc/linkage-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_PPC 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 Register holder, int accessor_index, int expected_arguments,
22 Register scratch) {
22 // ----------- S t a t e ------------- 23 // ----------- S t a t e -------------
23 // -- r3 : receiver 24 // -- r3 : receiver
24 // -- r5 : name 25 // -- r5 : name
25 // -- lr : return address 26 // -- lr : return address
26 // ----------------------------------- 27 // -----------------------------------
27 { 28 {
28 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); 29 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
29 30
30 if (!getter.is_null()) { 31 if (accessor_index >= 0) {
32 DCHECK(!holder.is(scratch));
33 DCHECK(!receiver.is(scratch));
31 // Call the JavaScript getter with the receiver on the stack. 34 // Call the JavaScript getter with the receiver on the stack.
32 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { 35 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
33 // Swap in the global receiver. 36 // Swap in the global receiver.
34 __ LoadP(receiver, 37 __ LoadP(scratch,
35 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); 38 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
39 receiver = scratch;
36 } 40 }
37 __ push(receiver); 41 __ push(receiver);
38 ParameterCount actual(0); 42 ParameterCount actual(0);
39 ParameterCount expected(getter); 43 ParameterCount expected(expected_arguments);
40 __ InvokeFunction(getter, expected, actual, CALL_FUNCTION, 44 __ LoadAccessor(r4, holder, accessor_index, ACCESSOR_GETTER);
41 NullCallWrapper()); 45 __ InvokeFunction(r4, expected, actual, CALL_FUNCTION, NullCallWrapper());
42 } else { 46 } else {
43 // If we generate a global code snippet for deoptimization only, remember 47 // If we generate a global code snippet for deoptimization only, remember
44 // the place to continue after deoptimization. 48 // the place to continue after deoptimization.
45 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset()); 49 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
46 } 50 }
47 51
48 // Restore context register. 52 // Restore context register.
49 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 53 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
50 } 54 }
51 __ Ret(); 55 __ Ret();
52 } 56 }
53 57
54 58
55 void NamedStoreHandlerCompiler::GenerateStoreViaSetter( 59 void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
56 MacroAssembler* masm, Handle<HeapType> type, Register receiver, 60 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
57 Handle<JSFunction> setter) { 61 Register holder, int accessor_index, int expected_arguments,
62 Register scratch) {
58 // ----------- S t a t e ------------- 63 // ----------- S t a t e -------------
59 // -- lr : return address 64 // -- lr : return address
60 // ----------------------------------- 65 // -----------------------------------
61 { 66 {
62 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); 67 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
63 68
64 // Save value register, so we can restore it later. 69 // Save value register, so we can restore it later.
65 __ push(value()); 70 __ push(value());
66 71
67 if (!setter.is_null()) { 72 if (accessor_index >= 0) {
73 DCHECK(!holder.is(scratch));
74 DCHECK(!receiver.is(scratch));
75 DCHECK(!value().is(scratch));
68 // Call the JavaScript setter with receiver and value on the stack. 76 // Call the JavaScript setter with receiver and value on the stack.
69 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { 77 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
70 // Swap in the global receiver. 78 // Swap in the global receiver.
71 __ LoadP(receiver, 79 __ LoadP(scratch,
72 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); 80 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
81 receiver = scratch;
73 } 82 }
74 __ Push(receiver, value()); 83 __ Push(receiver, value());
75 ParameterCount actual(1); 84 ParameterCount actual(1);
76 ParameterCount expected(setter); 85 ParameterCount expected(expected_arguments);
77 __ InvokeFunction(setter, expected, actual, CALL_FUNCTION, 86 __ LoadAccessor(r4, holder, accessor_index, ACCESSOR_SETTER);
78 NullCallWrapper()); 87 __ InvokeFunction(r4, expected, actual, CALL_FUNCTION, NullCallWrapper());
79 } else { 88 } else {
80 // If we generate a global code snippet for deoptimization only, remember 89 // If we generate a global code snippet for deoptimization only, remember
81 // the place to continue after deoptimization. 90 // the place to continue after deoptimization.
82 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); 91 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
83 } 92 }
84 93
85 // We have to return the passed value, not the return value of the setter. 94 // We have to return the passed value, not the return value of the setter.
86 __ pop(r3); 95 __ pop(r3);
87 96
88 // Restore context register. 97 // Restore context register.
89 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 98 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
90 } 99 }
91 __ Ret(); 100 __ Ret();
92 } 101 }
93 102
94 103
104 void PropertyHandlerCompiler::PushVectorAndSlot(Register vector,
105 Register slot) {
106 MacroAssembler* masm = this->masm();
107 __ Push(vector, slot);
108 }
109
110
111 void PropertyHandlerCompiler::PopVectorAndSlot(Register vector, Register slot) {
112 MacroAssembler* masm = this->masm();
113 __ Pop(vector, slot);
114 }
115
116
117 void PropertyHandlerCompiler::DiscardVectorAndSlot() {
118 MacroAssembler* masm = this->masm();
119 // Remove vector and slot.
120 __ addi(sp, sp, Operand(2 * kPointerSize));
121 }
122
123
95 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( 124 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
96 MacroAssembler* masm, Label* miss_label, Register receiver, 125 MacroAssembler* masm, Label* miss_label, Register receiver,
97 Handle<Name> name, Register scratch0, Register scratch1) { 126 Handle<Name> name, Register scratch0, Register scratch1) {
98 DCHECK(name->IsUniqueName()); 127 DCHECK(name->IsUniqueName());
99 DCHECK(!receiver.is(scratch0)); 128 DCHECK(!receiver.is(scratch0));
100 Counters* counters = masm->isolate()->counters(); 129 Counters* counters = masm->isolate()->counters();
101 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); 130 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
102 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 131 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
103 132
104 Label done; 133 Label done;
(...skipping 28 matching lines...) Expand all
133 162
134 163
135 NameDictionaryLookupStub::GenerateNegativeLookup( 164 NameDictionaryLookupStub::GenerateNegativeLookup(
136 masm, miss_label, &done, receiver, properties, name, scratch1); 165 masm, miss_label, &done, receiver, properties, name, scratch1);
137 __ bind(&done); 166 __ bind(&done);
138 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 167 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
139 } 168 }
140 169
141 170
142 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype( 171 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
143 MacroAssembler* masm, int index, Register prototype, Label* miss) { 172 MacroAssembler* masm, int index, Register result, Label* miss) {
144 Isolate* isolate = masm->isolate();
145 // Get the global function with the given index.
146 Handle<JSFunction> function(
147 JSFunction::cast(isolate->native_context()->get(index)));
148
149 // Check we're still in the same context.
150 Register scratch = prototype;
151 const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX); 173 const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX);
152 __ LoadP(scratch, MemOperand(cp, offset)); 174 __ LoadP(result, MemOperand(cp, offset));
153 __ LoadP(scratch, 175 __ LoadP(result, FieldMemOperand(result, GlobalObject::kNativeContextOffset));
154 FieldMemOperand(scratch, GlobalObject::kNativeContextOffset)); 176 __ LoadP(result, MemOperand(result, Context::SlotOffset(index)));
155 __ LoadP(scratch, MemOperand(scratch, Context::SlotOffset(index)));
156 __ Move(ip, function);
157 __ cmp(ip, scratch);
158 __ bne(miss);
159
160 // Load its initial map. The global functions all have initial maps. 177 // Load its initial map. The global functions all have initial maps.
161 __ Move(prototype, Handle<Map>(function->initial_map())); 178 __ LoadP(result,
179 FieldMemOperand(result, JSFunction::kPrototypeOrInitialMapOffset));
162 // Load the prototype from the initial map. 180 // Load the prototype from the initial map.
163 __ LoadP(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); 181 __ LoadP(result, FieldMemOperand(result, Map::kPrototypeOffset));
164 } 182 }
165 183
166 184
167 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype( 185 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
168 MacroAssembler* masm, Register receiver, Register scratch1, 186 MacroAssembler* masm, Register receiver, Register scratch1,
169 Register scratch2, Label* miss_label) { 187 Register scratch2, Label* miss_label) {
170 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); 188 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
171 __ mr(r3, scratch1); 189 __ mr(r3, scratch1);
172 __ Ret(); 190 __ Ret();
173 } 191 }
174 192
175 193
176 // Generate code to check that a global property cell is empty. Create 194 // Generate code to check that a global property cell is empty. Create
177 // the property cell at compilation time if no cell exists for the 195 // the property cell at compilation time if no cell exists for the
178 // property. 196 // property.
179 void PropertyHandlerCompiler::GenerateCheckPropertyCell( 197 void PropertyHandlerCompiler::GenerateCheckPropertyCell(
180 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name, 198 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
181 Register scratch, Label* miss) { 199 Register scratch, Label* miss) {
182 Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name); 200 Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
183 DCHECK(cell->value()->IsTheHole()); 201 DCHECK(cell->value()->IsTheHole());
184 __ mov(scratch, Operand(cell)); 202 Handle<WeakCell> weak_cell = masm->isolate()->factory()->NewWeakCell(cell);
203 __ LoadWeakValue(scratch, weak_cell, miss);
185 __ LoadP(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); 204 __ LoadP(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
186 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 205 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
187 __ cmp(scratch, ip); 206 __ cmp(scratch, ip);
188 __ bne(miss); 207 __ bne(miss);
189 } 208 }
190 209
191 210
192 static void PushInterceptorArguments(MacroAssembler* masm, Register receiver, 211 static void PushInterceptorArguments(MacroAssembler* masm, Register receiver,
193 Register holder, Register name, 212 Register holder, Register name,
194 Handle<JSObject> holder_obj) { 213 Handle<JSObject> holder_obj) {
195 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0); 214 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
196 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1); 215 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 1);
197 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2); 216 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 2);
198 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3); 217 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 3);
199 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4);
200 __ push(name); 218 __ push(name);
201 Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
202 DCHECK(!masm->isolate()->heap()->InNewSpace(*interceptor));
203 Register scratch = name;
204 __ mov(scratch, Operand(interceptor));
205 __ push(scratch);
206 __ push(receiver); 219 __ push(receiver);
207 __ push(holder); 220 __ push(holder);
208 } 221 }
209 222
210 223
211 static void CompileCallLoadPropertyWithInterceptor( 224 static void CompileCallLoadPropertyWithInterceptor(
212 MacroAssembler* masm, Register receiver, Register holder, Register name, 225 MacroAssembler* masm, Register receiver, Register holder, Register name,
213 Handle<JSObject> holder_obj, IC::UtilityId id) { 226 Handle<JSObject> holder_obj, IC::UtilityId id) {
214 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 227 PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
215 __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()), 228 __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()),
216 NamedLoadHandlerCompiler::kInterceptorArgsLength); 229 NamedLoadHandlerCompiler::kInterceptorArgsLength);
217 } 230 }
218 231
219 232
220 // Generate call to api function. 233 // Generate call to api function.
221 void PropertyHandlerCompiler::GenerateFastApiCall( 234 void PropertyHandlerCompiler::GenerateApiAccessorCall(
222 MacroAssembler* masm, const CallOptimization& optimization, 235 MacroAssembler* masm, const CallOptimization& optimization,
223 Handle<Map> receiver_map, Register receiver, Register scratch_in, 236 Handle<Map> receiver_map, Register receiver, Register scratch_in,
224 bool is_store, int argc, Register* values) { 237 bool is_store, Register store_parameter, Register accessor_holder,
238 int accessor_index) {
239 DCHECK(!accessor_holder.is(scratch_in));
225 DCHECK(!receiver.is(scratch_in)); 240 DCHECK(!receiver.is(scratch_in));
226 __ push(receiver); 241 __ push(receiver);
227 // Write the arguments to stack frame. 242 // Write the arguments to stack frame.
228 for (int i = 0; i < argc; i++) { 243 if (is_store) {
229 Register arg = values[argc - 1 - i]; 244 DCHECK(!receiver.is(store_parameter));
230 DCHECK(!receiver.is(arg)); 245 DCHECK(!scratch_in.is(store_parameter));
231 DCHECK(!scratch_in.is(arg)); 246 __ push(store_parameter);
232 __ push(arg);
233 } 247 }
234 DCHECK(optimization.is_simple_api_call()); 248 DCHECK(optimization.is_simple_api_call());
235 249
236 // Abi for CallApiFunctionStub. 250 // Abi for CallApiFunctionStub.
237 Register callee = r3; 251 Register callee = r3;
238 Register call_data = r7; 252 Register data = r7;
239 Register holder = r5; 253 Register holder = r5;
240 Register api_function_address = r4; 254 Register api_function_address = r4;
241 255
256 // Put callee in place.
257 __ LoadAccessor(callee, accessor_holder, accessor_index,
258 is_store ? ACCESSOR_SETTER : ACCESSOR_GETTER);
259
242 // Put holder in place. 260 // Put holder in place.
243 CallOptimization::HolderLookup holder_lookup; 261 CallOptimization::HolderLookup holder_lookup;
244 Handle<JSObject> api_holder = 262 int holder_depth = 0;
245 optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup); 263 optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup,
264 &holder_depth);
246 switch (holder_lookup) { 265 switch (holder_lookup) {
247 case CallOptimization::kHolderIsReceiver: 266 case CallOptimization::kHolderIsReceiver:
248 __ Move(holder, receiver); 267 __ Move(holder, receiver);
249 break; 268 break;
250 case CallOptimization::kHolderFound: 269 case CallOptimization::kHolderFound:
251 __ Move(holder, api_holder); 270 __ LoadP(holder, FieldMemOperand(receiver, HeapObject::kMapOffset));
271 __ LoadP(holder, FieldMemOperand(holder, Map::kPrototypeOffset));
272 for (int i = 1; i < holder_depth; i++) {
273 __ LoadP(holder, FieldMemOperand(holder, HeapObject::kMapOffset));
274 __ LoadP(holder, FieldMemOperand(holder, Map::kPrototypeOffset));
275 }
252 break; 276 break;
253 case CallOptimization::kHolderNotFound: 277 case CallOptimization::kHolderNotFound:
254 UNREACHABLE(); 278 UNREACHABLE();
255 break; 279 break;
256 } 280 }
257 281
258 Isolate* isolate = masm->isolate(); 282 Isolate* isolate = masm->isolate();
259 Handle<JSFunction> function = optimization.constant_function();
260 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 283 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
261 Handle<Object> call_data_obj(api_call_info->data(), isolate);
262
263 // Put callee in place.
264 __ Move(callee, function);
265
266 bool call_data_undefined = false; 284 bool call_data_undefined = false;
267 // Put call_data in place. 285 // Put call data in place.
268 if (isolate->heap()->InNewSpace(*call_data_obj)) { 286 if (api_call_info->data()->IsUndefined()) {
269 __ Move(call_data, api_call_info);
270 __ LoadP(call_data,
271 FieldMemOperand(call_data, CallHandlerInfo::kDataOffset));
272 } else if (call_data_obj->IsUndefined()) {
273 call_data_undefined = true; 287 call_data_undefined = true;
274 __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex); 288 __ LoadRoot(data, Heap::kUndefinedValueRootIndex);
275 } else { 289 } else {
276 __ Move(call_data, call_data_obj); 290 __ LoadP(data,
291 FieldMemOperand(callee, JSFunction::kSharedFunctionInfoOffset));
292 __ LoadP(data,
293 FieldMemOperand(data, SharedFunctionInfo::kFunctionDataOffset));
294 __ LoadP(data,
295 FieldMemOperand(data, FunctionTemplateInfo::kCallCodeOffset));
296 __ LoadP(data, FieldMemOperand(data, CallHandlerInfo::kDataOffset));
277 } 297 }
278 298
279 // Put api_function_address in place. 299 // Put api_function_address in place.
280 Address function_address = v8::ToCData<Address>(api_call_info->callback()); 300 Address function_address = v8::ToCData<Address>(api_call_info->callback());
281 ApiFunction fun(function_address); 301 ApiFunction fun(function_address);
282 ExternalReference::Type type = ExternalReference::DIRECT_API_CALL; 302 ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
283 ExternalReference ref = ExternalReference(&fun, type, masm->isolate()); 303 ExternalReference ref = ExternalReference(&fun, type, masm->isolate());
284 __ mov(api_function_address, Operand(ref)); 304 __ mov(api_function_address, Operand(ref));
285 305
286 // Jump to stub. 306 // Jump to stub.
287 CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc); 307 CallApiAccessorStub stub(isolate, is_store, call_data_undefined);
288 __ TailCallStub(&stub); 308 __ TailCallStub(&stub);
289 } 309 }
290 310
291 311
292 void NamedStoreHandlerCompiler::GenerateSlow(MacroAssembler* masm) { 312 void NamedStoreHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
293 // Push receiver, key and value for runtime call. 313 // Push receiver, key and value for runtime call.
294 __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(), 314 __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(),
295 StoreDescriptor::ValueRegister()); 315 StoreDescriptor::ValueRegister());
296 316
297 // The slow case calls into the runtime to complete the store without causing 317 // The slow case calls into the runtime to complete the store without causing
(...skipping 23 matching lines...) Expand all
321 341
322 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, 342 void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
323 Handle<Name> name) { 343 Handle<Name> name) {
324 if (!label->is_unused()) { 344 if (!label->is_unused()) {
325 __ bind(label); 345 __ bind(label);
326 __ mov(this->name(), Operand(name)); 346 __ mov(this->name(), Operand(name));
327 } 347 }
328 } 348 }
329 349
330 350
331 void NamedStoreHandlerCompiler::GenerateRestoreNameAndMap( 351 void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) {
332 Handle<Name> name, Handle<Map> transition) {
333 __ mov(this->name(), Operand(name)); 352 __ mov(this->name(), Operand(name));
334 __ mov(StoreTransitionDescriptor::MapRegister(), Operand(transition));
335 } 353 }
336 354
337 355
338 void NamedStoreHandlerCompiler::GenerateConstantCheck(Object* constant, 356 void NamedStoreHandlerCompiler::GenerateRestoreMap(Handle<Map> transition,
357 Register scratch,
358 Label* miss) {
359 Handle<WeakCell> cell = Map::WeakCellForMap(transition);
360 Register map_reg = StoreTransitionDescriptor::MapRegister();
361 DCHECK(!map_reg.is(scratch));
362 __ LoadWeakValue(map_reg, cell, miss);
363 if (transition->CanBeDeprecated()) {
364 __ lwz(scratch, FieldMemOperand(map_reg, Map::kBitField3Offset));
365 __ DecodeField<Map::Deprecated>(r0, scratch, SetRC);
366 __ bne(miss, cr0);
367 }
368 }
369
370
371 void NamedStoreHandlerCompiler::GenerateConstantCheck(Register map_reg,
372 int descriptor,
339 Register value_reg, 373 Register value_reg,
374 Register scratch,
340 Label* miss_label) { 375 Label* miss_label) {
341 __ Move(scratch1(), handle(constant, isolate())); 376 DCHECK(!map_reg.is(scratch));
342 __ cmp(value_reg, scratch1()); 377 DCHECK(!map_reg.is(value_reg));
378 DCHECK(!value_reg.is(scratch));
379 __ LoadInstanceDescriptors(map_reg, scratch);
380 __ LoadP(scratch, FieldMemOperand(
381 scratch, DescriptorArray::GetValueOffset(descriptor)));
382 __ cmp(value_reg, scratch);
343 __ bne(miss_label); 383 __ bne(miss_label);
344 } 384 }
345 385
346 386
347 void NamedStoreHandlerCompiler::GenerateFieldTypeChecks(HeapType* field_type, 387 void NamedStoreHandlerCompiler::GenerateFieldTypeChecks(HeapType* field_type,
348 Register value_reg, 388 Register value_reg,
349 Label* miss_label) { 389 Label* miss_label) {
390 Register map_reg = scratch1();
391 Register scratch = scratch2();
392 DCHECK(!value_reg.is(map_reg));
393 DCHECK(!value_reg.is(scratch));
350 __ JumpIfSmi(value_reg, miss_label); 394 __ JumpIfSmi(value_reg, miss_label);
351 HeapType::Iterator<Map> it = field_type->Classes(); 395 HeapType::Iterator<Map> it = field_type->Classes();
352 if (!it.Done()) { 396 if (!it.Done()) {
353 __ LoadP(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset)); 397 __ LoadP(map_reg, FieldMemOperand(value_reg, HeapObject::kMapOffset));
354 Label do_store; 398 Label do_store;
355 while (true) { 399 while (true) {
356 __ CompareMap(scratch1(), it.Current(), &do_store); 400 __ CmpWeakValue(map_reg, Map::WeakCellForMap(it.Current()), scratch);
357 it.Advance(); 401 it.Advance();
358 if (it.Done()) { 402 if (it.Done()) {
359 __ bne(miss_label); 403 __ bne(miss_label);
360 break; 404 break;
361 } 405 }
362 __ beq(&do_store); 406 __ beq(&do_store);
363 } 407 }
364 __ bind(&do_store); 408 __ bind(&do_store);
365 } 409 }
366 } 410 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 NameDictionary::kNotFound); 455 NameDictionary::kNotFound);
412 456
413 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1, 457 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
414 scratch2); 458 scratch2);
415 459
416 __ LoadP(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); 460 __ LoadP(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
417 reg = holder_reg; // From now on the object will be in holder_reg. 461 reg = holder_reg; // From now on the object will be in holder_reg.
418 __ LoadP(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); 462 __ LoadP(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
419 } else { 463 } else {
420 Register map_reg = scratch1; 464 Register map_reg = scratch1;
465 __ LoadP(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
421 if (depth != 1 || check == CHECK_ALL_MAPS) { 466 if (depth != 1 || check == CHECK_ALL_MAPS) {
422 // CheckMap implicitly loads the map of |reg| into |map_reg|. 467 Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
423 __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK); 468 __ CmpWeakValue(map_reg, cell, scratch2);
424 } else { 469 __ bne(miss);
425 __ LoadP(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
426 } 470 }
427 471
428 // Check access rights to the global object. This has to happen after 472 // Check access rights to the global object. This has to happen after
429 // the map check so that we know that the object is actually a global 473 // the map check so that we know that the object is actually a global
430 // object. 474 // object.
431 // This allows us to install generated handlers for accesses to the 475 // This allows us to install generated handlers for accesses to the
432 // global proxy (as opposed to using slow ICs). See corresponding code 476 // global proxy (as opposed to using slow ICs). See corresponding code
433 // in LookupForRead(). 477 // in LookupForRead().
434 if (current_map->IsJSGlobalProxyMap()) { 478 if (current_map->IsJSGlobalProxyMap()) {
435 __ CheckAccessGlobalProxy(reg, scratch2, miss); 479 __ CheckAccessGlobalProxy(reg, scratch2, miss);
436 } else if (current_map->IsJSGlobalObjectMap()) { 480 } else if (current_map->IsJSGlobalObjectMap()) {
437 GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current), 481 GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
438 name, scratch2, miss); 482 name, scratch2, miss);
439 } 483 }
440 484
441 reg = holder_reg; // From now on the object will be in holder_reg. 485 reg = holder_reg; // From now on the object will be in holder_reg.
442 486
443 // Two possible reasons for loading the prototype from the map: 487 __ LoadP(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
444 // (1) Can't store references to new space in code.
445 // (2) Handler is shared for all receivers with the same prototype
446 // map (but not necessarily the same prototype instance).
447 bool load_prototype_from_map =
448 heap()->InNewSpace(*prototype) || depth == 1;
449 if (load_prototype_from_map) {
450 __ LoadP(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
451 } else {
452 __ mov(reg, Operand(prototype));
453 }
454 } 488 }
455 489
456 // Go to the next object in the prototype chain. 490 // Go to the next object in the prototype chain.
457 current = prototype; 491 current = prototype;
458 current_map = handle(current->map()); 492 current_map = handle(current->map());
459 } 493 }
460 494
461 // Log the check depth. 495 // Log the check depth.
462 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 496 LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
463 497
464 if (depth != 0 || check == CHECK_ALL_MAPS) { 498 if (depth != 0 || check == CHECK_ALL_MAPS) {
465 // Check the holder map. 499 // Check the holder map.
466 __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK); 500 __ LoadP(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
501 Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
502 __ CmpWeakValue(scratch1, cell, scratch2);
503 __ bne(miss);
467 } 504 }
468 505
469 // Perform security check for access to the global object. 506 // Perform security check for access to the global object.
470 DCHECK(current_map->IsJSGlobalProxyMap() || 507 DCHECK(current_map->IsJSGlobalProxyMap() ||
471 !current_map->is_access_check_needed()); 508 !current_map->is_access_check_needed());
472 if (current_map->IsJSGlobalProxyMap()) { 509 if (current_map->IsJSGlobalProxyMap()) {
473 __ CheckAccessGlobalProxy(reg, scratch1, miss); 510 __ CheckAccessGlobalProxy(reg, scratch1, miss);
474 } 511 }
475 512
476 // Return the register containing the holder. 513 // Return the register containing the holder.
477 return reg; 514 return reg;
478 } 515 }
479 516
480 517
481 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 518 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
482 if (!miss->is_unused()) { 519 if (!miss->is_unused()) {
483 Label success; 520 Label success;
484 __ b(&success); 521 __ b(&success);
485 __ bind(miss); 522 __ bind(miss);
523 if (IC::ICUseVector(kind())) {
524 DCHECK(kind() == Code::LOAD_IC);
525 PopVectorAndSlot();
526 }
486 TailCallBuiltin(masm(), MissBuiltin(kind())); 527 TailCallBuiltin(masm(), MissBuiltin(kind()));
487 __ bind(&success); 528 __ bind(&success);
488 } 529 }
489 } 530 }
490 531
491 532
492 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 533 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
493 if (!miss->is_unused()) { 534 if (!miss->is_unused()) {
494 Label success; 535 Label success;
495 __ b(&success); 536 __ b(&success);
(...skipping 19 matching lines...) Expand all
515 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); 556 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
516 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); 557 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
517 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); 558 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
518 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4); 559 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
519 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5); 560 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
520 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6); 561 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
521 DCHECK(!scratch2().is(reg)); 562 DCHECK(!scratch2().is(reg));
522 DCHECK(!scratch3().is(reg)); 563 DCHECK(!scratch3().is(reg));
523 DCHECK(!scratch4().is(reg)); 564 DCHECK(!scratch4().is(reg));
524 __ push(receiver()); 565 __ push(receiver());
525 if (heap()->InNewSpace(callback->data())) { 566 // Push data from ExecutableAccessorInfo.
526 __ Move(scratch3(), callback); 567 Handle<Object> data(callback->data(), isolate());
527 __ LoadP(scratch3(), 568 if (data->IsUndefined() || data->IsSmi()) {
528 FieldMemOperand(scratch3(), ExecutableAccessorInfo::kDataOffset)); 569 __ Move(scratch3(), data);
529 } else { 570 } else {
530 __ Move(scratch3(), Handle<Object>(callback->data(), isolate())); 571 Handle<WeakCell> cell =
572 isolate()->factory()->NewWeakCell(Handle<HeapObject>::cast(data));
573 // The callback is alive if this instruction is executed,
574 // so the weak cell is not cleared and points to data.
575 __ GetWeakValue(scratch3(), cell);
531 } 576 }
532 __ push(scratch3()); 577 __ push(scratch3());
533 __ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex); 578 __ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex);
534 __ mr(scratch4(), scratch3()); 579 __ mr(scratch4(), scratch3());
535 __ Push(scratch3(), scratch4()); 580 __ Push(scratch3(), scratch4());
536 __ mov(scratch4(), Operand(ExternalReference::isolate_address(isolate()))); 581 __ mov(scratch4(), Operand(ExternalReference::isolate_address(isolate())));
537 __ Push(scratch4(), reg); 582 __ Push(scratch4(), reg);
538 __ push(name()); 583 __ push(name());
539 584
540 // Abi for CallApiGetter 585 // Abi for CallApiGetter
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 618
574 // Save necessary data before invoking an interceptor. 619 // Save necessary data before invoking an interceptor.
575 // Requires a frame to make GC aware of pushed pointers. 620 // Requires a frame to make GC aware of pushed pointers.
576 { 621 {
577 FrameAndConstantPoolScope frame_scope(masm(), StackFrame::INTERNAL); 622 FrameAndConstantPoolScope frame_scope(masm(), StackFrame::INTERNAL);
578 if (must_preserve_receiver_reg) { 623 if (must_preserve_receiver_reg) {
579 __ Push(receiver(), holder_reg, this->name()); 624 __ Push(receiver(), holder_reg, this->name());
580 } else { 625 } else {
581 __ Push(holder_reg, this->name()); 626 __ Push(holder_reg, this->name());
582 } 627 }
628 InterceptorVectorSlotPush(holder_reg);
583 // Invoke an interceptor. Note: map checks from receiver to 629 // Invoke an interceptor. Note: map checks from receiver to
584 // interceptor's holder has been compiled before (see a caller 630 // interceptor's holder has been compiled before (see a caller
585 // of this method.) 631 // of this method.)
586 CompileCallLoadPropertyWithInterceptor( 632 CompileCallLoadPropertyWithInterceptor(
587 masm(), receiver(), holder_reg, this->name(), holder(), 633 masm(), receiver(), holder_reg, this->name(), holder(),
588 IC::kLoadPropertyWithInterceptorOnly); 634 IC::kLoadPropertyWithInterceptorOnly);
589 635
590 // Check if interceptor provided a value for property. If it's 636 // Check if interceptor provided a value for property. If it's
591 // the case, return immediately. 637 // the case, return immediately.
592 Label interceptor_failed; 638 Label interceptor_failed;
593 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex); 639 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex);
594 __ cmp(r3, scratch1()); 640 __ cmp(r3, scratch1());
595 __ beq(&interceptor_failed); 641 __ beq(&interceptor_failed);
596 frame_scope.GenerateLeaveFrame(); 642 frame_scope.GenerateLeaveFrame();
597 __ Ret(); 643 __ Ret();
598 644
599 __ bind(&interceptor_failed); 645 __ bind(&interceptor_failed);
646 InterceptorVectorSlotPop(holder_reg);
600 __ pop(this->name()); 647 __ pop(this->name());
601 __ pop(holder_reg); 648 __ pop(holder_reg);
602 if (must_preserve_receiver_reg) { 649 if (must_preserve_receiver_reg) {
603 __ pop(receiver()); 650 __ pop(receiver());
604 } 651 }
605 // Leave the internal frame. 652 // Leave the internal frame.
606 } 653 }
607 654
608 GenerateLoadPostInterceptor(it, holder_reg); 655 GenerateLoadPostInterceptor(it, holder_reg);
609 } 656 }
610 657
611 658
612 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) { 659 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
613 // Call the runtime system to load the interceptor. 660 // Call the runtime system to load the interceptor.
614 DCHECK(holder()->HasNamedInterceptor()); 661 DCHECK(holder()->HasNamedInterceptor());
615 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined()); 662 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
616 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(), 663 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
617 holder()); 664 holder());
618 665
619 ExternalReference ref = ExternalReference( 666 ExternalReference ref = ExternalReference(
620 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); 667 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
621 __ TailCallExternalReference( 668 __ TailCallExternalReference(
622 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); 669 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
623 } 670 }
624 671
625 672
626 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 673 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
627 Handle<JSObject> object, Handle<Name> name, 674 Handle<JSObject> object, Handle<Name> name, int accessor_index) {
628 Handle<ExecutableAccessorInfo> callback) { 675 Register holder_reg = Frontend(name);
629 Register holder_reg = Frontend(receiver(), name);
630 676
631 __ Push(receiver(), holder_reg); // receiver 677 __ Push(receiver(), holder_reg); // receiver
632 __ mov(ip, Operand(callback)); // callback info 678 __ LoadSmiLiteral(ip, Smi::FromInt(accessor_index));
633 __ push(ip); 679 __ push(ip);
634 __ mov(ip, Operand(name)); 680 __ mov(ip, Operand(name));
635 __ Push(ip, value()); 681 __ Push(ip, value());
636 682
637 // Do tail-call to the runtime system. 683 // Do tail-call to the runtime system.
638 ExternalReference store_callback_property = 684 ExternalReference store_callback_property =
639 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 685 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
640 __ TailCallExternalReference(store_callback_property, 5, 1); 686 __ TailCallExternalReference(store_callback_property, 5, 1);
641 687
642 // Return the generated code. 688 // Return the generated code.
(...skipping 16 matching lines...) Expand all
659 705
660 706
661 Register NamedStoreHandlerCompiler::value() { 707 Register NamedStoreHandlerCompiler::value() {
662 return StoreDescriptor::ValueRegister(); 708 return StoreDescriptor::ValueRegister();
663 } 709 }
664 710
665 711
666 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 712 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
667 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { 713 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
668 Label miss; 714 Label miss;
715 if (IC::ICUseVector(kind())) {
716 PushVectorAndSlot();
717 }
669 FrontendHeader(receiver(), name, &miss); 718 FrontendHeader(receiver(), name, &miss);
670 719
671 // Get the value from the cell. 720 // Get the value from the cell.
672 Register result = StoreDescriptor::ValueRegister(); 721 Register result = StoreDescriptor::ValueRegister();
673 __ mov(result, Operand(cell)); 722 Handle<WeakCell> weak_cell = factory()->NewWeakCell(cell);
723 __ LoadWeakValue(result, weak_cell, &miss);
674 __ LoadP(result, FieldMemOperand(result, Cell::kValueOffset)); 724 __ LoadP(result, FieldMemOperand(result, Cell::kValueOffset));
675 725
676 // Check for deleted property if property can actually be deleted. 726 // Check for deleted property if property can actually be deleted.
677 if (is_configurable) { 727 if (is_configurable) {
678 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 728 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
679 __ cmp(result, ip); 729 __ cmp(result, ip);
680 __ beq(&miss); 730 __ beq(&miss);
681 } 731 }
682 732
683 Counters* counters = isolate()->counters(); 733 Counters* counters = isolate()->counters();
684 __ IncrementCounter(counters->named_load_global_stub(), 1, r4, r6); 734 __ IncrementCounter(counters->named_load_global_stub(), 1, r4, r6);
735 if (IC::ICUseVector(kind())) {
736 DiscardVectorAndSlot();
737 }
685 __ Ret(); 738 __ Ret();
686 739
687 FrontendFooter(name, &miss); 740 FrontendFooter(name, &miss);
688 741
689 // Return the generated code. 742 // Return the generated code.
690 return GetCode(kind(), Code::NORMAL, name); 743 return GetCode(kind(), Code::NORMAL, name);
691 } 744 }
692 745
693 746
694 #undef __ 747 #undef __
695 } 748 }
696 } // namespace v8::internal 749 } // namespace v8::internal
697 750
698 #endif // V8_TARGET_ARCH_ARM 751 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/compiler/ppc/linkage-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