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

Side by Side Diff: src/ic/mips64/ic-mips64.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, 12 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/mips/ic-mips.cc ('k') | src/ic/ppc/ic-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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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_MIPS64 5 #if V8_TARGET_ARCH_MIPS64
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 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow, 467 MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow,
468 KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length, 468 KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length,
469 Register value, Register key, Register receiver, Register receiver_map, 469 Register value, Register key, Register receiver, Register receiver_map,
470 Register elements_map, Register elements) { 470 Register elements_map, Register elements) {
471 Label transition_smi_elements; 471 Label transition_smi_elements;
472 Label finish_object_store, non_double_value, transition_double_elements; 472 Label finish_object_store, non_double_value, transition_double_elements;
473 Label fast_double_without_map_check; 473 Label fast_double_without_map_check;
474 474
475 // Fast case: Do the store, could be either Object or double. 475 // Fast case: Do the store, could be either Object or double.
476 __ bind(fast_object); 476 __ bind(fast_object);
477 Register scratch_value = a4; 477 Register scratch = a4;
478 Register scratch2 = t0;
478 Register address = a5; 479 Register address = a5;
480 DCHECK(!AreAliased(value, key, receiver, receiver_map, elements_map, elements,
481 scratch, scratch2, address));
482
479 if (check_map == kCheckMap) { 483 if (check_map == kCheckMap) {
480 __ ld(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset)); 484 __ ld(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
481 __ Branch(fast_double, ne, elements_map, 485 __ Branch(fast_double, ne, elements_map,
482 Operand(masm->isolate()->factory()->fixed_array_map())); 486 Operand(masm->isolate()->factory()->fixed_array_map()));
483 } 487 }
484 488
485 // HOLECHECK: guards "A[i] = V" 489 // HOLECHECK: guards "A[i] = V"
486 // We have to go to the runtime if the current value is the hole because 490 // We have to go to the runtime if the current value is the hole because
487 // there may be a callback on the element. 491 // there may be a callback on the element.
488 Label holecheck_passed1; 492 Label holecheck_passed1;
489 __ Daddu(address, elements, FixedArray::kHeaderSize - kHeapObjectTag); 493 __ Daddu(address, elements, FixedArray::kHeaderSize - kHeapObjectTag);
490 __ SmiScale(at, key, kPointerSizeLog2); 494 __ SmiScale(at, key, kPointerSizeLog2);
491 __ daddu(address, address, at); 495 __ daddu(address, address, at);
492 __ ld(scratch_value, MemOperand(address)); 496 __ ld(scratch, MemOperand(address));
493 497
494 __ Branch(&holecheck_passed1, ne, scratch_value, 498 __ Branch(&holecheck_passed1, ne, scratch,
495 Operand(masm->isolate()->factory()->the_hole_value())); 499 Operand(masm->isolate()->factory()->the_hole_value()));
496 __ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch_value, 500 __ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch, slow);
497 slow);
498 501
499 __ bind(&holecheck_passed1); 502 __ bind(&holecheck_passed1);
500 503
501 // Smi stores don't require further checks. 504 // Smi stores don't require further checks.
502 Label non_smi_value; 505 Label non_smi_value;
503 __ JumpIfNotSmi(value, &non_smi_value); 506 __ JumpIfNotSmi(value, &non_smi_value);
504 507
505 if (increment_length == kIncrementLength) { 508 if (increment_length == kIncrementLength) {
506 // Add 1 to receiver->length. 509 // Add 1 to receiver->length.
507 __ Daddu(scratch_value, key, Operand(Smi::FromInt(1))); 510 __ Daddu(scratch, key, Operand(Smi::FromInt(1)));
508 __ sd(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset)); 511 __ sd(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
509 } 512 }
510 // It's irrelevant whether array is smi-only or not when writing a smi. 513 // It's irrelevant whether array is smi-only or not when writing a smi.
511 __ Daddu(address, elements, 514 __ Daddu(address, elements,
512 Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 515 Operand(FixedArray::kHeaderSize - kHeapObjectTag));
513 __ SmiScale(scratch_value, key, kPointerSizeLog2); 516 __ SmiScale(scratch, key, kPointerSizeLog2);
514 __ Daddu(address, address, scratch_value); 517 __ Daddu(address, address, scratch);
515 __ sd(value, MemOperand(address)); 518 __ sd(value, MemOperand(address));
516 __ Ret(); 519 __ Ret();
517 520
518 __ bind(&non_smi_value); 521 __ bind(&non_smi_value);
519 // Escape to elements kind transition case. 522 // Escape to elements kind transition case.
520 __ CheckFastObjectElements(receiver_map, scratch_value, 523 __ CheckFastObjectElements(receiver_map, scratch, &transition_smi_elements);
521 &transition_smi_elements);
522 524
523 // Fast elements array, store the value to the elements backing store. 525 // Fast elements array, store the value to the elements backing store.
524 __ bind(&finish_object_store); 526 __ bind(&finish_object_store);
525 if (increment_length == kIncrementLength) { 527 if (increment_length == kIncrementLength) {
526 // Add 1 to receiver->length. 528 // Add 1 to receiver->length.
527 __ Daddu(scratch_value, key, Operand(Smi::FromInt(1))); 529 __ Daddu(scratch, key, Operand(Smi::FromInt(1)));
528 __ sd(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset)); 530 __ sd(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
529 } 531 }
530 __ Daddu(address, elements, 532 __ Daddu(address, elements,
531 Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 533 Operand(FixedArray::kHeaderSize - kHeapObjectTag));
532 __ SmiScale(scratch_value, key, kPointerSizeLog2); 534 __ SmiScale(scratch, key, kPointerSizeLog2);
533 __ Daddu(address, address, scratch_value); 535 __ Daddu(address, address, scratch);
534 __ sd(value, MemOperand(address)); 536 __ sd(value, MemOperand(address));
535 // Update write barrier for the elements array address. 537 // Update write barrier for the elements array address.
536 __ mov(scratch_value, value); // Preserve the value which is returned. 538 __ mov(scratch, value); // Preserve the value which is returned.
537 __ RecordWrite(elements, address, scratch_value, kRAHasNotBeenSaved, 539 __ RecordWrite(elements, address, scratch, kRAHasNotBeenSaved,
538 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 540 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
539 __ Ret(); 541 __ Ret();
540 542
541 __ bind(fast_double); 543 __ bind(fast_double);
542 if (check_map == kCheckMap) { 544 if (check_map == kCheckMap) {
543 // Check for fast double array case. If this fails, call through to the 545 // Check for fast double array case. If this fails, call through to the
544 // runtime. 546 // runtime.
545 __ LoadRoot(at, Heap::kFixedDoubleArrayMapRootIndex); 547 __ LoadRoot(at, Heap::kFixedDoubleArrayMapRootIndex);
546 __ Branch(slow, ne, elements_map, Operand(at)); 548 __ Branch(slow, ne, elements_map, Operand(at));
547 } 549 }
548 550
549 // HOLECHECK: guards "A[i] double hole?" 551 // HOLECHECK: guards "A[i] double hole?"
550 // We have to see if the double version of the hole is present. If so 552 // We have to see if the double version of the hole is present. If so
551 // go to the runtime. 553 // go to the runtime.
552 __ Daddu(address, elements, 554 __ Daddu(address, elements,
553 Operand(FixedDoubleArray::kHeaderSize + Register::kExponentOffset - 555 Operand(FixedDoubleArray::kHeaderSize + Register::kExponentOffset -
554 kHeapObjectTag)); 556 kHeapObjectTag));
555 __ SmiScale(at, key, kPointerSizeLog2); 557 __ SmiScale(at, key, kPointerSizeLog2);
556 __ daddu(address, address, at); 558 __ daddu(address, address, at);
557 __ lw(scratch_value, MemOperand(address)); 559 __ lw(scratch, MemOperand(address));
558 __ Branch(&fast_double_without_map_check, ne, scratch_value, 560 __ Branch(&fast_double_without_map_check, ne, scratch,
559 Operand(static_cast<int32_t>(kHoleNanUpper32))); 561 Operand(static_cast<int32_t>(kHoleNanUpper32)));
560 __ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch_value, 562 __ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch, slow);
561 slow);
562 563
563 __ bind(&fast_double_without_map_check); 564 __ bind(&fast_double_without_map_check);
564 __ StoreNumberToDoubleElements(value, key, 565 __ StoreNumberToDoubleElements(value, key, elements, scratch, scratch2,
565 elements, // Overwritten. 566 &transition_double_elements);
566 a3, // Scratch regs...
567 a4, &transition_double_elements);
568 if (increment_length == kIncrementLength) { 567 if (increment_length == kIncrementLength) {
569 // Add 1 to receiver->length. 568 // Add 1 to receiver->length.
570 __ Daddu(scratch_value, key, Operand(Smi::FromInt(1))); 569 __ Daddu(scratch, key, Operand(Smi::FromInt(1)));
571 __ sd(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset)); 570 __ sd(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
572 } 571 }
573 __ Ret(); 572 __ Ret();
574 573
575 __ bind(&transition_smi_elements); 574 __ bind(&transition_smi_elements);
576 // Transition the array appropriately depending on the value type. 575 // Transition the array appropriately depending on the value type.
577 __ ld(a4, FieldMemOperand(value, HeapObject::kMapOffset)); 576 __ ld(scratch, FieldMemOperand(value, HeapObject::kMapOffset));
578 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 577 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
579 __ Branch(&non_double_value, ne, a4, Operand(at)); 578 __ Branch(&non_double_value, ne, scratch, Operand(at));
580 579
581 // Value is a double. Transition FAST_SMI_ELEMENTS -> 580 // Value is a double. Transition FAST_SMI_ELEMENTS ->
582 // FAST_DOUBLE_ELEMENTS and complete the store. 581 // FAST_DOUBLE_ELEMENTS and complete the store.
583 __ LoadTransitionedArrayMapConditional( 582 __ LoadTransitionedArrayMapConditional(
584 FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, receiver_map, a4, slow); 583 FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, receiver_map, scratch, slow);
585 AllocationSiteMode mode = 584 AllocationSiteMode mode =
586 AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS); 585 AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS);
587 ElementsTransitionGenerator::GenerateSmiToDouble(masm, receiver, key, value, 586 ElementsTransitionGenerator::GenerateSmiToDouble(masm, receiver, key, value,
588 receiver_map, mode, slow); 587 receiver_map, mode, slow);
589 __ ld(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); 588 __ ld(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
590 __ jmp(&fast_double_without_map_check); 589 __ jmp(&fast_double_without_map_check);
591 590
592 __ bind(&non_double_value); 591 __ bind(&non_double_value);
593 // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS 592 // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
594 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, FAST_ELEMENTS, 593 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, FAST_ELEMENTS,
595 receiver_map, a4, slow); 594 receiver_map, scratch, slow);
596 mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS); 595 mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS);
597 ElementsTransitionGenerator::GenerateMapChangeElementsTransition( 596 ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
598 masm, receiver, key, value, receiver_map, mode, slow); 597 masm, receiver, key, value, receiver_map, mode, slow);
599 __ ld(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); 598 __ ld(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
600 __ jmp(&finish_object_store); 599 __ jmp(&finish_object_store);
601 600
602 __ bind(&transition_double_elements); 601 __ bind(&transition_double_elements);
603 // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a 602 // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
604 // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and 603 // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
605 // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS 604 // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
606 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS, 605 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS,
607 receiver_map, a4, slow); 606 receiver_map, scratch, slow);
608 mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS); 607 mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS);
609 ElementsTransitionGenerator::GenerateDoubleToObject( 608 ElementsTransitionGenerator::GenerateDoubleToObject(
610 masm, receiver, key, value, receiver_map, mode, slow); 609 masm, receiver, key, value, receiver_map, mode, slow);
611 __ ld(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); 610 __ ld(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
612 __ jmp(&finish_object_store); 611 __ jmp(&finish_object_store);
613 } 612 }
614 613
615 614
616 void KeyedStoreIC::GenerateMegamorphic(MacroAssembler* masm, 615 void KeyedStoreIC::GenerateMegamorphic(MacroAssembler* masm,
617 LanguageMode language_mode) { 616 LanguageMode language_mode) {
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
894 patcher.ChangeBranchCondition(ne); 893 patcher.ChangeBranchCondition(ne);
895 } else { 894 } else {
896 DCHECK(Assembler::IsBne(branch_instr)); 895 DCHECK(Assembler::IsBne(branch_instr));
897 patcher.ChangeBranchCondition(eq); 896 patcher.ChangeBranchCondition(eq);
898 } 897 }
899 } 898 }
900 } // namespace internal 899 } // namespace internal
901 } // namespace v8 900 } // namespace v8
902 901
903 #endif // V8_TARGET_ARCH_MIPS64 902 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/ic/mips/ic-mips.cc ('k') | src/ic/ppc/ic-ppc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698