| OLD | NEW |
| 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 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
| 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 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS, | 559 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS, |
| 560 rbx, rdi, slow); | 560 rbx, rdi, slow); |
| 561 mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS); | 561 mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS); |
| 562 ElementsTransitionGenerator::GenerateDoubleToObject(masm, receiver, key, | 562 ElementsTransitionGenerator::GenerateDoubleToObject(masm, receiver, key, |
| 563 value, rbx, mode, slow); | 563 value, rbx, mode, slow); |
| 564 __ movp(rbx, FieldOperand(receiver, JSObject::kElementsOffset)); | 564 __ movp(rbx, FieldOperand(receiver, JSObject::kElementsOffset)); |
| 565 __ jmp(&finish_object_store); | 565 __ jmp(&finish_object_store); |
| 566 } | 566 } |
| 567 | 567 |
| 568 | 568 |
| 569 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, | 569 void KeyedStoreIC::GenerateGeneric( |
| 570 StrictMode strict_mode) { | 570 MacroAssembler* masm, StrictMode strict_mode, |
| 571 KeyedStoreStubCacheRequirement handler_requirement) { |
| 571 // Return address is on the stack. | 572 // Return address is on the stack. |
| 572 Label slow, slow_with_tagged_index, fast_object, fast_object_grow; | 573 Label slow, slow_with_tagged_index, fast_object, fast_object_grow; |
| 573 Label fast_double, fast_double_grow; | 574 Label fast_double, fast_double_grow; |
| 574 Label array, extra, check_if_double_array; | 575 Label array, extra, check_if_double_array, maybe_name_key, miss; |
| 575 Register receiver = StoreDescriptor::ReceiverRegister(); | 576 Register receiver = StoreDescriptor::ReceiverRegister(); |
| 576 Register key = StoreDescriptor::NameRegister(); | 577 Register key = StoreDescriptor::NameRegister(); |
| 577 DCHECK(receiver.is(rdx)); | 578 DCHECK(receiver.is(rdx)); |
| 578 DCHECK(key.is(rcx)); | 579 DCHECK(key.is(rcx)); |
| 579 | 580 |
| 580 // Check that the object isn't a smi. | 581 // Check that the object isn't a smi. |
| 581 __ JumpIfSmi(receiver, &slow_with_tagged_index); | 582 __ JumpIfSmi(receiver, &slow_with_tagged_index); |
| 582 // Get the map from the receiver. | 583 // Get the map from the receiver. |
| 583 __ movp(r9, FieldOperand(receiver, HeapObject::kMapOffset)); | 584 __ movp(r9, FieldOperand(receiver, HeapObject::kMapOffset)); |
| 584 // Check that the receiver does not require access checks and is not observed. | 585 // Check that the receiver does not require access checks and is not observed. |
| 585 // The generic stub does not perform map checks or handle observed objects. | 586 // The generic stub does not perform map checks or handle observed objects. |
| 586 __ testb(FieldOperand(r9, Map::kBitFieldOffset), | 587 __ testb(FieldOperand(r9, Map::kBitFieldOffset), |
| 587 Immediate(1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved)); | 588 Immediate(1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved)); |
| 588 __ j(not_zero, &slow_with_tagged_index); | 589 __ j(not_zero, &slow_with_tagged_index); |
| 589 // Check that the key is a smi. | 590 // Check that the key is a smi. |
| 590 __ JumpIfNotSmi(key, &slow_with_tagged_index); | 591 __ JumpIfNotSmi(key, &maybe_name_key); |
| 591 __ SmiToInteger32(key, key); | 592 __ SmiToInteger32(key, key); |
| 592 | 593 |
| 593 __ CmpInstanceType(r9, JS_ARRAY_TYPE); | 594 __ CmpInstanceType(r9, JS_ARRAY_TYPE); |
| 594 __ j(equal, &array); | 595 __ j(equal, &array); |
| 595 // Check that the object is some kind of JSObject. | 596 // Check that the object is some kind of JSObject. |
| 596 __ CmpInstanceType(r9, FIRST_JS_OBJECT_TYPE); | 597 __ CmpInstanceType(r9, FIRST_JS_OBJECT_TYPE); |
| 597 __ j(below, &slow); | 598 __ j(below, &slow); |
| 598 | 599 |
| 599 // Object case: Check key against length in the elements array. | 600 // Object case: Check key against length in the elements array. |
| 600 __ movp(rbx, FieldOperand(receiver, JSObject::kElementsOffset)); | 601 __ movp(rbx, FieldOperand(receiver, JSObject::kElementsOffset)); |
| 601 // Check array bounds. | 602 // Check array bounds. |
| 602 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), key); | 603 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), key); |
| 603 // rbx: FixedArray | 604 // rbx: FixedArray |
| 604 __ j(above, &fast_object); | 605 __ j(above, &fast_object); |
| 605 | 606 |
| 606 // Slow case: call runtime. | 607 // Slow case: call runtime. |
| 607 __ bind(&slow); | 608 __ bind(&slow); |
| 608 __ Integer32ToSmi(key, key); | 609 __ Integer32ToSmi(key, key); |
| 609 __ bind(&slow_with_tagged_index); | 610 __ bind(&slow_with_tagged_index); |
| 610 PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode); | 611 PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode); |
| 611 // Never returns to here. | 612 // Never returns to here. |
| 612 | 613 |
| 614 __ bind(&maybe_name_key); |
| 615 __ movp(r9, FieldOperand(key, HeapObject::kMapOffset)); |
| 616 __ movzxbp(r9, FieldOperand(r9, Map::kInstanceTypeOffset)); |
| 617 __ JumpIfNotUniqueNameInstanceType(r9, &slow_with_tagged_index); |
| 618 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
| 619 Code::ComputeHandlerFlags(Code::STORE_IC)); |
| 620 masm->isolate()->stub_cache()->GenerateProbe(masm, flags, false, receiver, |
| 621 key, rbx, no_reg); |
| 622 // Cache miss. |
| 623 if (handler_requirement == kCallRuntimeOnMissingHandler) { |
| 624 __ jmp(&slow_with_tagged_index); |
| 625 } else { |
| 626 DCHECK(handler_requirement == kMissOnMissingHandler); |
| 627 __ jmp(&miss); |
| 628 } |
| 629 |
| 613 // Extra capacity case: Check if there is extra capacity to | 630 // Extra capacity case: Check if there is extra capacity to |
| 614 // perform the store and update the length. Used for adding one | 631 // perform the store and update the length. Used for adding one |
| 615 // element to the array by writing to array[array.length]. | 632 // element to the array by writing to array[array.length]. |
| 616 __ bind(&extra); | 633 __ bind(&extra); |
| 617 // receiver is a JSArray. | 634 // receiver is a JSArray. |
| 618 // rbx: receiver's elements array (a FixedArray) | 635 // rbx: receiver's elements array (a FixedArray) |
| 619 // flags: smicompare (receiver.length(), rbx) | 636 // flags: smicompare (receiver.length(), rbx) |
| 620 __ j(not_equal, &slow); // do not leave holes in the array | 637 __ j(not_equal, &slow); // do not leave holes in the array |
| 621 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), key); | 638 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), key); |
| 622 __ j(below_equal, &slow); | 639 __ j(below_equal, &slow); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 641 | 658 |
| 642 // Check the key against the length in the array, compute the | 659 // Check the key against the length in the array, compute the |
| 643 // address to store into and fall through to fast case. | 660 // address to store into and fall through to fast case. |
| 644 __ SmiCompareInteger32(FieldOperand(receiver, JSArray::kLengthOffset), key); | 661 __ SmiCompareInteger32(FieldOperand(receiver, JSArray::kLengthOffset), key); |
| 645 __ j(below_equal, &extra); | 662 __ j(below_equal, &extra); |
| 646 | 663 |
| 647 KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double, &slow, | 664 KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double, &slow, |
| 648 kCheckMap, kDontIncrementLength); | 665 kCheckMap, kDontIncrementLength); |
| 649 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, | 666 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, |
| 650 &slow, kDontCheckMap, kIncrementLength); | 667 &slow, kDontCheckMap, kIncrementLength); |
| 668 |
| 669 if (handler_requirement == kMissOnMissingHandler) { |
| 670 __ bind(&miss); |
| 671 GenerateMiss(masm); |
| 672 } |
| 651 } | 673 } |
| 652 | 674 |
| 653 | 675 |
| 654 static Operand GenerateMappedArgumentsLookup( | 676 static Operand GenerateMappedArgumentsLookup( |
| 655 MacroAssembler* masm, Register object, Register key, Register scratch1, | 677 MacroAssembler* masm, Register object, Register key, Register scratch1, |
| 656 Register scratch2, Register scratch3, Label* unmapped_case, | 678 Register scratch2, Register scratch3, Label* unmapped_case, |
| 657 Label* slow_case) { | 679 Label* slow_case) { |
| 658 Heap* heap = masm->isolate()->heap(); | 680 Heap* heap = masm->isolate()->heap(); |
| 659 | 681 |
| 660 // Check that the receiver is a JSObject. Because of the elements | 682 // Check that the receiver is a JSObject. Because of the elements |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 981 Condition cc = | 1003 Condition cc = |
| 982 (check == ENABLE_INLINED_SMI_CHECK) | 1004 (check == ENABLE_INLINED_SMI_CHECK) |
| 983 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) | 1005 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) |
| 984 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); | 1006 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); |
| 985 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1007 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
| 986 } | 1008 } |
| 987 } | 1009 } |
| 988 } // namespace v8::internal | 1010 } // namespace v8::internal |
| 989 | 1011 |
| 990 #endif // V8_TARGET_ARCH_X64 | 1012 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |