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

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

Issue 1546323002: [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 | « src/ic/mips64/ic-mips64.cc ('k') | src/mips/macro-assembler-mips.h » ('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 #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 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow, 490 MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow,
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_value = r7; 500 Register scratch = r7;
501 Register scratch2 = r0;
501 Register address = r8; 502 Register address = r8;
503 DCHECK(!AreAliased(value, key, receiver, receiver_map, elements_map, elements,
504 scratch, scratch2, address));
505
502 if (check_map == kCheckMap) { 506 if (check_map == kCheckMap) {
503 __ LoadP(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset)); 507 __ LoadP(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
504 __ mov(scratch_value, 508 __ mov(scratch, Operand(masm->isolate()->factory()->fixed_array_map()));
505 Operand(masm->isolate()->factory()->fixed_array_map())); 509 __ cmp(elements_map, scratch);
506 __ cmp(elements_map, scratch_value);
507 __ bne(fast_double); 510 __ bne(fast_double);
508 } 511 }
509 512
510 // HOLECHECK: guards "A[i] = V" 513 // HOLECHECK: guards "A[i] = V"
511 // We have to go to the runtime if the current value is the hole because 514 // We have to go to the runtime if the current value is the hole because
512 // there may be a callback on the element 515 // there may be a callback on the element
513 Label holecheck_passed1; 516 Label holecheck_passed1;
514 __ addi(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 517 __ addi(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
515 __ SmiToPtrArrayOffset(scratch_value, key); 518 __ SmiToPtrArrayOffset(scratch, key);
516 __ LoadPX(scratch_value, MemOperand(address, scratch_value)); 519 __ LoadPX(scratch, MemOperand(address, scratch));
517 __ Cmpi(scratch_value, Operand(masm->isolate()->factory()->the_hole_value()), 520 __ Cmpi(scratch, Operand(masm->isolate()->factory()->the_hole_value()),
518 r0); 521 scratch2);
519 __ bne(&holecheck_passed1); 522 __ bne(&holecheck_passed1);
520 __ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch_value, 523 __ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch, slow);
521 slow);
522 524
523 __ bind(&holecheck_passed1); 525 __ bind(&holecheck_passed1);
524 526
525 // Smi stores don't require further checks. 527 // Smi stores don't require further checks.
526 Label non_smi_value; 528 Label non_smi_value;
527 __ JumpIfNotSmi(value, &non_smi_value); 529 __ JumpIfNotSmi(value, &non_smi_value);
528 530
529 if (increment_length == kIncrementLength) { 531 if (increment_length == kIncrementLength) {
530 // Add 1 to receiver->length. 532 // Add 1 to receiver->length.
531 __ AddSmiLiteral(scratch_value, key, Smi::FromInt(1), r0); 533 __ AddSmiLiteral(scratch, key, Smi::FromInt(1), scratch2);
532 __ StoreP(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset), 534 __ StoreP(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset),
533 r0); 535 scratch2);
534 } 536 }
535 // It's irrelevant whether array is smi-only or not when writing a smi. 537 // It's irrelevant whether array is smi-only or not when writing a smi.
536 __ addi(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 538 __ addi(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
537 __ SmiToPtrArrayOffset(scratch_value, key); 539 __ SmiToPtrArrayOffset(scratch, key);
538 __ StorePX(value, MemOperand(address, scratch_value)); 540 __ StorePX(value, MemOperand(address, scratch));
539 __ Ret(); 541 __ Ret();
540 542
541 __ bind(&non_smi_value); 543 __ bind(&non_smi_value);
542 // Escape to elements kind transition case. 544 // Escape to elements kind transition case.
543 __ CheckFastObjectElements(receiver_map, scratch_value, 545 __ CheckFastObjectElements(receiver_map, scratch, &transition_smi_elements);
544 &transition_smi_elements);
545 546
546 // Fast elements array, store the value to the elements backing store. 547 // Fast elements array, store the value to the elements backing store.
547 __ bind(&finish_object_store); 548 __ bind(&finish_object_store);
548 if (increment_length == kIncrementLength) { 549 if (increment_length == kIncrementLength) {
549 // Add 1 to receiver->length. 550 // Add 1 to receiver->length.
550 __ AddSmiLiteral(scratch_value, key, Smi::FromInt(1), r0); 551 __ AddSmiLiteral(scratch, key, Smi::FromInt(1), scratch2);
551 __ StoreP(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset), 552 __ StoreP(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset),
552 r0); 553 scratch2);
553 } 554 }
554 __ addi(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 555 __ addi(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
555 __ SmiToPtrArrayOffset(scratch_value, key); 556 __ SmiToPtrArrayOffset(scratch, key);
556 __ StorePUX(value, MemOperand(address, scratch_value)); 557 __ StorePUX(value, MemOperand(address, scratch));
557 // Update write barrier for the elements array address. 558 // Update write barrier for the elements array address.
558 __ mr(scratch_value, value); // Preserve the value which is returned. 559 __ mr(scratch, value); // Preserve the value which is returned.
559 __ RecordWrite(elements, address, scratch_value, kLRHasNotBeenSaved, 560 __ RecordWrite(elements, address, scratch, kLRHasNotBeenSaved,
560 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 561 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
561 __ Ret(); 562 __ Ret();
562 563
563 __ bind(fast_double); 564 __ bind(fast_double);
564 if (check_map == kCheckMap) { 565 if (check_map == kCheckMap) {
565 // Check for fast double array case. If this fails, call through to the 566 // Check for fast double array case. If this fails, call through to the
566 // runtime. 567 // runtime.
567 __ CompareRoot(elements_map, Heap::kFixedDoubleArrayMapRootIndex); 568 __ CompareRoot(elements_map, Heap::kFixedDoubleArrayMapRootIndex);
568 __ bne(slow); 569 __ bne(slow);
569 } 570 }
570 571
571 // HOLECHECK: guards "A[i] double hole?" 572 // HOLECHECK: guards "A[i] double hole?"
572 // We have to see if the double version of the hole is present. If so 573 // We have to see if the double version of the hole is present. If so
573 // go to the runtime. 574 // go to the runtime.
574 __ addi(address, elements, 575 __ addi(address, elements,
575 Operand((FixedDoubleArray::kHeaderSize + Register::kExponentOffset - 576 Operand((FixedDoubleArray::kHeaderSize + Register::kExponentOffset -
576 kHeapObjectTag))); 577 kHeapObjectTag)));
577 __ SmiToDoubleArrayOffset(scratch_value, key); 578 __ SmiToDoubleArrayOffset(scratch, key);
578 __ lwzx(scratch_value, MemOperand(address, scratch_value)); 579 __ lwzx(scratch, MemOperand(address, scratch));
579 __ Cmpi(scratch_value, Operand(kHoleNanUpper32), r0); 580 __ Cmpi(scratch, Operand(kHoleNanUpper32), scratch2);
580 __ bne(&fast_double_without_map_check); 581 __ bne(&fast_double_without_map_check);
581 __ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch_value, 582 __ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch, slow);
582 slow);
583 583
584 __ bind(&fast_double_without_map_check); 584 __ bind(&fast_double_without_map_check);
585 __ StoreNumberToDoubleElements(value, key, elements, r6, d0, 585 __ StoreNumberToDoubleElements(value, key, elements, scratch, d0,
586 &transition_double_elements); 586 &transition_double_elements);
587 if (increment_length == kIncrementLength) { 587 if (increment_length == kIncrementLength) {
588 // Add 1 to receiver->length. 588 // Add 1 to receiver->length.
589 __ AddSmiLiteral(scratch_value, key, Smi::FromInt(1), r0); 589 __ AddSmiLiteral(scratch, key, Smi::FromInt(1), scratch2);
590 __ StoreP(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset), 590 __ StoreP(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset),
591 r0); 591 scratch2);
592 } 592 }
593 __ Ret(); 593 __ Ret();
594 594
595 __ bind(&transition_smi_elements); 595 __ bind(&transition_smi_elements);
596 // Transition the array appropriately depending on the value type. 596 // Transition the array appropriately depending on the value type.
597 __ LoadP(r7, FieldMemOperand(value, HeapObject::kMapOffset)); 597 __ LoadP(r7, FieldMemOperand(value, HeapObject::kMapOffset));
598 __ CompareRoot(r7, Heap::kHeapNumberMapRootIndex); 598 __ CompareRoot(r7, Heap::kHeapNumberMapRootIndex);
599 __ bne(&non_double_value); 599 __ bne(&non_double_value);
600 600
601 // Value is a double. Transition FAST_SMI_ELEMENTS -> 601 // Value is a double. Transition FAST_SMI_ELEMENTS ->
602 // FAST_DOUBLE_ELEMENTS and complete the store. 602 // FAST_DOUBLE_ELEMENTS and complete the store.
603 __ LoadTransitionedArrayMapConditional( 603 __ LoadTransitionedArrayMapConditional(
604 FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, receiver_map, r7, slow); 604 FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, receiver_map, scratch, slow);
605 AllocationSiteMode mode = 605 AllocationSiteMode mode =
606 AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS); 606 AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS);
607 ElementsTransitionGenerator::GenerateSmiToDouble(masm, receiver, key, value, 607 ElementsTransitionGenerator::GenerateSmiToDouble(masm, receiver, key, value,
608 receiver_map, mode, slow); 608 receiver_map, mode, slow);
609 __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); 609 __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
610 __ b(&fast_double_without_map_check); 610 __ b(&fast_double_without_map_check);
611 611
612 __ bind(&non_double_value); 612 __ bind(&non_double_value);
613 // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS 613 // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
614 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, FAST_ELEMENTS, 614 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, FAST_ELEMENTS,
615 receiver_map, r7, slow); 615 receiver_map, scratch, slow);
616 mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS); 616 mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS);
617 ElementsTransitionGenerator::GenerateMapChangeElementsTransition( 617 ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
618 masm, receiver, key, value, receiver_map, mode, slow); 618 masm, receiver, key, value, receiver_map, mode, slow);
619 __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); 619 __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
620 __ b(&finish_object_store); 620 __ b(&finish_object_store);
621 621
622 __ bind(&transition_double_elements); 622 __ bind(&transition_double_elements);
623 // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a 623 // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
624 // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and 624 // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
625 // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS 625 // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
626 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS, 626 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS,
627 receiver_map, r7, slow); 627 receiver_map, scratch, slow);
628 mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS); 628 mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS);
629 ElementsTransitionGenerator::GenerateDoubleToObject( 629 ElementsTransitionGenerator::GenerateDoubleToObject(
630 masm, receiver, key, value, receiver_map, mode, slow); 630 masm, receiver, key, value, receiver_map, mode, slow);
631 __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); 631 __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
632 __ b(&finish_object_store); 632 __ b(&finish_object_store);
633 } 633 }
634 634
635 635
636 void KeyedStoreIC::GenerateMegamorphic(MacroAssembler* masm, 636 void KeyedStoreIC::GenerateMegamorphic(MacroAssembler* masm,
637 LanguageMode language_mode) { 637 LanguageMode language_mode) {
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
911 patcher.EmitCondition(ne); 911 patcher.EmitCondition(ne);
912 } else { 912 } else {
913 DCHECK(Assembler::GetCondition(branch_instr) == ne); 913 DCHECK(Assembler::GetCondition(branch_instr) == ne);
914 patcher.EmitCondition(eq); 914 patcher.EmitCondition(eq);
915 } 915 }
916 } 916 }
917 } // namespace internal 917 } // namespace internal
918 } // namespace v8 918 } // namespace v8
919 919
920 #endif // V8_TARGET_ARCH_PPC 920 #endif // V8_TARGET_ARCH_PPC
OLDNEW
« no previous file with comments | « src/ic/mips64/ic-mips64.cc ('k') | src/mips/macro-assembler-mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698