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

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

Powered by Google App Engine
This is Rietveld 408576698