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

Side by Side Diff: src/ic/ppc/ic-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/ic/ppc/ic-compiler-ppc.cc ('k') | src/ic/ppc/stub-cache-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/codegen.h" 9 #include "src/codegen.h"
10 #include "src/ic/ic.h" 10 #include "src/ic/ic.h"
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 // we enter the runtime system to make sure that indexing into string 157 // we enter the runtime system to make sure that indexing into string
158 // objects work as intended. 158 // objects work as intended.
159 DCHECK(JS_OBJECT_TYPE > JS_VALUE_TYPE); 159 DCHECK(JS_OBJECT_TYPE > JS_VALUE_TYPE);
160 __ lbz(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); 160 __ lbz(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
161 __ cmpi(scratch, Operand(JS_OBJECT_TYPE)); 161 __ cmpi(scratch, Operand(JS_OBJECT_TYPE));
162 __ blt(slow); 162 __ blt(slow);
163 } 163 }
164 164
165 165
166 // Loads an indexed element from a fast case array. 166 // Loads an indexed element from a fast case array.
167 // If not_fast_array is NULL, doesn't perform the elements map check.
168 static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver, 167 static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
169 Register key, Register elements, 168 Register key, Register elements,
170 Register scratch1, Register scratch2, 169 Register scratch1, Register scratch2,
171 Register result, Label* not_fast_array, 170 Register result, Label* slow) {
172 Label* out_of_range) {
173 // Register use: 171 // Register use:
174 // 172 //
175 // receiver - holds the receiver on entry. 173 // receiver - holds the receiver on entry.
176 // Unchanged unless 'result' is the same register. 174 // Unchanged unless 'result' is the same register.
177 // 175 //
178 // key - holds the smi key on entry. 176 // key - holds the smi key on entry.
179 // Unchanged unless 'result' is the same register. 177 // Unchanged unless 'result' is the same register.
180 // 178 //
181 // elements - holds the elements of the receiver on exit.
182 //
183 // result - holds the result on exit if the load succeeded. 179 // result - holds the result on exit if the load succeeded.
184 // Allowed to be the the same as 'receiver' or 'key'. 180 // Allowed to be the the same as 'receiver' or 'key'.
185 // Unchanged on bailout so 'receiver' and 'key' can be safely 181 // Unchanged on bailout so 'receiver' and 'key' can be safely
186 // used by further computation. 182 // used by further computation.
187 // 183 //
188 // Scratch registers: 184 // Scratch registers:
189 // 185 //
190 // scratch1 - used to hold elements map and elements length. 186 // elements - holds the elements of the receiver and its protoypes.
191 // Holds the elements map if not_fast_array branch is taken.
192 // 187 //
193 // scratch2 - used to hold the loaded value. 188 // scratch1 - used to hold elements length, bit fields, base addresses.
189 //
190 // scratch2 - used to hold maps, prototypes, and the loaded value.
191 Label check_prototypes, check_next_prototype;
192 Label done, in_bounds, return_undefined;
194 193
195 __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); 194 __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
196 if (not_fast_array != NULL) { 195 __ AssertFastElements(elements);
197 // Check that the object is in fast mode and writable. 196
198 __ LoadP(scratch1, FieldMemOperand(elements, HeapObject::kMapOffset));
199 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
200 __ cmp(scratch1, ip);
201 __ bne(not_fast_array);
202 } else {
203 __ AssertFastElements(elements);
204 }
205 // Check that the key (index) is within bounds. 197 // Check that the key (index) is within bounds.
206 __ LoadP(scratch1, FieldMemOperand(elements, FixedArray::kLengthOffset)); 198 __ LoadP(scratch1, FieldMemOperand(elements, FixedArray::kLengthOffset));
207 __ cmpl(key, scratch1); 199 __ cmpl(key, scratch1);
208 __ bge(out_of_range); 200 __ blt(&in_bounds);
201 // Out-of-bounds. Check the prototype chain to see if we can just return
202 // 'undefined'.
203 __ cmpi(key, Operand::Zero());
204 __ blt(slow); // Negative keys can't take the fast OOB path.
205 __ bind(&check_prototypes);
206 __ LoadP(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset));
207 __ bind(&check_next_prototype);
208 __ LoadP(scratch2, FieldMemOperand(scratch2, Map::kPrototypeOffset));
209 // scratch2: current prototype
210 __ CompareRoot(scratch2, Heap::kNullValueRootIndex);
211 __ beq(&return_undefined);
212 __ LoadP(elements, FieldMemOperand(scratch2, JSObject::kElementsOffset));
213 __ LoadP(scratch2, FieldMemOperand(scratch2, HeapObject::kMapOffset));
214 // elements: elements of current prototype
215 // scratch2: map of current prototype
216 __ CompareInstanceType(scratch2, scratch1, JS_OBJECT_TYPE);
217 __ blt(slow);
218 __ lbz(scratch1, FieldMemOperand(scratch2, Map::kBitFieldOffset));
219 __ andi(r0, scratch1, Operand((1 << Map::kIsAccessCheckNeeded) |
220 (1 << Map::kHasIndexedInterceptor)));
221 __ bne(slow, cr0);
222 __ CompareRoot(elements, Heap::kEmptyFixedArrayRootIndex);
223 __ bne(slow);
224 __ jmp(&check_next_prototype);
225
226 __ bind(&return_undefined);
227 __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
228 __ jmp(&done);
229
230 __ bind(&in_bounds);
209 // Fast case: Do the load. 231 // Fast case: Do the load.
210 __ addi(scratch1, elements, 232 __ addi(scratch1, elements,
211 Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 233 Operand(FixedArray::kHeaderSize - kHeapObjectTag));
212 // The key is a smi. 234 // The key is a smi.
213 __ SmiToPtrArrayOffset(scratch2, key); 235 __ SmiToPtrArrayOffset(scratch2, key);
214 __ LoadPX(scratch2, MemOperand(scratch2, scratch1)); 236 __ LoadPX(scratch2, MemOperand(scratch2, scratch1));
215 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 237 __ CompareRoot(scratch2, Heap::kTheHoleValueRootIndex);
216 __ cmp(scratch2, ip); 238 // In case the loaded value is the_hole we have to check the prototype chain.
217 // In case the loaded value is the_hole we have to consult GetProperty 239 __ beq(&check_prototypes);
218 // to ensure the prototype chain is searched.
219 __ beq(out_of_range);
220 __ mr(result, scratch2); 240 __ mr(result, scratch2);
241 __ bind(&done);
221 } 242 }
222 243
223 244
224 // Checks whether a key is an array index string or a unique name. 245 // Checks whether a key is an array index string or a unique name.
225 // Falls through if a key is a unique name. 246 // Falls through if a key is a unique name.
226 static void GenerateKeyNameCheck(MacroAssembler* masm, Register key, 247 static void GenerateKeyNameCheck(MacroAssembler* masm, Register key,
227 Register map, Register hash, 248 Register map, Register hash,
228 Label* index_string, Label* not_unique) { 249 Label* index_string, Label* not_unique) {
229 // The key is not a smi. 250 // The key is not a smi.
230 Label unique; 251 Label unique;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 // Dictionary load failed, go slow (but don't miss). 289 // Dictionary load failed, go slow (but don't miss).
269 __ bind(&slow); 290 __ bind(&slow);
270 GenerateRuntimeGetProperty(masm); 291 GenerateRuntimeGetProperty(masm);
271 } 292 }
272 293
273 294
274 // A register that isn't one of the parameters to the load ic. 295 // A register that isn't one of the parameters to the load ic.
275 static const Register LoadIC_TempRegister() { return r6; } 296 static const Register LoadIC_TempRegister() { return r6; }
276 297
277 298
299 static void LoadIC_PushArgs(MacroAssembler* masm) {
300 Register receiver = LoadDescriptor::ReceiverRegister();
301 Register name = LoadDescriptor::NameRegister();
302 if (FLAG_vector_ics) {
303 Register slot = VectorLoadICDescriptor::SlotRegister();
304 Register vector = VectorLoadICDescriptor::VectorRegister();
305
306 __ Push(receiver, name, slot, vector);
307 } else {
308 __ Push(receiver, name);
309 }
310 }
311
312
278 void LoadIC::GenerateMiss(MacroAssembler* masm) { 313 void LoadIC::GenerateMiss(MacroAssembler* masm) {
279 // The return address is in lr. 314 // The return address is in lr.
280 Isolate* isolate = masm->isolate(); 315 Isolate* isolate = masm->isolate();
281 316
282 __ IncrementCounter(isolate->counters()->load_miss(), 1, r6, r7); 317 DCHECK(!FLAG_vector_ics ||
318 !AreAliased(r7, r8, VectorLoadICDescriptor::SlotRegister(),
319 VectorLoadICDescriptor::VectorRegister()));
320 __ IncrementCounter(isolate->counters()->load_miss(), 1, r7, r8);
283 321
284 __ mr(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister()); 322 LoadIC_PushArgs(masm);
285 __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister());
286 323
287 // Perform tail call to the entry. 324 // Perform tail call to the entry.
288 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate); 325 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate);
289 __ TailCallExternalReference(ref, 2, 1); 326 int arg_count = FLAG_vector_ics ? 4 : 2;
327 __ TailCallExternalReference(ref, arg_count, 1);
290 } 328 }
291 329
292 330
293 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { 331 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
294 // The return address is in lr. 332 // The return address is in lr.
295 333
296 __ mr(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister()); 334 __ mr(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister());
297 __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister()); 335 __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister());
298 336
299 __ TailCallRuntime(Runtime::kGetProperty, 2, 1); 337 __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 __ Ret(); 446 __ Ret();
409 __ bind(&slow); 447 __ bind(&slow);
410 GenerateMiss(masm); 448 GenerateMiss(masm);
411 } 449 }
412 450
413 451
414 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { 452 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
415 // The return address is in lr. 453 // The return address is in lr.
416 Isolate* isolate = masm->isolate(); 454 Isolate* isolate = masm->isolate();
417 455
418 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r6, r7); 456 DCHECK(!FLAG_vector_ics ||
457 !AreAliased(r7, r8, VectorLoadICDescriptor::SlotRegister(),
458 VectorLoadICDescriptor::VectorRegister()));
459 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r7, r8);
419 460
420 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); 461 LoadIC_PushArgs(masm);
421 462
422 // Perform tail call to the entry. 463 // Perform tail call to the entry.
423 ExternalReference ref = 464 ExternalReference ref =
424 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate); 465 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate);
425 466 int arg_count = FLAG_vector_ics ? 4 : 2;
426 __ TailCallExternalReference(ref, 2, 1); 467 __ TailCallExternalReference(ref, arg_count, 1);
427 } 468 }
428 469
429 470
430 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { 471 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
431 // The return address is in lr. 472 // The return address is in lr.
432 473
433 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); 474 __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
434 475
435 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); 476 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
436 } 477 }
437 478
438 479
439 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { 480 void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) {
440 // The return address is in lr. 481 // The return address is in lr.
441 Label slow, check_name, index_smi, index_name, property_array_property; 482 Label slow, check_name, index_smi, index_name, property_array_property;
442 Label probe_dictionary, check_number_dictionary; 483 Label probe_dictionary, check_number_dictionary;
443 484
444 Register key = LoadDescriptor::NameRegister(); 485 Register key = LoadDescriptor::NameRegister();
445 Register receiver = LoadDescriptor::ReceiverRegister(); 486 Register receiver = LoadDescriptor::ReceiverRegister();
446 DCHECK(key.is(r5)); 487 DCHECK(key.is(r5));
447 DCHECK(receiver.is(r4)); 488 DCHECK(receiver.is(r4));
448 489
449 Isolate* isolate = masm->isolate(); 490 Isolate* isolate = masm->isolate();
450 491
451 // Check that the key is a smi. 492 // Check that the key is a smi.
452 __ JumpIfNotSmi(key, &check_name); 493 __ JumpIfNotSmi(key, &check_name);
453 __ bind(&index_smi); 494 __ bind(&index_smi);
454 // Now the key is known to be a smi. This place is also jumped to from below 495 // Now the key is known to be a smi. This place is also jumped to from below
455 // where a numeric string is converted to a smi. 496 // where a numeric string is converted to a smi.
456 497
457 GenerateKeyedLoadReceiverCheck(masm, receiver, r3, r6, 498 GenerateKeyedLoadReceiverCheck(masm, receiver, r3, r6,
458 Map::kHasIndexedInterceptor, &slow); 499 Map::kHasIndexedInterceptor, &slow);
459 500
460 // Check the receiver's map to see if it has fast elements. 501 // Check the receiver's map to see if it has fast elements.
461 __ CheckFastElements(r3, r6, &check_number_dictionary); 502 __ CheckFastElements(r3, r6, &check_number_dictionary);
462 503
463 GenerateFastArrayLoad(masm, receiver, key, r3, r6, r7, r3, NULL, &slow); 504 GenerateFastArrayLoad(masm, receiver, key, r3, r6, r7, r3, &slow);
464 __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, r7, r6); 505 __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, r7, r6);
465 __ Ret(); 506 __ Ret();
466 507
467 __ bind(&check_number_dictionary); 508 __ bind(&check_number_dictionary);
468 __ LoadP(r7, FieldMemOperand(receiver, JSObject::kElementsOffset)); 509 __ LoadP(r7, FieldMemOperand(receiver, JSObject::kElementsOffset));
469 __ LoadP(r6, FieldMemOperand(r7, JSObject::kMapOffset)); 510 __ LoadP(r6, FieldMemOperand(r7, JSObject::kMapOffset));
470 511
471 // Check whether the elements is a number dictionary. 512 // Check whether the elements is a number dictionary.
472 // r6: elements map 513 // r6: elements map
473 // r7: elements 514 // r7: elements
474 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); 515 __ LoadRoot(ip, Heap::kHashTableMapRootIndex);
475 __ cmp(r6, ip); 516 __ cmp(r6, ip);
476 __ bne(&slow); 517 __ bne(&slow);
477 __ SmiUntag(r3, key); 518 __ SmiUntag(r3, key);
478 __ LoadFromNumberDictionary(&slow, r7, key, r3, r3, r6, r8); 519 __ LoadFromNumberDictionary(&slow, r7, key, r3, r3, r6, r8);
479 __ Ret(); 520 __ Ret();
480 521
481 // Slow case, key and receiver still in r3 and r4. 522 // Slow case, key and receiver still in r3 and r4.
482 __ bind(&slow); 523 __ bind(&slow);
483 __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1, r7, 524 __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1, r7,
484 r6); 525 r6);
485 GenerateRuntimeGetProperty(masm); 526 GenerateRuntimeGetProperty(masm);
486 527
487 __ bind(&check_name); 528 __ bind(&check_name);
488 GenerateKeyNameCheck(masm, key, r3, r6, &index_name, &slow); 529 GenerateKeyNameCheck(masm, key, r3, r6, &index_name, &slow);
489 530
490 GenerateKeyedLoadReceiverCheck(masm, receiver, r3, r6, 531 GenerateKeyedLoadReceiverCheck(masm, receiver, r3, r6,
491 Map::kHasNamedInterceptor, &slow); 532 Map::kHasNamedInterceptor, &slow);
492 533
493 // If the receiver is a fast-case object, check the keyed lookup 534 // If the receiver is a fast-case object, check the stub cache. Otherwise
494 // cache. Otherwise probe the dictionary. 535 // probe the dictionary.
495 __ LoadP(r6, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 536 __ LoadP(r6, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
496 __ LoadP(r7, FieldMemOperand(r6, HeapObject::kMapOffset)); 537 __ LoadP(r7, FieldMemOperand(r6, HeapObject::kMapOffset));
497 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); 538 __ LoadRoot(ip, Heap::kHashTableMapRootIndex);
498 __ cmp(r7, ip); 539 __ cmp(r7, ip);
499 __ beq(&probe_dictionary); 540 __ beq(&probe_dictionary);
500 541
501 // Load the map of the receiver, compute the keyed lookup cache hash
502 // based on 32 bits of the map pointer and the name hash.
503 __ LoadP(r3, FieldMemOperand(receiver, HeapObject::kMapOffset));
504 __ srawi(r6, r3, KeyedLookupCache::kMapHashShift);
505 __ lwz(r7, FieldMemOperand(key, Name::kHashFieldOffset));
506 __ srawi(r7, r7, Name::kHashShift);
507 __ xor_(r6, r6, r7);
508 int mask = KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask;
509 __ mov(r7, Operand(mask));
510 __ and_(r6, r6, r7, LeaveRC);
511 542
512 // Load the key (consisting of map and unique name) from the cache and 543 if (FLAG_vector_ics) {
513 // check for match. 544 // When vector ics are in use, the handlers in the stub cache expect a
514 Label load_in_object_property; 545 // vector and slot. Since we won't change the IC from any downstream
515 static const int kEntriesPerBucket = KeyedLookupCache::kEntriesPerBucket; 546 // misses, a dummy vector can be used.
516 Label hit_on_nth_entry[kEntriesPerBucket]; 547 Register vector = VectorLoadICDescriptor::VectorRegister();
517 ExternalReference cache_keys = 548 Register slot = VectorLoadICDescriptor::SlotRegister();
518 ExternalReference::keyed_lookup_cache_keys(isolate); 549 DCHECK(!AreAliased(vector, slot, r7, r8, r9, r10));
519 550 Handle<TypeFeedbackVector> dummy_vector = Handle<TypeFeedbackVector>::cast(
520 __ mov(r7, Operand(cache_keys)); 551 masm->isolate()->factory()->keyed_load_dummy_vector());
521 __ mr(r0, r5); 552 int int_slot = dummy_vector->GetIndex(FeedbackVectorICSlot(0));
522 __ ShiftLeftImm(r5, r6, Operand(kPointerSizeLog2 + 1)); 553 __ LoadRoot(vector, Heap::kKeyedLoadDummyVectorRootIndex);
523 __ add(r7, r7, r5); 554 __ LoadSmiLiteral(slot, Smi::FromInt(int_slot));
524 __ mr(r5, r0);
525
526 for (int i = 0; i < kEntriesPerBucket - 1; i++) {
527 Label try_next_entry;
528 // Load map and move r7 to next entry.
529 __ LoadP(r8, MemOperand(r7));
530 __ addi(r7, r7, Operand(kPointerSize * 2));
531 __ cmp(r3, r8);
532 __ bne(&try_next_entry);
533 __ LoadP(r8, MemOperand(r7, -kPointerSize)); // Load name
534 __ cmp(key, r8);
535 __ beq(&hit_on_nth_entry[i]);
536 __ bind(&try_next_entry);
537 } 555 }
538 556
539 // Last entry: Load map and move r7 to name. 557 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
540 __ LoadP(r8, MemOperand(r7)); 558 Code::ComputeHandlerFlags(Code::LOAD_IC));
541 __ addi(r7, r7, Operand(kPointerSize)); 559 masm->isolate()->stub_cache()->GenerateProbe(
542 __ cmp(r3, r8); 560 masm, Code::KEYED_LOAD_IC, flags, false, receiver, key, r7, r8, r9, r10);
543 __ bne(&slow); 561 // Cache miss.
544 __ LoadP(r8, MemOperand(r7)); 562 GenerateMiss(masm);
545 __ cmp(key, r8);
546 __ bne(&slow);
547
548 // Get field offset.
549 // r3 : receiver's map
550 // r6 : lookup cache index
551 ExternalReference cache_field_offsets =
552 ExternalReference::keyed_lookup_cache_field_offsets(isolate);
553
554 // Hit on nth entry.
555 for (int i = kEntriesPerBucket - 1; i >= 0; i--) {
556 __ bind(&hit_on_nth_entry[i]);
557 __ mov(r7, Operand(cache_field_offsets));
558 if (i != 0) {
559 __ addi(r6, r6, Operand(i));
560 }
561 __ ShiftLeftImm(r8, r6, Operand(2));
562 __ lwzx(r8, MemOperand(r8, r7));
563 __ lbz(r9, FieldMemOperand(r3, Map::kInObjectPropertiesOffset));
564 __ sub(r8, r8, r9);
565 __ cmpi(r8, Operand::Zero());
566 __ bge(&property_array_property);
567 if (i != 0) {
568 __ b(&load_in_object_property);
569 }
570 }
571
572 // Load in-object property.
573 __ bind(&load_in_object_property);
574 __ lbz(r9, FieldMemOperand(r3, Map::kInstanceSizeOffset));
575 __ add(r9, r9, r8); // Index from start of object.
576 __ subi(receiver, receiver, Operand(kHeapObjectTag)); // Remove the heap tag.
577 __ ShiftLeftImm(r3, r9, Operand(kPointerSizeLog2));
578 __ LoadPX(r3, MemOperand(r3, receiver));
579 __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(), 1,
580 r7, r6);
581 __ Ret();
582
583 // Load property array property.
584 __ bind(&property_array_property);
585 __ LoadP(receiver, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
586 __ addi(receiver, receiver,
587 Operand(FixedArray::kHeaderSize - kHeapObjectTag));
588 __ ShiftLeftImm(r3, r8, Operand(kPointerSizeLog2));
589 __ LoadPX(r3, MemOperand(r3, receiver));
590 __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(), 1,
591 r7, r6);
592 __ Ret();
593 563
594 // Do a quick inline probe of the receiver's dictionary, if it 564 // Do a quick inline probe of the receiver's dictionary, if it
595 // exists. 565 // exists.
596 __ bind(&probe_dictionary); 566 __ bind(&probe_dictionary);
597 // r6: elements 567 // r6: elements
598 __ LoadP(r3, FieldMemOperand(receiver, HeapObject::kMapOffset)); 568 __ LoadP(r3, FieldMemOperand(receiver, HeapObject::kMapOffset));
599 __ lbz(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset)); 569 __ lbz(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset));
600 GenerateGlobalInstanceTypeCheck(masm, r3, &slow); 570 GenerateGlobalInstanceTypeCheck(masm, r3, &slow);
601 // Load the property to r3. 571 // Load the property to r3.
602 GenerateDictionaryLoad(masm, &slow, r6, key, r3, r8, r7); 572 GenerateDictionaryLoad(masm, &slow, r6, key, r3, r8, r7);
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 receiver_map, r7, slow); 733 receiver_map, r7, slow);
764 mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS); 734 mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS);
765 ElementsTransitionGenerator::GenerateDoubleToObject( 735 ElementsTransitionGenerator::GenerateDoubleToObject(
766 masm, receiver, key, value, receiver_map, mode, slow); 736 masm, receiver, key, value, receiver_map, mode, slow);
767 __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); 737 __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
768 __ b(&finish_object_store); 738 __ b(&finish_object_store);
769 } 739 }
770 740
771 741
772 void KeyedStoreIC::GenerateMegamorphic(MacroAssembler* masm, 742 void KeyedStoreIC::GenerateMegamorphic(MacroAssembler* masm,
773 StrictMode strict_mode) { 743 LanguageMode language_mode) {
774 // ---------- S t a t e -------------- 744 // ---------- S t a t e --------------
775 // -- r3 : value 745 // -- r3 : value
776 // -- r4 : key 746 // -- r4 : key
777 // -- r5 : receiver 747 // -- r5 : receiver
778 // -- lr : return address 748 // -- lr : return address
779 // ----------------------------------- 749 // -----------------------------------
780 Label slow, fast_object, fast_object_grow; 750 Label slow, fast_object, fast_object_grow;
781 Label fast_double, fast_double_grow; 751 Label fast_double, fast_double_grow;
782 Label array, extra, check_if_double_array, maybe_name_key, miss; 752 Label array, extra, check_if_double_array, maybe_name_key, miss;
783 753
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 __ LoadP(ip, FieldMemOperand(elements, FixedArray::kLengthOffset)); 789 __ LoadP(ip, FieldMemOperand(elements, FixedArray::kLengthOffset));
820 __ cmpl(key, ip); 790 __ cmpl(key, ip);
821 __ blt(&fast_object); 791 __ blt(&fast_object);
822 792
823 // Slow case, handle jump to runtime. 793 // Slow case, handle jump to runtime.
824 __ bind(&slow); 794 __ bind(&slow);
825 // Entry registers are intact. 795 // Entry registers are intact.
826 // r3: value. 796 // r3: value.
827 // r4: key. 797 // r4: key.
828 // r5: receiver. 798 // r5: receiver.
829 PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode); 799 PropertyICCompiler::GenerateRuntimeSetProperty(masm, language_mode);
830 // Never returns to here. 800 // Never returns to here.
831 801
832 __ bind(&maybe_name_key); 802 __ bind(&maybe_name_key);
833 __ LoadP(r7, FieldMemOperand(key, HeapObject::kMapOffset)); 803 __ LoadP(r7, FieldMemOperand(key, HeapObject::kMapOffset));
834 __ lbz(r7, FieldMemOperand(r7, Map::kInstanceTypeOffset)); 804 __ lbz(r7, FieldMemOperand(r7, Map::kInstanceTypeOffset));
835 __ JumpIfNotUniqueNameInstanceType(r7, &slow); 805 __ JumpIfNotUniqueNameInstanceType(r7, &slow);
836 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( 806 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
837 Code::ComputeHandlerFlags(Code::STORE_IC)); 807 Code::ComputeHandlerFlags(Code::STORE_IC));
838 masm->isolate()->stub_cache()->GenerateProbe(masm, flags, false, receiver, 808 masm->isolate()->stub_cache()->GenerateProbe(
839 key, r6, r7, r8, r9); 809 masm, Code::STORE_IC, flags, false, receiver, key, r6, r7, r8, r9);
840 // Cache miss. 810 // Cache miss.
841 __ b(&miss); 811 __ b(&miss);
842 812
843 // Extra capacity case: Check if there is extra capacity to 813 // Extra capacity case: Check if there is extra capacity to
844 // perform the store and update the length. Used for adding one 814 // perform the store and update the length. Used for adding one
845 // element to the array by writing to array[array.length]. 815 // element to the array by writing to array[array.length].
846 __ bind(&extra); 816 __ bind(&extra);
847 // Condition code from comparing key and array length is still available. 817 // Condition code from comparing key and array length is still available.
848 __ bne(&slow); // Only support writing to writing to array[array.length]. 818 __ bne(&slow); // Only support writing to writing to array[array.length].
849 // Check for room in the elements backing store. 819 // Check for room in the elements backing store.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
890 Register receiver = StoreDescriptor::ReceiverRegister(); 860 Register receiver = StoreDescriptor::ReceiverRegister();
891 Register name = StoreDescriptor::NameRegister(); 861 Register name = StoreDescriptor::NameRegister();
892 DCHECK(receiver.is(r4)); 862 DCHECK(receiver.is(r4));
893 DCHECK(name.is(r5)); 863 DCHECK(name.is(r5));
894 DCHECK(StoreDescriptor::ValueRegister().is(r3)); 864 DCHECK(StoreDescriptor::ValueRegister().is(r3));
895 865
896 // Get the receiver from the stack and probe the stub cache. 866 // Get the receiver from the stack and probe the stub cache.
897 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( 867 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
898 Code::ComputeHandlerFlags(Code::STORE_IC)); 868 Code::ComputeHandlerFlags(Code::STORE_IC));
899 869
900 masm->isolate()->stub_cache()->GenerateProbe(masm, flags, false, receiver, 870 masm->isolate()->stub_cache()->GenerateProbe(
901 name, r6, r7, r8, r9); 871 masm, Code::STORE_IC, flags, false, receiver, name, r6, r7, r8, r9);
902 872
903 // Cache miss: Jump to runtime. 873 // Cache miss: Jump to runtime.
904 GenerateMiss(masm); 874 GenerateMiss(masm);
905 } 875 }
906 876
907 877
908 void StoreIC::GenerateMiss(MacroAssembler* masm) { 878 void StoreIC::GenerateMiss(MacroAssembler* masm) {
909 __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(), 879 __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(),
910 StoreDescriptor::ValueRegister()); 880 StoreDescriptor::ValueRegister());
911 881
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1038 patcher.EmitCondition(ne); 1008 patcher.EmitCondition(ne);
1039 } else { 1009 } else {
1040 DCHECK(Assembler::GetCondition(branch_instr) == ne); 1010 DCHECK(Assembler::GetCondition(branch_instr) == ne);
1041 patcher.EmitCondition(eq); 1011 patcher.EmitCondition(eq);
1042 } 1012 }
1043 } 1013 }
1044 } 1014 }
1045 } // namespace v8::internal 1015 } // namespace v8::internal
1046 1016
1047 #endif // V8_TARGET_ARCH_PPC 1017 #endif // V8_TARGET_ARCH_PPC
OLDNEW
« no previous file with comments | « src/ic/ppc/ic-compiler-ppc.cc ('k') | src/ic/ppc/stub-cache-ppc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698