| 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-inl.h" | 10 #include "src/ic-inl.h" |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 // Scratch registers: | 173 // Scratch registers: |
| 174 // map - used to hold the map of the receiver. | 174 // map - used to hold the map of the receiver. |
| 175 | 175 |
| 176 // Check that the object isn't a smi. | 176 // Check that the object isn't a smi. |
| 177 __ JumpIfSmi(receiver, slow); | 177 __ JumpIfSmi(receiver, slow); |
| 178 | 178 |
| 179 // Check that the object is some kind of JS object EXCEPT JS Value type. | 179 // Check that the object is some kind of JS object EXCEPT JS Value type. |
| 180 // In the case that the object is a value-wrapper object, | 180 // In the case that the object is a value-wrapper object, |
| 181 // we enter the runtime system to make sure that indexing | 181 // we enter the runtime system to make sure that indexing |
| 182 // into string objects work as intended. | 182 // into string objects work as intended. |
| 183 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE); | 183 DCHECK(JS_OBJECT_TYPE > JS_VALUE_TYPE); |
| 184 __ CmpObjectType(receiver, JS_OBJECT_TYPE, map); | 184 __ CmpObjectType(receiver, JS_OBJECT_TYPE, map); |
| 185 __ j(below, slow); | 185 __ j(below, slow); |
| 186 | 186 |
| 187 // Check bit field. | 187 // Check bit field. |
| 188 __ testb(FieldOperand(map, Map::kBitFieldOffset), | 188 __ testb(FieldOperand(map, Map::kBitFieldOffset), |
| 189 Immediate((1 << Map::kIsAccessCheckNeeded) | | 189 Immediate((1 << Map::kIsAccessCheckNeeded) | |
| 190 (1 << interceptor_bit))); | 190 (1 << interceptor_bit))); |
| 191 __ j(not_zero, slow); | 191 __ j(not_zero, slow); |
| 192 } | 192 } |
| 193 | 193 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 | 286 |
| 287 | 287 |
| 288 | 288 |
| 289 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { | 289 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { |
| 290 // The return address is on the stack. | 290 // The return address is on the stack. |
| 291 Label slow, check_name, index_smi, index_name, property_array_property; | 291 Label slow, check_name, index_smi, index_name, property_array_property; |
| 292 Label probe_dictionary, check_number_dictionary; | 292 Label probe_dictionary, check_number_dictionary; |
| 293 | 293 |
| 294 Register receiver = ReceiverRegister(); | 294 Register receiver = ReceiverRegister(); |
| 295 Register key = NameRegister(); | 295 Register key = NameRegister(); |
| 296 ASSERT(receiver.is(rdx)); | 296 DCHECK(receiver.is(rdx)); |
| 297 ASSERT(key.is(rcx)); | 297 DCHECK(key.is(rcx)); |
| 298 | 298 |
| 299 // Check that the key is a smi. | 299 // Check that the key is a smi. |
| 300 __ JumpIfNotSmi(key, &check_name); | 300 __ JumpIfNotSmi(key, &check_name); |
| 301 __ bind(&index_smi); | 301 __ bind(&index_smi); |
| 302 // Now the key is known to be a smi. This place is also jumped to from below | 302 // Now the key is known to be a smi. This place is also jumped to from below |
| 303 // where a numeric string is converted to a smi. | 303 // where a numeric string is converted to a smi. |
| 304 | 304 |
| 305 GenerateKeyedLoadReceiverCheck( | 305 GenerateKeyedLoadReceiverCheck( |
| 306 masm, receiver, rax, Map::kHasIndexedInterceptor, &slow); | 306 masm, receiver, rax, Map::kHasIndexedInterceptor, &slow); |
| 307 | 307 |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 | 445 |
| 446 | 446 |
| 447 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { | 447 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { |
| 448 // Return address is on the stack. | 448 // Return address is on the stack. |
| 449 Label miss; | 449 Label miss; |
| 450 | 450 |
| 451 Register receiver = ReceiverRegister(); | 451 Register receiver = ReceiverRegister(); |
| 452 Register index = NameRegister(); | 452 Register index = NameRegister(); |
| 453 Register scratch = rbx; | 453 Register scratch = rbx; |
| 454 Register result = rax; | 454 Register result = rax; |
| 455 ASSERT(!scratch.is(receiver) && !scratch.is(index)); | 455 DCHECK(!scratch.is(receiver) && !scratch.is(index)); |
| 456 | 456 |
| 457 StringCharAtGenerator char_at_generator(receiver, | 457 StringCharAtGenerator char_at_generator(receiver, |
| 458 index, | 458 index, |
| 459 scratch, | 459 scratch, |
| 460 result, | 460 result, |
| 461 &miss, // When not a string. | 461 &miss, // When not a string. |
| 462 &miss, // When not a number. | 462 &miss, // When not a number. |
| 463 &miss, // When index out of range. | 463 &miss, // When index out of range. |
| 464 STRING_INDEX_IS_ARRAY_INDEX); | 464 STRING_INDEX_IS_ARRAY_INDEX); |
| 465 char_at_generator.GenerateFast(masm); | 465 char_at_generator.GenerateFast(masm); |
| 466 __ ret(0); | 466 __ ret(0); |
| 467 | 467 |
| 468 StubRuntimeCallHelper call_helper; | 468 StubRuntimeCallHelper call_helper; |
| 469 char_at_generator.GenerateSlow(masm, call_helper); | 469 char_at_generator.GenerateSlow(masm, call_helper); |
| 470 | 470 |
| 471 __ bind(&miss); | 471 __ bind(&miss); |
| 472 GenerateMiss(masm); | 472 GenerateMiss(masm); |
| 473 } | 473 } |
| 474 | 474 |
| 475 | 475 |
| 476 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { | 476 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { |
| 477 // Return address is on the stack. | 477 // Return address is on the stack. |
| 478 Label slow; | 478 Label slow; |
| 479 | 479 |
| 480 Register receiver = ReceiverRegister(); | 480 Register receiver = ReceiverRegister(); |
| 481 Register key = NameRegister(); | 481 Register key = NameRegister(); |
| 482 Register scratch = rax; | 482 Register scratch = rax; |
| 483 ASSERT(!scratch.is(receiver) && !scratch.is(key)); | 483 DCHECK(!scratch.is(receiver) && !scratch.is(key)); |
| 484 | 484 |
| 485 // Check that the receiver isn't a smi. | 485 // Check that the receiver isn't a smi. |
| 486 __ JumpIfSmi(receiver, &slow); | 486 __ JumpIfSmi(receiver, &slow); |
| 487 | 487 |
| 488 // Check that the key is an array index, that is Uint32. | 488 // Check that the key is an array index, that is Uint32. |
| 489 STATIC_ASSERT(kSmiValueSize <= 32); | 489 STATIC_ASSERT(kSmiValueSize <= 32); |
| 490 __ JumpUnlessNonNegativeSmi(key, &slow); | 490 __ JumpUnlessNonNegativeSmi(key, &slow); |
| 491 | 491 |
| 492 // Get the map of the receiver. | 492 // Get the map of the receiver. |
| 493 __ movp(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | 493 __ movp(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 522 Label* fast_double, | 522 Label* fast_double, |
| 523 Label* slow, | 523 Label* slow, |
| 524 KeyedStoreCheckMap check_map, | 524 KeyedStoreCheckMap check_map, |
| 525 KeyedStoreIncrementLength increment_length) { | 525 KeyedStoreIncrementLength increment_length) { |
| 526 Label transition_smi_elements; | 526 Label transition_smi_elements; |
| 527 Label finish_object_store, non_double_value, transition_double_elements; | 527 Label finish_object_store, non_double_value, transition_double_elements; |
| 528 Label fast_double_without_map_check; | 528 Label fast_double_without_map_check; |
| 529 Register receiver = KeyedStoreIC::ReceiverRegister(); | 529 Register receiver = KeyedStoreIC::ReceiverRegister(); |
| 530 Register key = KeyedStoreIC::NameRegister(); | 530 Register key = KeyedStoreIC::NameRegister(); |
| 531 Register value = KeyedStoreIC::ValueRegister(); | 531 Register value = KeyedStoreIC::ValueRegister(); |
| 532 ASSERT(receiver.is(rdx)); | 532 DCHECK(receiver.is(rdx)); |
| 533 ASSERT(key.is(rcx)); | 533 DCHECK(key.is(rcx)); |
| 534 ASSERT(value.is(rax)); | 534 DCHECK(value.is(rax)); |
| 535 // Fast case: Do the store, could be either Object or double. | 535 // Fast case: Do the store, could be either Object or double. |
| 536 __ bind(fast_object); | 536 __ bind(fast_object); |
| 537 // rbx: receiver's elements array (a FixedArray) | 537 // rbx: receiver's elements array (a FixedArray) |
| 538 // receiver is a JSArray. | 538 // receiver is a JSArray. |
| 539 // r9: map of receiver | 539 // r9: map of receiver |
| 540 if (check_map == kCheckMap) { | 540 if (check_map == kCheckMap) { |
| 541 __ movp(rdi, FieldOperand(rbx, HeapObject::kMapOffset)); | 541 __ movp(rdi, FieldOperand(rbx, HeapObject::kMapOffset)); |
| 542 __ CompareRoot(rdi, Heap::kFixedArrayMapRootIndex); | 542 __ CompareRoot(rdi, Heap::kFixedArrayMapRootIndex); |
| 543 __ j(not_equal, fast_double); | 543 __ j(not_equal, fast_double); |
| 544 } | 544 } |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 669 | 669 |
| 670 | 670 |
| 671 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, | 671 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, |
| 672 StrictMode strict_mode) { | 672 StrictMode strict_mode) { |
| 673 // Return address is on the stack. | 673 // Return address is on the stack. |
| 674 Label slow, slow_with_tagged_index, fast_object, fast_object_grow; | 674 Label slow, slow_with_tagged_index, fast_object, fast_object_grow; |
| 675 Label fast_double, fast_double_grow; | 675 Label fast_double, fast_double_grow; |
| 676 Label array, extra, check_if_double_array; | 676 Label array, extra, check_if_double_array; |
| 677 Register receiver = ReceiverRegister(); | 677 Register receiver = ReceiverRegister(); |
| 678 Register key = NameRegister(); | 678 Register key = NameRegister(); |
| 679 ASSERT(receiver.is(rdx)); | 679 DCHECK(receiver.is(rdx)); |
| 680 ASSERT(key.is(rcx)); | 680 DCHECK(key.is(rcx)); |
| 681 | 681 |
| 682 // Check that the object isn't a smi. | 682 // Check that the object isn't a smi. |
| 683 __ JumpIfSmi(receiver, &slow_with_tagged_index); | 683 __ JumpIfSmi(receiver, &slow_with_tagged_index); |
| 684 // Get the map from the receiver. | 684 // Get the map from the receiver. |
| 685 __ movp(r9, FieldOperand(receiver, HeapObject::kMapOffset)); | 685 __ movp(r9, FieldOperand(receiver, HeapObject::kMapOffset)); |
| 686 // Check that the receiver does not require access checks and is not observed. | 686 // Check that the receiver does not require access checks and is not observed. |
| 687 // The generic stub does not perform map checks or handle observed objects. | 687 // The generic stub does not perform map checks or handle observed objects. |
| 688 __ testb(FieldOperand(r9, Map::kBitFieldOffset), | 688 __ testb(FieldOperand(r9, Map::kBitFieldOffset), |
| 689 Immediate(1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved)); | 689 Immediate(1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved)); |
| 690 __ j(not_zero, &slow_with_tagged_index); | 690 __ j(not_zero, &slow_with_tagged_index); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 831 scratch, | 831 scratch, |
| 832 times_pointer_size, | 832 times_pointer_size, |
| 833 FixedArray::kHeaderSize); | 833 FixedArray::kHeaderSize); |
| 834 } | 834 } |
| 835 | 835 |
| 836 | 836 |
| 837 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { | 837 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { |
| 838 // The return address is on the stack. | 838 // The return address is on the stack. |
| 839 Register receiver = ReceiverRegister(); | 839 Register receiver = ReceiverRegister(); |
| 840 Register key = NameRegister(); | 840 Register key = NameRegister(); |
| 841 ASSERT(receiver.is(rdx)); | 841 DCHECK(receiver.is(rdx)); |
| 842 ASSERT(key.is(rcx)); | 842 DCHECK(key.is(rcx)); |
| 843 | 843 |
| 844 Label slow, notin; | 844 Label slow, notin; |
| 845 Operand mapped_location = | 845 Operand mapped_location = |
| 846 GenerateMappedArgumentsLookup( | 846 GenerateMappedArgumentsLookup( |
| 847 masm, receiver, key, rbx, rax, rdi, ¬in, &slow); | 847 masm, receiver, key, rbx, rax, rdi, ¬in, &slow); |
| 848 __ movp(rax, mapped_location); | 848 __ movp(rax, mapped_location); |
| 849 __ Ret(); | 849 __ Ret(); |
| 850 __ bind(¬in); | 850 __ bind(¬in); |
| 851 // The unmapped lookup expects that the parameter map is in rbx. | 851 // The unmapped lookup expects that the parameter map is in rbx. |
| 852 Operand unmapped_location = | 852 Operand unmapped_location = |
| 853 GenerateUnmappedArgumentsLookup(masm, key, rbx, rax, &slow); | 853 GenerateUnmappedArgumentsLookup(masm, key, rbx, rax, &slow); |
| 854 __ CompareRoot(unmapped_location, Heap::kTheHoleValueRootIndex); | 854 __ CompareRoot(unmapped_location, Heap::kTheHoleValueRootIndex); |
| 855 __ j(equal, &slow); | 855 __ j(equal, &slow); |
| 856 __ movp(rax, unmapped_location); | 856 __ movp(rax, unmapped_location); |
| 857 __ Ret(); | 857 __ Ret(); |
| 858 __ bind(&slow); | 858 __ bind(&slow); |
| 859 GenerateMiss(masm); | 859 GenerateMiss(masm); |
| 860 } | 860 } |
| 861 | 861 |
| 862 | 862 |
| 863 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { | 863 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { |
| 864 // The return address is on the stack. | 864 // The return address is on the stack. |
| 865 Label slow, notin; | 865 Label slow, notin; |
| 866 Register receiver = ReceiverRegister(); | 866 Register receiver = ReceiverRegister(); |
| 867 Register name = NameRegister(); | 867 Register name = NameRegister(); |
| 868 Register value = ValueRegister(); | 868 Register value = ValueRegister(); |
| 869 ASSERT(receiver.is(rdx)); | 869 DCHECK(receiver.is(rdx)); |
| 870 ASSERT(name.is(rcx)); | 870 DCHECK(name.is(rcx)); |
| 871 ASSERT(value.is(rax)); | 871 DCHECK(value.is(rax)); |
| 872 | 872 |
| 873 Operand mapped_location = GenerateMappedArgumentsLookup( | 873 Operand mapped_location = GenerateMappedArgumentsLookup( |
| 874 masm, receiver, name, rbx, rdi, r8, ¬in, &slow); | 874 masm, receiver, name, rbx, rdi, r8, ¬in, &slow); |
| 875 __ movp(mapped_location, value); | 875 __ movp(mapped_location, value); |
| 876 __ leap(r9, mapped_location); | 876 __ leap(r9, mapped_location); |
| 877 __ movp(r8, value); | 877 __ movp(r8, value); |
| 878 __ RecordWrite(rbx, | 878 __ RecordWrite(rbx, |
| 879 r9, | 879 r9, |
| 880 r8, | 880 r8, |
| 881 kDontSaveFPRegs, | 881 kDontSaveFPRegs, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 898 __ Ret(); | 898 __ Ret(); |
| 899 __ bind(&slow); | 899 __ bind(&slow); |
| 900 GenerateMiss(masm); | 900 GenerateMiss(masm); |
| 901 } | 901 } |
| 902 | 902 |
| 903 | 903 |
| 904 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { | 904 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { |
| 905 // The return address is on the stack. | 905 // The return address is on the stack. |
| 906 Register receiver = ReceiverRegister(); | 906 Register receiver = ReceiverRegister(); |
| 907 Register name = NameRegister(); | 907 Register name = NameRegister(); |
| 908 ASSERT(receiver.is(rdx)); | 908 DCHECK(receiver.is(rdx)); |
| 909 ASSERT(name.is(rcx)); | 909 DCHECK(name.is(rcx)); |
| 910 | 910 |
| 911 // Probe the stub cache. | 911 // Probe the stub cache. |
| 912 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 912 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
| 913 Code::ComputeHandlerFlags(Code::LOAD_IC)); | 913 Code::ComputeHandlerFlags(Code::LOAD_IC)); |
| 914 masm->isolate()->stub_cache()->GenerateProbe( | 914 masm->isolate()->stub_cache()->GenerateProbe( |
| 915 masm, flags, receiver, name, rbx, rax); | 915 masm, flags, receiver, name, rbx, rax); |
| 916 | 916 |
| 917 GenerateMiss(masm); | 917 GenerateMiss(masm); |
| 918 } | 918 } |
| 919 | 919 |
| 920 | 920 |
| 921 void LoadIC::GenerateNormal(MacroAssembler* masm) { | 921 void LoadIC::GenerateNormal(MacroAssembler* masm) { |
| 922 Register dictionary = rax; | 922 Register dictionary = rax; |
| 923 ASSERT(!dictionary.is(ReceiverRegister())); | 923 DCHECK(!dictionary.is(ReceiverRegister())); |
| 924 ASSERT(!dictionary.is(NameRegister())); | 924 DCHECK(!dictionary.is(NameRegister())); |
| 925 | 925 |
| 926 Label slow; | 926 Label slow; |
| 927 | 927 |
| 928 __ movp(dictionary, | 928 __ movp(dictionary, |
| 929 FieldOperand(ReceiverRegister(), JSObject::kPropertiesOffset)); | 929 FieldOperand(ReceiverRegister(), JSObject::kPropertiesOffset)); |
| 930 GenerateDictionaryLoad(masm, &slow, dictionary, NameRegister(), rbx, rdi, | 930 GenerateDictionaryLoad(masm, &slow, dictionary, NameRegister(), rbx, rdi, |
| 931 rax); | 931 rax); |
| 932 __ ret(0); | 932 __ ret(0); |
| 933 | 933 |
| 934 // Dictionary load failed, go slow (but don't miss). | 934 // Dictionary load failed, go slow (but don't miss). |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 993 __ TailCallExternalReference(ref, 2, 1); | 993 __ TailCallExternalReference(ref, 2, 1); |
| 994 } | 994 } |
| 995 | 995 |
| 996 | 996 |
| 997 // IC register specifications | 997 // IC register specifications |
| 998 const Register LoadIC::ReceiverRegister() { return rdx; } | 998 const Register LoadIC::ReceiverRegister() { return rdx; } |
| 999 const Register LoadIC::NameRegister() { return rcx; } | 999 const Register LoadIC::NameRegister() { return rcx; } |
| 1000 | 1000 |
| 1001 | 1001 |
| 1002 const Register LoadIC::SlotRegister() { | 1002 const Register LoadIC::SlotRegister() { |
| 1003 ASSERT(FLAG_vector_ics); | 1003 DCHECK(FLAG_vector_ics); |
| 1004 return rax; | 1004 return rax; |
| 1005 } | 1005 } |
| 1006 | 1006 |
| 1007 | 1007 |
| 1008 const Register LoadIC::VectorRegister() { | 1008 const Register LoadIC::VectorRegister() { |
| 1009 ASSERT(FLAG_vector_ics); | 1009 DCHECK(FLAG_vector_ics); |
| 1010 return rbx; | 1010 return rbx; |
| 1011 } | 1011 } |
| 1012 | 1012 |
| 1013 | 1013 |
| 1014 const Register StoreIC::ReceiverRegister() { return rdx; } | 1014 const Register StoreIC::ReceiverRegister() { return rdx; } |
| 1015 const Register StoreIC::NameRegister() { return rcx; } | 1015 const Register StoreIC::NameRegister() { return rcx; } |
| 1016 const Register StoreIC::ValueRegister() { return rax; } | 1016 const Register StoreIC::ValueRegister() { return rax; } |
| 1017 | 1017 |
| 1018 | 1018 |
| 1019 const Register KeyedStoreIC::MapRegister() { | 1019 const Register KeyedStoreIC::MapRegister() { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1046 // Cache miss: Jump to runtime. | 1046 // Cache miss: Jump to runtime. |
| 1047 GenerateMiss(masm); | 1047 GenerateMiss(masm); |
| 1048 } | 1048 } |
| 1049 | 1049 |
| 1050 | 1050 |
| 1051 static void StoreIC_PushArgs(MacroAssembler* masm) { | 1051 static void StoreIC_PushArgs(MacroAssembler* masm) { |
| 1052 Register receiver = StoreIC::ReceiverRegister(); | 1052 Register receiver = StoreIC::ReceiverRegister(); |
| 1053 Register name = StoreIC::NameRegister(); | 1053 Register name = StoreIC::NameRegister(); |
| 1054 Register value = StoreIC::ValueRegister(); | 1054 Register value = StoreIC::ValueRegister(); |
| 1055 | 1055 |
| 1056 ASSERT(!rbx.is(receiver) && !rbx.is(name) && !rbx.is(value)); | 1056 DCHECK(!rbx.is(receiver) && !rbx.is(name) && !rbx.is(value)); |
| 1057 | 1057 |
| 1058 __ PopReturnAddressTo(rbx); | 1058 __ PopReturnAddressTo(rbx); |
| 1059 __ Push(receiver); | 1059 __ Push(receiver); |
| 1060 __ Push(name); | 1060 __ Push(name); |
| 1061 __ Push(value); | 1061 __ Push(value); |
| 1062 __ PushReturnAddressFrom(rbx); | 1062 __ PushReturnAddressFrom(rbx); |
| 1063 } | 1063 } |
| 1064 | 1064 |
| 1065 | 1065 |
| 1066 void StoreIC::GenerateMiss(MacroAssembler* masm) { | 1066 void StoreIC::GenerateMiss(MacroAssembler* masm) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1090 | 1090 |
| 1091 __ bind(&miss); | 1091 __ bind(&miss); |
| 1092 __ IncrementCounter(counters->store_normal_miss(), 1); | 1092 __ IncrementCounter(counters->store_normal_miss(), 1); |
| 1093 GenerateMiss(masm); | 1093 GenerateMiss(masm); |
| 1094 } | 1094 } |
| 1095 | 1095 |
| 1096 | 1096 |
| 1097 void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, | 1097 void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, |
| 1098 StrictMode strict_mode) { | 1098 StrictMode strict_mode) { |
| 1099 // Return address is on the stack. | 1099 // Return address is on the stack. |
| 1100 ASSERT(!rbx.is(ReceiverRegister()) && !rbx.is(NameRegister()) && | 1100 DCHECK(!rbx.is(ReceiverRegister()) && !rbx.is(NameRegister()) && |
| 1101 !rbx.is(ValueRegister())); | 1101 !rbx.is(ValueRegister())); |
| 1102 | 1102 |
| 1103 __ PopReturnAddressTo(rbx); | 1103 __ PopReturnAddressTo(rbx); |
| 1104 __ Push(ReceiverRegister()); | 1104 __ Push(ReceiverRegister()); |
| 1105 __ Push(NameRegister()); | 1105 __ Push(NameRegister()); |
| 1106 __ Push(ValueRegister()); | 1106 __ Push(ValueRegister()); |
| 1107 __ Push(Smi::FromInt(strict_mode)); | 1107 __ Push(Smi::FromInt(strict_mode)); |
| 1108 __ PushReturnAddressFrom(rbx); | 1108 __ PushReturnAddressFrom(rbx); |
| 1109 | 1109 |
| 1110 // Do tail-call to runtime routine. | 1110 // Do tail-call to runtime routine. |
| 1111 __ TailCallRuntime(Runtime::kSetProperty, 4, 1); | 1111 __ TailCallRuntime(Runtime::kSetProperty, 4, 1); |
| 1112 } | 1112 } |
| 1113 | 1113 |
| 1114 | 1114 |
| 1115 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, | 1115 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, |
| 1116 StrictMode strict_mode) { | 1116 StrictMode strict_mode) { |
| 1117 // Return address is on the stack. | 1117 // Return address is on the stack. |
| 1118 ASSERT(!rbx.is(ReceiverRegister()) && !rbx.is(NameRegister()) && | 1118 DCHECK(!rbx.is(ReceiverRegister()) && !rbx.is(NameRegister()) && |
| 1119 !rbx.is(ValueRegister())); | 1119 !rbx.is(ValueRegister())); |
| 1120 | 1120 |
| 1121 __ PopReturnAddressTo(rbx); | 1121 __ PopReturnAddressTo(rbx); |
| 1122 __ Push(ReceiverRegister()); | 1122 __ Push(ReceiverRegister()); |
| 1123 __ Push(NameRegister()); | 1123 __ Push(NameRegister()); |
| 1124 __ Push(ValueRegister()); | 1124 __ Push(ValueRegister()); |
| 1125 __ Push(Smi::FromInt(strict_mode)); // Strict mode. | 1125 __ Push(Smi::FromInt(strict_mode)); // Strict mode. |
| 1126 __ PushReturnAddressFrom(rbx); | 1126 __ PushReturnAddressFrom(rbx); |
| 1127 | 1127 |
| 1128 // Do tail-call to runtime routine. | 1128 // Do tail-call to runtime routine. |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1196 | 1196 |
| 1197 | 1197 |
| 1198 void PatchInlinedSmiCode(Address address, InlinedSmiCheck check) { | 1198 void PatchInlinedSmiCode(Address address, InlinedSmiCheck check) { |
| 1199 // The address of the instruction following the call. | 1199 // The address of the instruction following the call. |
| 1200 Address test_instruction_address = | 1200 Address test_instruction_address = |
| 1201 address + Assembler::kCallTargetAddressOffset; | 1201 address + Assembler::kCallTargetAddressOffset; |
| 1202 | 1202 |
| 1203 // If the instruction following the call is not a test al, nothing | 1203 // If the instruction following the call is not a test al, nothing |
| 1204 // was inlined. | 1204 // was inlined. |
| 1205 if (*test_instruction_address != Assembler::kTestAlByte) { | 1205 if (*test_instruction_address != Assembler::kTestAlByte) { |
| 1206 ASSERT(*test_instruction_address == Assembler::kNopByte); | 1206 DCHECK(*test_instruction_address == Assembler::kNopByte); |
| 1207 return; | 1207 return; |
| 1208 } | 1208 } |
| 1209 | 1209 |
| 1210 Address delta_address = test_instruction_address + 1; | 1210 Address delta_address = test_instruction_address + 1; |
| 1211 // The delta to the start of the map check instruction and the | 1211 // The delta to the start of the map check instruction and the |
| 1212 // condition code uses at the patched jump. | 1212 // condition code uses at the patched jump. |
| 1213 uint8_t delta = *reinterpret_cast<uint8_t*>(delta_address); | 1213 uint8_t delta = *reinterpret_cast<uint8_t*>(delta_address); |
| 1214 if (FLAG_trace_ic) { | 1214 if (FLAG_trace_ic) { |
| 1215 PrintF("[ patching ic at %p, test=%p, delta=%d\n", | 1215 PrintF("[ patching ic at %p, test=%p, delta=%d\n", |
| 1216 address, test_instruction_address, delta); | 1216 address, test_instruction_address, delta); |
| 1217 } | 1217 } |
| 1218 | 1218 |
| 1219 // Patch with a short conditional jump. Enabling means switching from a short | 1219 // Patch with a short conditional jump. Enabling means switching from a short |
| 1220 // jump-if-carry/not-carry to jump-if-zero/not-zero, whereas disabling is the | 1220 // jump-if-carry/not-carry to jump-if-zero/not-zero, whereas disabling is the |
| 1221 // reverse operation of that. | 1221 // reverse operation of that. |
| 1222 Address jmp_address = test_instruction_address - delta; | 1222 Address jmp_address = test_instruction_address - delta; |
| 1223 ASSERT((check == ENABLE_INLINED_SMI_CHECK) | 1223 DCHECK((check == ENABLE_INLINED_SMI_CHECK) |
| 1224 ? (*jmp_address == Assembler::kJncShortOpcode || | 1224 ? (*jmp_address == Assembler::kJncShortOpcode || |
| 1225 *jmp_address == Assembler::kJcShortOpcode) | 1225 *jmp_address == Assembler::kJcShortOpcode) |
| 1226 : (*jmp_address == Assembler::kJnzShortOpcode || | 1226 : (*jmp_address == Assembler::kJnzShortOpcode || |
| 1227 *jmp_address == Assembler::kJzShortOpcode)); | 1227 *jmp_address == Assembler::kJzShortOpcode)); |
| 1228 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) | 1228 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) |
| 1229 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) | 1229 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) |
| 1230 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); | 1230 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); |
| 1231 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1231 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
| 1232 } | 1232 } |
| 1233 | 1233 |
| 1234 | 1234 |
| 1235 } } // namespace v8::internal | 1235 } } // namespace v8::internal |
| 1236 | 1236 |
| 1237 #endif // V8_TARGET_ARCH_X64 | 1237 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |