| 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_X87 | 7 #if V8_TARGET_ARCH_X87 |
| 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 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 return FieldOperand(backing_store, key, times_half_pointer_size, | 305 return FieldOperand(backing_store, key, times_half_pointer_size, |
| 306 FixedArray::kHeaderSize); | 306 FixedArray::kHeaderSize); |
| 307 } | 307 } |
| 308 | 308 |
| 309 | 309 |
| 310 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { | 310 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { |
| 311 // The return address is on the stack. | 311 // The return address is on the stack. |
| 312 Label slow, check_name, index_smi, index_name, property_array_property; | 312 Label slow, check_name, index_smi, index_name, property_array_property; |
| 313 Label probe_dictionary, check_number_dictionary; | 313 Label probe_dictionary, check_number_dictionary; |
| 314 | 314 |
| 315 Register receiver = LoadConvention::ReceiverRegister(); | 315 Register receiver = LoadDescriptor::ReceiverRegister(); |
| 316 Register key = LoadConvention::NameRegister(); | 316 Register key = LoadDescriptor::NameRegister(); |
| 317 DCHECK(receiver.is(edx)); | 317 DCHECK(receiver.is(edx)); |
| 318 DCHECK(key.is(ecx)); | 318 DCHECK(key.is(ecx)); |
| 319 | 319 |
| 320 // Check that the key is a smi. | 320 // Check that the key is a smi. |
| 321 __ JumpIfNotSmi(key, &check_name); | 321 __ JumpIfNotSmi(key, &check_name); |
| 322 __ bind(&index_smi); | 322 __ bind(&index_smi); |
| 323 // Now the key is known to be a smi. This place is also jumped to from | 323 // Now the key is known to be a smi. This place is also jumped to from |
| 324 // where a numeric string is converted to a smi. | 324 // where a numeric string is converted to a smi. |
| 325 | 325 |
| 326 GenerateKeyedLoadReceiverCheck(masm, receiver, eax, | 326 GenerateKeyedLoadReceiverCheck(masm, receiver, eax, |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 __ IndexFromHash(ebx, key); | 475 __ IndexFromHash(ebx, key); |
| 476 // Now jump to the place where smi keys are handled. | 476 // Now jump to the place where smi keys are handled. |
| 477 __ jmp(&index_smi); | 477 __ jmp(&index_smi); |
| 478 } | 478 } |
| 479 | 479 |
| 480 | 480 |
| 481 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { | 481 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { |
| 482 // Return address is on the stack. | 482 // Return address is on the stack. |
| 483 Label miss; | 483 Label miss; |
| 484 | 484 |
| 485 Register receiver = LoadConvention::ReceiverRegister(); | 485 Register receiver = LoadDescriptor::ReceiverRegister(); |
| 486 Register index = LoadConvention::NameRegister(); | 486 Register index = LoadDescriptor::NameRegister(); |
| 487 Register scratch = ebx; | 487 Register scratch = ebx; |
| 488 DCHECK(!scratch.is(receiver) && !scratch.is(index)); | 488 DCHECK(!scratch.is(receiver) && !scratch.is(index)); |
| 489 Register result = eax; | 489 Register result = eax; |
| 490 DCHECK(!result.is(scratch)); | 490 DCHECK(!result.is(scratch)); |
| 491 | 491 |
| 492 StringCharAtGenerator char_at_generator(receiver, index, scratch, result, | 492 StringCharAtGenerator char_at_generator(receiver, index, scratch, result, |
| 493 &miss, // When not a string. | 493 &miss, // When not a string. |
| 494 &miss, // When not a number. | 494 &miss, // When not a number. |
| 495 &miss, // When index out of range. | 495 &miss, // When index out of range. |
| 496 STRING_INDEX_IS_ARRAY_INDEX); | 496 STRING_INDEX_IS_ARRAY_INDEX); |
| 497 char_at_generator.GenerateFast(masm); | 497 char_at_generator.GenerateFast(masm); |
| 498 __ ret(0); | 498 __ ret(0); |
| 499 | 499 |
| 500 StubRuntimeCallHelper call_helper; | 500 StubRuntimeCallHelper call_helper; |
| 501 char_at_generator.GenerateSlow(masm, call_helper); | 501 char_at_generator.GenerateSlow(masm, call_helper); |
| 502 | 502 |
| 503 __ bind(&miss); | 503 __ bind(&miss); |
| 504 GenerateMiss(masm); | 504 GenerateMiss(masm); |
| 505 } | 505 } |
| 506 | 506 |
| 507 | 507 |
| 508 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { | 508 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { |
| 509 // Return address is on the stack. | 509 // Return address is on the stack. |
| 510 Label slow; | 510 Label slow; |
| 511 | 511 |
| 512 Register receiver = LoadConvention::ReceiverRegister(); | 512 Register receiver = LoadDescriptor::ReceiverRegister(); |
| 513 Register key = LoadConvention::NameRegister(); | 513 Register key = LoadDescriptor::NameRegister(); |
| 514 Register scratch = eax; | 514 Register scratch = eax; |
| 515 DCHECK(!scratch.is(receiver) && !scratch.is(key)); | 515 DCHECK(!scratch.is(receiver) && !scratch.is(key)); |
| 516 | 516 |
| 517 // Check that the receiver isn't a smi. | 517 // Check that the receiver isn't a smi. |
| 518 __ JumpIfSmi(receiver, &slow); | 518 __ JumpIfSmi(receiver, &slow); |
| 519 | 519 |
| 520 // Check that the key is an array index, that is Uint32. | 520 // Check that the key is an array index, that is Uint32. |
| 521 __ test(key, Immediate(kSmiTagMask | kSmiSignMask)); | 521 __ test(key, Immediate(kSmiTagMask | kSmiSignMask)); |
| 522 __ j(not_zero, &slow); | 522 __ j(not_zero, &slow); |
| 523 | 523 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 542 IC_Utility(kLoadElementWithInterceptor), masm->isolate()); | 542 IC_Utility(kLoadElementWithInterceptor), masm->isolate()); |
| 543 __ TailCallExternalReference(ref, 2, 1); | 543 __ TailCallExternalReference(ref, 2, 1); |
| 544 | 544 |
| 545 __ bind(&slow); | 545 __ bind(&slow); |
| 546 GenerateMiss(masm); | 546 GenerateMiss(masm); |
| 547 } | 547 } |
| 548 | 548 |
| 549 | 549 |
| 550 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { | 550 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { |
| 551 // The return address is on the stack. | 551 // The return address is on the stack. |
| 552 Register receiver = LoadConvention::ReceiverRegister(); | 552 Register receiver = LoadDescriptor::ReceiverRegister(); |
| 553 Register key = LoadConvention::NameRegister(); | 553 Register key = LoadDescriptor::NameRegister(); |
| 554 DCHECK(receiver.is(edx)); | 554 DCHECK(receiver.is(edx)); |
| 555 DCHECK(key.is(ecx)); | 555 DCHECK(key.is(ecx)); |
| 556 | 556 |
| 557 Label slow, notin; | 557 Label slow, notin; |
| 558 Factory* factory = masm->isolate()->factory(); | 558 Factory* factory = masm->isolate()->factory(); |
| 559 Operand mapped_location = GenerateMappedArgumentsLookup( | 559 Operand mapped_location = GenerateMappedArgumentsLookup( |
| 560 masm, receiver, key, ebx, eax, ¬in, &slow); | 560 masm, receiver, key, ebx, eax, ¬in, &slow); |
| 561 __ mov(eax, mapped_location); | 561 __ mov(eax, mapped_location); |
| 562 __ Ret(); | 562 __ Ret(); |
| 563 __ bind(¬in); | 563 __ bind(¬in); |
| 564 // The unmapped lookup expects that the parameter map is in ebx. | 564 // The unmapped lookup expects that the parameter map is in ebx. |
| 565 Operand unmapped_location = | 565 Operand unmapped_location = |
| 566 GenerateUnmappedArgumentsLookup(masm, key, ebx, eax, &slow); | 566 GenerateUnmappedArgumentsLookup(masm, key, ebx, eax, &slow); |
| 567 __ cmp(unmapped_location, factory->the_hole_value()); | 567 __ cmp(unmapped_location, factory->the_hole_value()); |
| 568 __ j(equal, &slow); | 568 __ j(equal, &slow); |
| 569 __ mov(eax, unmapped_location); | 569 __ mov(eax, unmapped_location); |
| 570 __ Ret(); | 570 __ Ret(); |
| 571 __ bind(&slow); | 571 __ bind(&slow); |
| 572 GenerateMiss(masm); | 572 GenerateMiss(masm); |
| 573 } | 573 } |
| 574 | 574 |
| 575 | 575 |
| 576 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { | 576 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { |
| 577 // Return address is on the stack. | 577 // Return address is on the stack. |
| 578 Label slow, notin; | 578 Label slow, notin; |
| 579 Register receiver = StoreConvention::ReceiverRegister(); | 579 Register receiver = StoreDescriptor::ReceiverRegister(); |
| 580 Register name = StoreConvention::NameRegister(); | 580 Register name = StoreDescriptor::NameRegister(); |
| 581 Register value = StoreConvention::ValueRegister(); | 581 Register value = StoreDescriptor::ValueRegister(); |
| 582 DCHECK(receiver.is(edx)); | 582 DCHECK(receiver.is(edx)); |
| 583 DCHECK(name.is(ecx)); | 583 DCHECK(name.is(ecx)); |
| 584 DCHECK(value.is(eax)); | 584 DCHECK(value.is(eax)); |
| 585 | 585 |
| 586 Operand mapped_location = GenerateMappedArgumentsLookup( | 586 Operand mapped_location = GenerateMappedArgumentsLookup( |
| 587 masm, receiver, name, ebx, edi, ¬in, &slow); | 587 masm, receiver, name, ebx, edi, ¬in, &slow); |
| 588 __ mov(mapped_location, value); | 588 __ mov(mapped_location, value); |
| 589 __ lea(ecx, mapped_location); | 589 __ lea(ecx, mapped_location); |
| 590 __ mov(edx, value); | 590 __ mov(edx, value); |
| 591 __ RecordWrite(ebx, ecx, edx); | 591 __ RecordWrite(ebx, ecx, edx); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 603 GenerateMiss(masm); | 603 GenerateMiss(masm); |
| 604 } | 604 } |
| 605 | 605 |
| 606 | 606 |
| 607 static void KeyedStoreGenerateGenericHelper( | 607 static void KeyedStoreGenerateGenericHelper( |
| 608 MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow, | 608 MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow, |
| 609 KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length) { | 609 KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length) { |
| 610 Label transition_smi_elements; | 610 Label transition_smi_elements; |
| 611 Label finish_object_store, non_double_value, transition_double_elements; | 611 Label finish_object_store, non_double_value, transition_double_elements; |
| 612 Label fast_double_without_map_check; | 612 Label fast_double_without_map_check; |
| 613 Register receiver = StoreConvention::ReceiverRegister(); | 613 Register receiver = StoreDescriptor::ReceiverRegister(); |
| 614 Register key = StoreConvention::NameRegister(); | 614 Register key = StoreDescriptor::NameRegister(); |
| 615 Register value = StoreConvention::ValueRegister(); | 615 Register value = StoreDescriptor::ValueRegister(); |
| 616 DCHECK(receiver.is(edx)); | 616 DCHECK(receiver.is(edx)); |
| 617 DCHECK(key.is(ecx)); | 617 DCHECK(key.is(ecx)); |
| 618 DCHECK(value.is(eax)); | 618 DCHECK(value.is(eax)); |
| 619 // key is a smi. | 619 // key is a smi. |
| 620 // ebx: FixedArray receiver->elements | 620 // ebx: FixedArray receiver->elements |
| 621 // edi: receiver map | 621 // edi: receiver map |
| 622 // Fast case: Do the store, could either Object or double. | 622 // Fast case: Do the store, could either Object or double. |
| 623 __ bind(fast_object); | 623 __ bind(fast_object); |
| 624 if (check_map == kCheckMap) { | 624 if (check_map == kCheckMap) { |
| 625 __ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset)); | 625 __ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset)); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 __ jmp(&finish_object_store); | 740 __ jmp(&finish_object_store); |
| 741 } | 741 } |
| 742 | 742 |
| 743 | 743 |
| 744 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, | 744 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, |
| 745 StrictMode strict_mode) { | 745 StrictMode strict_mode) { |
| 746 // Return address is on the stack. | 746 // Return address is on the stack. |
| 747 Label slow, fast_object, fast_object_grow; | 747 Label slow, fast_object, fast_object_grow; |
| 748 Label fast_double, fast_double_grow; | 748 Label fast_double, fast_double_grow; |
| 749 Label array, extra, check_if_double_array; | 749 Label array, extra, check_if_double_array; |
| 750 Register receiver = StoreConvention::ReceiverRegister(); | 750 Register receiver = StoreDescriptor::ReceiverRegister(); |
| 751 Register key = StoreConvention::NameRegister(); | 751 Register key = StoreDescriptor::NameRegister(); |
| 752 DCHECK(receiver.is(edx)); | 752 DCHECK(receiver.is(edx)); |
| 753 DCHECK(key.is(ecx)); | 753 DCHECK(key.is(ecx)); |
| 754 | 754 |
| 755 // Check that the object isn't a smi. | 755 // Check that the object isn't a smi. |
| 756 __ JumpIfSmi(receiver, &slow); | 756 __ JumpIfSmi(receiver, &slow); |
| 757 // Get the map from the receiver. | 757 // Get the map from the receiver. |
| 758 __ mov(edi, FieldOperand(receiver, HeapObject::kMapOffset)); | 758 __ mov(edi, FieldOperand(receiver, HeapObject::kMapOffset)); |
| 759 // Check that the receiver does not require access checks and is not observed. | 759 // Check that the receiver does not require access checks and is not observed. |
| 760 // The generic stub does not perform map checks or handle observed objects. | 760 // The generic stub does not perform map checks or handle observed objects. |
| 761 __ test_b(FieldOperand(edi, Map::kBitFieldOffset), | 761 __ test_b(FieldOperand(edi, Map::kBitFieldOffset), |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 820 | 820 |
| 821 KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double, &slow, | 821 KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double, &slow, |
| 822 kCheckMap, kDontIncrementLength); | 822 kCheckMap, kDontIncrementLength); |
| 823 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, | 823 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, |
| 824 &slow, kDontCheckMap, kIncrementLength); | 824 &slow, kDontCheckMap, kIncrementLength); |
| 825 } | 825 } |
| 826 | 826 |
| 827 | 827 |
| 828 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { | 828 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { |
| 829 // The return address is on the stack. | 829 // The return address is on the stack. |
| 830 Register receiver = LoadConvention::ReceiverRegister(); | 830 Register receiver = LoadDescriptor::ReceiverRegister(); |
| 831 Register name = LoadConvention::NameRegister(); | 831 Register name = LoadDescriptor::NameRegister(); |
| 832 DCHECK(receiver.is(edx)); | 832 DCHECK(receiver.is(edx)); |
| 833 DCHECK(name.is(ecx)); | 833 DCHECK(name.is(ecx)); |
| 834 | 834 |
| 835 // Probe the stub cache. | 835 // Probe the stub cache. |
| 836 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 836 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
| 837 Code::ComputeHandlerFlags(Code::LOAD_IC)); | 837 Code::ComputeHandlerFlags(Code::LOAD_IC)); |
| 838 masm->isolate()->stub_cache()->GenerateProbe(masm, flags, receiver, name, ebx, | 838 masm->isolate()->stub_cache()->GenerateProbe(masm, flags, receiver, name, ebx, |
| 839 eax); | 839 eax); |
| 840 | 840 |
| 841 // Cache miss: Jump to runtime. | 841 // Cache miss: Jump to runtime. |
| 842 GenerateMiss(masm); | 842 GenerateMiss(masm); |
| 843 } | 843 } |
| 844 | 844 |
| 845 | 845 |
| 846 void LoadIC::GenerateNormal(MacroAssembler* masm) { | 846 void LoadIC::GenerateNormal(MacroAssembler* masm) { |
| 847 Register dictionary = eax; | 847 Register dictionary = eax; |
| 848 DCHECK(!dictionary.is(LoadConvention::ReceiverRegister())); | 848 DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister())); |
| 849 DCHECK(!dictionary.is(LoadConvention::NameRegister())); | 849 DCHECK(!dictionary.is(LoadDescriptor::NameRegister())); |
| 850 | 850 |
| 851 Label slow; | 851 Label slow; |
| 852 | 852 |
| 853 __ mov(dictionary, FieldOperand(LoadConvention::ReceiverRegister(), | 853 __ mov(dictionary, FieldOperand(LoadDescriptor::ReceiverRegister(), |
| 854 JSObject::kPropertiesOffset)); | 854 JSObject::kPropertiesOffset)); |
| 855 GenerateDictionaryLoad(masm, &slow, dictionary, | 855 GenerateDictionaryLoad(masm, &slow, dictionary, |
| 856 LoadConvention::NameRegister(), edi, ebx, eax); | 856 LoadDescriptor::NameRegister(), edi, ebx, eax); |
| 857 __ ret(0); | 857 __ ret(0); |
| 858 | 858 |
| 859 // Dictionary load failed, go slow (but don't miss). | 859 // Dictionary load failed, go slow (but don't miss). |
| 860 __ bind(&slow); | 860 __ bind(&slow); |
| 861 GenerateRuntimeGetProperty(masm); | 861 GenerateRuntimeGetProperty(masm); |
| 862 } | 862 } |
| 863 | 863 |
| 864 | 864 |
| 865 static void LoadIC_PushArgs(MacroAssembler* masm) { | 865 static void LoadIC_PushArgs(MacroAssembler* masm) { |
| 866 Register receiver = LoadConvention::ReceiverRegister(); | 866 Register receiver = LoadDescriptor::ReceiverRegister(); |
| 867 Register name = LoadConvention::NameRegister(); | 867 Register name = LoadDescriptor::NameRegister(); |
| 868 DCHECK(!ebx.is(receiver) && !ebx.is(name)); | 868 DCHECK(!ebx.is(receiver) && !ebx.is(name)); |
| 869 | 869 |
| 870 __ pop(ebx); | 870 __ pop(ebx); |
| 871 __ push(receiver); | 871 __ push(receiver); |
| 872 __ push(name); | 872 __ push(name); |
| 873 __ push(ebx); | 873 __ push(ebx); |
| 874 } | 874 } |
| 875 | 875 |
| 876 | 876 |
| 877 void LoadIC::GenerateMiss(MacroAssembler* masm) { | 877 void LoadIC::GenerateMiss(MacroAssembler* masm) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 916 // Perform tail call to the entry. | 916 // Perform tail call to the entry. |
| 917 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); | 917 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); |
| 918 } | 918 } |
| 919 | 919 |
| 920 | 920 |
| 921 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { | 921 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { |
| 922 // Return address is on the stack. | 922 // Return address is on the stack. |
| 923 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 923 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
| 924 Code::ComputeHandlerFlags(Code::STORE_IC)); | 924 Code::ComputeHandlerFlags(Code::STORE_IC)); |
| 925 masm->isolate()->stub_cache()->GenerateProbe( | 925 masm->isolate()->stub_cache()->GenerateProbe( |
| 926 masm, flags, StoreConvention::ReceiverRegister(), | 926 masm, flags, StoreDescriptor::ReceiverRegister(), |
| 927 StoreConvention::NameRegister(), ebx, no_reg); | 927 StoreDescriptor::NameRegister(), ebx, no_reg); |
| 928 | 928 |
| 929 // Cache miss: Jump to runtime. | 929 // Cache miss: Jump to runtime. |
| 930 GenerateMiss(masm); | 930 GenerateMiss(masm); |
| 931 } | 931 } |
| 932 | 932 |
| 933 | 933 |
| 934 static void StoreIC_PushArgs(MacroAssembler* masm) { | 934 static void StoreIC_PushArgs(MacroAssembler* masm) { |
| 935 Register receiver = StoreConvention::ReceiverRegister(); | 935 Register receiver = StoreDescriptor::ReceiverRegister(); |
| 936 Register name = StoreConvention::NameRegister(); | 936 Register name = StoreDescriptor::NameRegister(); |
| 937 Register value = StoreConvention::ValueRegister(); | 937 Register value = StoreDescriptor::ValueRegister(); |
| 938 | 938 |
| 939 DCHECK(!ebx.is(receiver) && !ebx.is(name) && !ebx.is(value)); | 939 DCHECK(!ebx.is(receiver) && !ebx.is(name) && !ebx.is(value)); |
| 940 | 940 |
| 941 __ pop(ebx); | 941 __ pop(ebx); |
| 942 __ push(receiver); | 942 __ push(receiver); |
| 943 __ push(name); | 943 __ push(name); |
| 944 __ push(value); | 944 __ push(value); |
| 945 __ push(ebx); | 945 __ push(ebx); |
| 946 } | 946 } |
| 947 | 947 |
| 948 | 948 |
| 949 void StoreIC::GenerateMiss(MacroAssembler* masm) { | 949 void StoreIC::GenerateMiss(MacroAssembler* masm) { |
| 950 // Return address is on the stack. | 950 // Return address is on the stack. |
| 951 StoreIC_PushArgs(masm); | 951 StoreIC_PushArgs(masm); |
| 952 | 952 |
| 953 // Perform tail call to the entry. | 953 // Perform tail call to the entry. |
| 954 ExternalReference ref = | 954 ExternalReference ref = |
| 955 ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate()); | 955 ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate()); |
| 956 __ TailCallExternalReference(ref, 3, 1); | 956 __ TailCallExternalReference(ref, 3, 1); |
| 957 } | 957 } |
| 958 | 958 |
| 959 | 959 |
| 960 void StoreIC::GenerateNormal(MacroAssembler* masm) { | 960 void StoreIC::GenerateNormal(MacroAssembler* masm) { |
| 961 Label restore_miss; | 961 Label restore_miss; |
| 962 Register receiver = StoreConvention::ReceiverRegister(); | 962 Register receiver = StoreDescriptor::ReceiverRegister(); |
| 963 Register name = StoreConvention::NameRegister(); | 963 Register name = StoreDescriptor::NameRegister(); |
| 964 Register value = StoreConvention::ValueRegister(); | 964 Register value = StoreDescriptor::ValueRegister(); |
| 965 Register dictionary = ebx; | 965 Register dictionary = ebx; |
| 966 | 966 |
| 967 __ mov(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 967 __ mov(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); |
| 968 | 968 |
| 969 // A lot of registers are needed for storing to slow case | 969 // A lot of registers are needed for storing to slow case |
| 970 // objects. Push and restore receiver but rely on | 970 // objects. Push and restore receiver but rely on |
| 971 // GenerateDictionaryStore preserving the value and name. | 971 // GenerateDictionaryStore preserving the value and name. |
| 972 __ push(receiver); | 972 __ push(receiver); |
| 973 GenerateDictionaryStore(masm, &restore_miss, dictionary, name, value, | 973 GenerateDictionaryStore(masm, &restore_miss, dictionary, name, value, |
| 974 receiver, edi); | 974 receiver, edi); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1062 Condition cc = | 1062 Condition cc = |
| 1063 (check == ENABLE_INLINED_SMI_CHECK) | 1063 (check == ENABLE_INLINED_SMI_CHECK) |
| 1064 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) | 1064 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) |
| 1065 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); | 1065 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); |
| 1066 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1066 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
| 1067 } | 1067 } |
| 1068 } | 1068 } |
| 1069 } // namespace v8::internal | 1069 } // namespace v8::internal |
| 1070 | 1070 |
| 1071 #endif // V8_TARGET_ARCH_X87 | 1071 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |