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

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

Issue 1556643002: PPC: Refine "[ic] Fixed receiver_map register trashing in KeyedStoreIC megamorphic." (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 11 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 | « no previous file | no next file » | 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 #if V8_TARGET_ARCH_PPC 5 #if V8_TARGET_ARCH_PPC
6 6
7 #include "src/codegen.h" 7 #include "src/codegen.h"
8 #include "src/ic/ic.h" 8 #include "src/ic/ic.h"
9 #include "src/ic/ic-compiler.h" 9 #include "src/ic/ic-compiler.h"
10 #include "src/ic/stub-cache.h" 10 #include "src/ic/stub-cache.h"
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length, 491 KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length,
492 Register value, Register key, Register receiver, Register receiver_map, 492 Register value, Register key, Register receiver, Register receiver_map,
493 Register elements_map, Register elements) { 493 Register elements_map, Register elements) {
494 Label transition_smi_elements; 494 Label transition_smi_elements;
495 Label finish_object_store, non_double_value, transition_double_elements; 495 Label finish_object_store, non_double_value, transition_double_elements;
496 Label fast_double_without_map_check; 496 Label fast_double_without_map_check;
497 497
498 // Fast case: Do the store, could be either Object or double. 498 // Fast case: Do the store, could be either Object or double.
499 __ bind(fast_object); 499 __ bind(fast_object);
500 Register scratch = r7; 500 Register scratch = r7;
501 Register scratch2 = r0;
502 Register address = r8; 501 Register address = r8;
503 DCHECK(!AreAliased(value, key, receiver, receiver_map, elements_map, elements, 502 DCHECK(!AreAliased(value, key, receiver, receiver_map, elements_map, elements,
504 scratch, scratch2, address)); 503 scratch, address));
505 504
506 if (check_map == kCheckMap) { 505 if (check_map == kCheckMap) {
507 __ LoadP(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset)); 506 __ LoadP(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
508 __ mov(scratch, Operand(masm->isolate()->factory()->fixed_array_map())); 507 __ mov(scratch, Operand(masm->isolate()->factory()->fixed_array_map()));
509 __ cmp(elements_map, scratch); 508 __ cmp(elements_map, scratch);
510 __ bne(fast_double); 509 __ bne(fast_double);
511 } 510 }
512 511
513 // HOLECHECK: guards "A[i] = V" 512 // HOLECHECK: guards "A[i] = V"
514 // We have to go to the runtime if the current value is the hole because 513 // We have to go to the runtime if the current value is the hole because
515 // there may be a callback on the element 514 // there may be a callback on the element
516 Label holecheck_passed1; 515 Label holecheck_passed1;
517 __ addi(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 516 __ addi(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
518 __ SmiToPtrArrayOffset(scratch, key); 517 __ SmiToPtrArrayOffset(scratch, key);
519 __ LoadPX(scratch, MemOperand(address, scratch)); 518 __ LoadPX(scratch, MemOperand(address, scratch));
520 __ Cmpi(scratch, Operand(masm->isolate()->factory()->the_hole_value()), 519 __ Cmpi(scratch, Operand(masm->isolate()->factory()->the_hole_value()), r0);
521 scratch2);
522 __ bne(&holecheck_passed1); 520 __ bne(&holecheck_passed1);
523 __ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch, slow); 521 __ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch, slow);
524 522
525 __ bind(&holecheck_passed1); 523 __ bind(&holecheck_passed1);
526 524
527 // Smi stores don't require further checks. 525 // Smi stores don't require further checks.
528 Label non_smi_value; 526 Label non_smi_value;
529 __ JumpIfNotSmi(value, &non_smi_value); 527 __ JumpIfNotSmi(value, &non_smi_value);
530 528
531 if (increment_length == kIncrementLength) { 529 if (increment_length == kIncrementLength) {
532 // Add 1 to receiver->length. 530 // Add 1 to receiver->length.
533 __ AddSmiLiteral(scratch, key, Smi::FromInt(1), scratch2); 531 __ AddSmiLiteral(scratch, key, Smi::FromInt(1), r0);
534 __ StoreP(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset), 532 __ StoreP(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset), r0);
535 scratch2);
536 } 533 }
537 // It's irrelevant whether array is smi-only or not when writing a smi. 534 // It's irrelevant whether array is smi-only or not when writing a smi.
538 __ addi(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 535 __ addi(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
539 __ SmiToPtrArrayOffset(scratch, key); 536 __ SmiToPtrArrayOffset(scratch, key);
540 __ StorePX(value, MemOperand(address, scratch)); 537 __ StorePX(value, MemOperand(address, scratch));
541 __ Ret(); 538 __ Ret();
542 539
543 __ bind(&non_smi_value); 540 __ bind(&non_smi_value);
544 // Escape to elements kind transition case. 541 // Escape to elements kind transition case.
545 __ CheckFastObjectElements(receiver_map, scratch, &transition_smi_elements); 542 __ CheckFastObjectElements(receiver_map, scratch, &transition_smi_elements);
546 543
547 // Fast elements array, store the value to the elements backing store. 544 // Fast elements array, store the value to the elements backing store.
548 __ bind(&finish_object_store); 545 __ bind(&finish_object_store);
549 if (increment_length == kIncrementLength) { 546 if (increment_length == kIncrementLength) {
550 // Add 1 to receiver->length. 547 // Add 1 to receiver->length.
551 __ AddSmiLiteral(scratch, key, Smi::FromInt(1), scratch2); 548 __ AddSmiLiteral(scratch, key, Smi::FromInt(1), r0);
552 __ StoreP(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset), 549 __ StoreP(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset), r0);
553 scratch2);
554 } 550 }
555 __ addi(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 551 __ addi(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
556 __ SmiToPtrArrayOffset(scratch, key); 552 __ SmiToPtrArrayOffset(scratch, key);
557 __ StorePUX(value, MemOperand(address, scratch)); 553 __ StorePUX(value, MemOperand(address, scratch));
558 // Update write barrier for the elements array address. 554 // Update write barrier for the elements array address.
559 __ mr(scratch, value); // Preserve the value which is returned. 555 __ mr(scratch, value); // Preserve the value which is returned.
560 __ RecordWrite(elements, address, scratch, kLRHasNotBeenSaved, 556 __ RecordWrite(elements, address, scratch, kLRHasNotBeenSaved,
561 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 557 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
562 __ Ret(); 558 __ Ret();
563 559
564 __ bind(fast_double); 560 __ bind(fast_double);
565 if (check_map == kCheckMap) { 561 if (check_map == kCheckMap) {
566 // Check for fast double array case. If this fails, call through to the 562 // Check for fast double array case. If this fails, call through to the
567 // runtime. 563 // runtime.
568 __ CompareRoot(elements_map, Heap::kFixedDoubleArrayMapRootIndex); 564 __ CompareRoot(elements_map, Heap::kFixedDoubleArrayMapRootIndex);
569 __ bne(slow); 565 __ bne(slow);
570 } 566 }
571 567
572 // HOLECHECK: guards "A[i] double hole?" 568 // HOLECHECK: guards "A[i] double hole?"
573 // We have to see if the double version of the hole is present. If so 569 // We have to see if the double version of the hole is present. If so
574 // go to the runtime. 570 // go to the runtime.
575 __ addi(address, elements, 571 __ addi(address, elements,
576 Operand((FixedDoubleArray::kHeaderSize + Register::kExponentOffset - 572 Operand((FixedDoubleArray::kHeaderSize + Register::kExponentOffset -
577 kHeapObjectTag))); 573 kHeapObjectTag)));
578 __ SmiToDoubleArrayOffset(scratch, key); 574 __ SmiToDoubleArrayOffset(scratch, key);
579 __ lwzx(scratch, MemOperand(address, scratch)); 575 __ lwzx(scratch, MemOperand(address, scratch));
580 __ Cmpi(scratch, Operand(kHoleNanUpper32), scratch2); 576 __ Cmpi(scratch, Operand(kHoleNanUpper32), r0);
581 __ bne(&fast_double_without_map_check); 577 __ bne(&fast_double_without_map_check);
582 __ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch, slow); 578 __ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch, slow);
583 579
584 __ bind(&fast_double_without_map_check); 580 __ bind(&fast_double_without_map_check);
585 __ StoreNumberToDoubleElements(value, key, elements, scratch, d0, 581 __ StoreNumberToDoubleElements(value, key, elements, scratch, d0,
586 &transition_double_elements); 582 &transition_double_elements);
587 if (increment_length == kIncrementLength) { 583 if (increment_length == kIncrementLength) {
588 // Add 1 to receiver->length. 584 // Add 1 to receiver->length.
589 __ AddSmiLiteral(scratch, key, Smi::FromInt(1), scratch2); 585 __ AddSmiLiteral(scratch, key, Smi::FromInt(1), r0);
590 __ StoreP(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset), 586 __ StoreP(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset), r0);
591 scratch2);
592 } 587 }
593 __ Ret(); 588 __ Ret();
594 589
595 __ bind(&transition_smi_elements); 590 __ bind(&transition_smi_elements);
596 // Transition the array appropriately depending on the value type. 591 // Transition the array appropriately depending on the value type.
597 __ LoadP(r7, FieldMemOperand(value, HeapObject::kMapOffset)); 592 __ LoadP(scratch, FieldMemOperand(value, HeapObject::kMapOffset));
598 __ CompareRoot(r7, Heap::kHeapNumberMapRootIndex); 593 __ CompareRoot(scratch, Heap::kHeapNumberMapRootIndex);
599 __ bne(&non_double_value); 594 __ bne(&non_double_value);
600 595
601 // Value is a double. Transition FAST_SMI_ELEMENTS -> 596 // Value is a double. Transition FAST_SMI_ELEMENTS ->
602 // FAST_DOUBLE_ELEMENTS and complete the store. 597 // FAST_DOUBLE_ELEMENTS and complete the store.
603 __ LoadTransitionedArrayMapConditional( 598 __ LoadTransitionedArrayMapConditional(
604 FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, receiver_map, scratch, slow); 599 FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, receiver_map, scratch, slow);
605 AllocationSiteMode mode = 600 AllocationSiteMode mode =
606 AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS); 601 AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS);
607 ElementsTransitionGenerator::GenerateSmiToDouble(masm, receiver, key, value, 602 ElementsTransitionGenerator::GenerateSmiToDouble(masm, receiver, key, value,
608 receiver_map, mode, slow); 603 receiver_map, mode, slow);
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
911 patcher.EmitCondition(ne); 906 patcher.EmitCondition(ne);
912 } else { 907 } else {
913 DCHECK(Assembler::GetCondition(branch_instr) == ne); 908 DCHECK(Assembler::GetCondition(branch_instr) == ne);
914 patcher.EmitCondition(eq); 909 patcher.EmitCondition(eq);
915 } 910 }
916 } 911 }
917 } // namespace internal 912 } // namespace internal
918 } // namespace v8 913 } // namespace v8
919 914
920 #endif // V8_TARGET_ARCH_PPC 915 #endif // V8_TARGET_ARCH_PPC
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698