| 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_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
| 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 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 __ mov(map, FieldOperand(receiver, HeapObject::kMapOffset)); | 174 __ mov(map, FieldOperand(receiver, HeapObject::kMapOffset)); |
| 175 | 175 |
| 176 // Check bit field. | 176 // Check bit field. |
| 177 __ test_b(FieldOperand(map, Map::kBitFieldOffset), | 177 __ test_b(FieldOperand(map, Map::kBitFieldOffset), |
| 178 (1 << Map::kIsAccessCheckNeeded) | (1 << interceptor_bit)); | 178 (1 << Map::kIsAccessCheckNeeded) | (1 << interceptor_bit)); |
| 179 __ j(not_zero, slow); | 179 __ j(not_zero, slow); |
| 180 // Check that the object is some kind of JS object EXCEPT JS Value type. | 180 // Check that the object is some kind of JS object EXCEPT JS Value type. |
| 181 // In the case that the object is a value-wrapper object, | 181 // In the case that the object is a value-wrapper object, |
| 182 // we enter the runtime system to make sure that indexing | 182 // we enter the runtime system to make sure that indexing |
| 183 // into string objects works as intended. | 183 // into string objects works as intended. |
| 184 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE); | 184 DCHECK(JS_OBJECT_TYPE > JS_VALUE_TYPE); |
| 185 | 185 |
| 186 __ CmpInstanceType(map, JS_OBJECT_TYPE); | 186 __ CmpInstanceType(map, JS_OBJECT_TYPE); |
| 187 __ j(below, slow); | 187 __ j(below, slow); |
| 188 } | 188 } |
| 189 | 189 |
| 190 | 190 |
| 191 // Loads an indexed element from a fast case array. | 191 // Loads an indexed element from a fast case array. |
| 192 // If not_fast_array is NULL, doesn't perform the elements map check. | 192 // If not_fast_array is NULL, doesn't perform the elements map check. |
| 193 static void GenerateFastArrayLoad(MacroAssembler* masm, | 193 static void GenerateFastArrayLoad(MacroAssembler* masm, |
| 194 Register receiver, | 194 Register receiver, |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 } | 343 } |
| 344 | 344 |
| 345 | 345 |
| 346 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { | 346 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { |
| 347 // The return address is on the stack. | 347 // The return address is on the stack. |
| 348 Label slow, check_name, index_smi, index_name, property_array_property; | 348 Label slow, check_name, index_smi, index_name, property_array_property; |
| 349 Label probe_dictionary, check_number_dictionary; | 349 Label probe_dictionary, check_number_dictionary; |
| 350 | 350 |
| 351 Register receiver = ReceiverRegister(); | 351 Register receiver = ReceiverRegister(); |
| 352 Register key = NameRegister(); | 352 Register key = NameRegister(); |
| 353 ASSERT(receiver.is(edx)); | 353 DCHECK(receiver.is(edx)); |
| 354 ASSERT(key.is(ecx)); | 354 DCHECK(key.is(ecx)); |
| 355 | 355 |
| 356 // Check that the key is a smi. | 356 // Check that the key is a smi. |
| 357 __ JumpIfNotSmi(key, &check_name); | 357 __ JumpIfNotSmi(key, &check_name); |
| 358 __ bind(&index_smi); | 358 __ bind(&index_smi); |
| 359 // Now the key is known to be a smi. This place is also jumped to from | 359 // Now the key is known to be a smi. This place is also jumped to from |
| 360 // where a numeric string is converted to a smi. | 360 // where a numeric string is converted to a smi. |
| 361 | 361 |
| 362 GenerateKeyedLoadReceiverCheck( | 362 GenerateKeyedLoadReceiverCheck( |
| 363 masm, receiver, eax, Map::kHasIndexedInterceptor, &slow); | 363 masm, receiver, eax, Map::kHasIndexedInterceptor, &slow); |
| 364 | 364 |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 } | 516 } |
| 517 | 517 |
| 518 | 518 |
| 519 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { | 519 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { |
| 520 // Return address is on the stack. | 520 // Return address is on the stack. |
| 521 Label miss; | 521 Label miss; |
| 522 | 522 |
| 523 Register receiver = ReceiverRegister(); | 523 Register receiver = ReceiverRegister(); |
| 524 Register index = NameRegister(); | 524 Register index = NameRegister(); |
| 525 Register scratch = ebx; | 525 Register scratch = ebx; |
| 526 ASSERT(!scratch.is(receiver) && !scratch.is(index)); | 526 DCHECK(!scratch.is(receiver) && !scratch.is(index)); |
| 527 Register result = eax; | 527 Register result = eax; |
| 528 ASSERT(!result.is(scratch)); | 528 DCHECK(!result.is(scratch)); |
| 529 | 529 |
| 530 StringCharAtGenerator char_at_generator(receiver, | 530 StringCharAtGenerator char_at_generator(receiver, |
| 531 index, | 531 index, |
| 532 scratch, | 532 scratch, |
| 533 result, | 533 result, |
| 534 &miss, // When not a string. | 534 &miss, // When not a string. |
| 535 &miss, // When not a number. | 535 &miss, // When not a number. |
| 536 &miss, // When index out of range. | 536 &miss, // When index out of range. |
| 537 STRING_INDEX_IS_ARRAY_INDEX); | 537 STRING_INDEX_IS_ARRAY_INDEX); |
| 538 char_at_generator.GenerateFast(masm); | 538 char_at_generator.GenerateFast(masm); |
| 539 __ ret(0); | 539 __ ret(0); |
| 540 | 540 |
| 541 StubRuntimeCallHelper call_helper; | 541 StubRuntimeCallHelper call_helper; |
| 542 char_at_generator.GenerateSlow(masm, call_helper); | 542 char_at_generator.GenerateSlow(masm, call_helper); |
| 543 | 543 |
| 544 __ bind(&miss); | 544 __ bind(&miss); |
| 545 GenerateMiss(masm); | 545 GenerateMiss(masm); |
| 546 } | 546 } |
| 547 | 547 |
| 548 | 548 |
| 549 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { | 549 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { |
| 550 // Return address is on the stack. | 550 // Return address is on the stack. |
| 551 Label slow; | 551 Label slow; |
| 552 | 552 |
| 553 Register receiver = ReceiverRegister(); | 553 Register receiver = ReceiverRegister(); |
| 554 Register key = NameRegister(); | 554 Register key = NameRegister(); |
| 555 Register scratch = eax; | 555 Register scratch = eax; |
| 556 ASSERT(!scratch.is(receiver) && !scratch.is(key)); | 556 DCHECK(!scratch.is(receiver) && !scratch.is(key)); |
| 557 | 557 |
| 558 // Check that the receiver isn't a smi. | 558 // Check that the receiver isn't a smi. |
| 559 __ JumpIfSmi(receiver, &slow); | 559 __ JumpIfSmi(receiver, &slow); |
| 560 | 560 |
| 561 // Check that the key is an array index, that is Uint32. | 561 // Check that the key is an array index, that is Uint32. |
| 562 __ test(key, Immediate(kSmiTagMask | kSmiSignMask)); | 562 __ test(key, Immediate(kSmiTagMask | kSmiSignMask)); |
| 563 __ j(not_zero, &slow); | 563 __ j(not_zero, &slow); |
| 564 | 564 |
| 565 // Get the map of the receiver. | 565 // Get the map of the receiver. |
| 566 __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | 566 __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 585 | 585 |
| 586 __ bind(&slow); | 586 __ bind(&slow); |
| 587 GenerateMiss(masm); | 587 GenerateMiss(masm); |
| 588 } | 588 } |
| 589 | 589 |
| 590 | 590 |
| 591 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { | 591 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { |
| 592 // The return address is on the stack. | 592 // The return address is on the stack. |
| 593 Register receiver = ReceiverRegister(); | 593 Register receiver = ReceiverRegister(); |
| 594 Register key = NameRegister(); | 594 Register key = NameRegister(); |
| 595 ASSERT(receiver.is(edx)); | 595 DCHECK(receiver.is(edx)); |
| 596 ASSERT(key.is(ecx)); | 596 DCHECK(key.is(ecx)); |
| 597 | 597 |
| 598 Label slow, notin; | 598 Label slow, notin; |
| 599 Factory* factory = masm->isolate()->factory(); | 599 Factory* factory = masm->isolate()->factory(); |
| 600 Operand mapped_location = | 600 Operand mapped_location = |
| 601 GenerateMappedArgumentsLookup( | 601 GenerateMappedArgumentsLookup( |
| 602 masm, receiver, key, ebx, eax, ¬in, &slow); | 602 masm, receiver, key, ebx, eax, ¬in, &slow); |
| 603 __ mov(eax, mapped_location); | 603 __ mov(eax, mapped_location); |
| 604 __ Ret(); | 604 __ Ret(); |
| 605 __ bind(¬in); | 605 __ bind(¬in); |
| 606 // The unmapped lookup expects that the parameter map is in ebx. | 606 // The unmapped lookup expects that the parameter map is in ebx. |
| 607 Operand unmapped_location = | 607 Operand unmapped_location = |
| 608 GenerateUnmappedArgumentsLookup(masm, key, ebx, eax, &slow); | 608 GenerateUnmappedArgumentsLookup(masm, key, ebx, eax, &slow); |
| 609 __ cmp(unmapped_location, factory->the_hole_value()); | 609 __ cmp(unmapped_location, factory->the_hole_value()); |
| 610 __ j(equal, &slow); | 610 __ j(equal, &slow); |
| 611 __ mov(eax, unmapped_location); | 611 __ mov(eax, unmapped_location); |
| 612 __ Ret(); | 612 __ Ret(); |
| 613 __ bind(&slow); | 613 __ bind(&slow); |
| 614 GenerateMiss(masm); | 614 GenerateMiss(masm); |
| 615 } | 615 } |
| 616 | 616 |
| 617 | 617 |
| 618 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { | 618 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { |
| 619 // Return address is on the stack. | 619 // Return address is on the stack. |
| 620 Label slow, notin; | 620 Label slow, notin; |
| 621 Register receiver = ReceiverRegister(); | 621 Register receiver = ReceiverRegister(); |
| 622 Register name = NameRegister(); | 622 Register name = NameRegister(); |
| 623 Register value = ValueRegister(); | 623 Register value = ValueRegister(); |
| 624 ASSERT(receiver.is(edx)); | 624 DCHECK(receiver.is(edx)); |
| 625 ASSERT(name.is(ecx)); | 625 DCHECK(name.is(ecx)); |
| 626 ASSERT(value.is(eax)); | 626 DCHECK(value.is(eax)); |
| 627 | 627 |
| 628 Operand mapped_location = | 628 Operand mapped_location = |
| 629 GenerateMappedArgumentsLookup(masm, receiver, name, ebx, edi, ¬in, | 629 GenerateMappedArgumentsLookup(masm, receiver, name, ebx, edi, ¬in, |
| 630 &slow); | 630 &slow); |
| 631 __ mov(mapped_location, value); | 631 __ mov(mapped_location, value); |
| 632 __ lea(ecx, mapped_location); | 632 __ lea(ecx, mapped_location); |
| 633 __ mov(edx, value); | 633 __ mov(edx, value); |
| 634 __ RecordWrite(ebx, ecx, edx, kDontSaveFPRegs); | 634 __ RecordWrite(ebx, ecx, edx, kDontSaveFPRegs); |
| 635 __ Ret(); | 635 __ Ret(); |
| 636 __ bind(¬in); | 636 __ bind(¬in); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 653 Label* fast_double, | 653 Label* fast_double, |
| 654 Label* slow, | 654 Label* slow, |
| 655 KeyedStoreCheckMap check_map, | 655 KeyedStoreCheckMap check_map, |
| 656 KeyedStoreIncrementLength increment_length) { | 656 KeyedStoreIncrementLength increment_length) { |
| 657 Label transition_smi_elements; | 657 Label transition_smi_elements; |
| 658 Label finish_object_store, non_double_value, transition_double_elements; | 658 Label finish_object_store, non_double_value, transition_double_elements; |
| 659 Label fast_double_without_map_check; | 659 Label fast_double_without_map_check; |
| 660 Register receiver = KeyedStoreIC::ReceiverRegister(); | 660 Register receiver = KeyedStoreIC::ReceiverRegister(); |
| 661 Register key = KeyedStoreIC::NameRegister(); | 661 Register key = KeyedStoreIC::NameRegister(); |
| 662 Register value = KeyedStoreIC::ValueRegister(); | 662 Register value = KeyedStoreIC::ValueRegister(); |
| 663 ASSERT(receiver.is(edx)); | 663 DCHECK(receiver.is(edx)); |
| 664 ASSERT(key.is(ecx)); | 664 DCHECK(key.is(ecx)); |
| 665 ASSERT(value.is(eax)); | 665 DCHECK(value.is(eax)); |
| 666 // key is a smi. | 666 // key is a smi. |
| 667 // ebx: FixedArray receiver->elements | 667 // ebx: FixedArray receiver->elements |
| 668 // edi: receiver map | 668 // edi: receiver map |
| 669 // Fast case: Do the store, could either Object or double. | 669 // Fast case: Do the store, could either Object or double. |
| 670 __ bind(fast_object); | 670 __ bind(fast_object); |
| 671 if (check_map == kCheckMap) { | 671 if (check_map == kCheckMap) { |
| 672 __ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset)); | 672 __ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset)); |
| 673 __ cmp(edi, masm->isolate()->factory()->fixed_array_map()); | 673 __ cmp(edi, masm->isolate()->factory()->fixed_array_map()); |
| 674 __ j(not_equal, fast_double); | 674 __ j(not_equal, fast_double); |
| 675 } | 675 } |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 | 801 |
| 802 | 802 |
| 803 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, | 803 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, |
| 804 StrictMode strict_mode) { | 804 StrictMode strict_mode) { |
| 805 // Return address is on the stack. | 805 // Return address is on the stack. |
| 806 Label slow, fast_object, fast_object_grow; | 806 Label slow, fast_object, fast_object_grow; |
| 807 Label fast_double, fast_double_grow; | 807 Label fast_double, fast_double_grow; |
| 808 Label array, extra, check_if_double_array; | 808 Label array, extra, check_if_double_array; |
| 809 Register receiver = ReceiverRegister(); | 809 Register receiver = ReceiverRegister(); |
| 810 Register key = NameRegister(); | 810 Register key = NameRegister(); |
| 811 ASSERT(receiver.is(edx)); | 811 DCHECK(receiver.is(edx)); |
| 812 ASSERT(key.is(ecx)); | 812 DCHECK(key.is(ecx)); |
| 813 | 813 |
| 814 // Check that the object isn't a smi. | 814 // Check that the object isn't a smi. |
| 815 __ JumpIfSmi(receiver, &slow); | 815 __ JumpIfSmi(receiver, &slow); |
| 816 // Get the map from the receiver. | 816 // Get the map from the receiver. |
| 817 __ mov(edi, FieldOperand(receiver, HeapObject::kMapOffset)); | 817 __ mov(edi, FieldOperand(receiver, HeapObject::kMapOffset)); |
| 818 // Check that the receiver does not require access checks and is not observed. | 818 // Check that the receiver does not require access checks and is not observed. |
| 819 // The generic stub does not perform map checks or handle observed objects. | 819 // The generic stub does not perform map checks or handle observed objects. |
| 820 __ test_b(FieldOperand(edi, Map::kBitFieldOffset), | 820 __ test_b(FieldOperand(edi, Map::kBitFieldOffset), |
| 821 1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved); | 821 1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved); |
| 822 __ j(not_zero, &slow); | 822 __ j(not_zero, &slow); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 881 &slow, kCheckMap, kDontIncrementLength); | 881 &slow, kCheckMap, kDontIncrementLength); |
| 882 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, | 882 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, |
| 883 &slow, kDontCheckMap, kIncrementLength); | 883 &slow, kDontCheckMap, kIncrementLength); |
| 884 } | 884 } |
| 885 | 885 |
| 886 | 886 |
| 887 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { | 887 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { |
| 888 // The return address is on the stack. | 888 // The return address is on the stack. |
| 889 Register receiver = ReceiverRegister(); | 889 Register receiver = ReceiverRegister(); |
| 890 Register name = NameRegister(); | 890 Register name = NameRegister(); |
| 891 ASSERT(receiver.is(edx)); | 891 DCHECK(receiver.is(edx)); |
| 892 ASSERT(name.is(ecx)); | 892 DCHECK(name.is(ecx)); |
| 893 | 893 |
| 894 // Probe the stub cache. | 894 // Probe the stub cache. |
| 895 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 895 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
| 896 Code::ComputeHandlerFlags(Code::LOAD_IC)); | 896 Code::ComputeHandlerFlags(Code::LOAD_IC)); |
| 897 masm->isolate()->stub_cache()->GenerateProbe( | 897 masm->isolate()->stub_cache()->GenerateProbe( |
| 898 masm, flags, receiver, name, ebx, eax); | 898 masm, flags, receiver, name, ebx, eax); |
| 899 | 899 |
| 900 // Cache miss: Jump to runtime. | 900 // Cache miss: Jump to runtime. |
| 901 GenerateMiss(masm); | 901 GenerateMiss(masm); |
| 902 } | 902 } |
| 903 | 903 |
| 904 | 904 |
| 905 void LoadIC::GenerateNormal(MacroAssembler* masm) { | 905 void LoadIC::GenerateNormal(MacroAssembler* masm) { |
| 906 Register dictionary = eax; | 906 Register dictionary = eax; |
| 907 ASSERT(!dictionary.is(ReceiverRegister())); | 907 DCHECK(!dictionary.is(ReceiverRegister())); |
| 908 ASSERT(!dictionary.is(NameRegister())); | 908 DCHECK(!dictionary.is(NameRegister())); |
| 909 | 909 |
| 910 Label slow; | 910 Label slow; |
| 911 | 911 |
| 912 __ mov(dictionary, | 912 __ mov(dictionary, |
| 913 FieldOperand(ReceiverRegister(), JSObject::kPropertiesOffset)); | 913 FieldOperand(ReceiverRegister(), JSObject::kPropertiesOffset)); |
| 914 GenerateDictionaryLoad(masm, &slow, dictionary, NameRegister(), edi, ebx, | 914 GenerateDictionaryLoad(masm, &slow, dictionary, NameRegister(), edi, ebx, |
| 915 eax); | 915 eax); |
| 916 __ ret(0); | 916 __ ret(0); |
| 917 | 917 |
| 918 // Dictionary load failed, go slow (but don't miss). | 918 // Dictionary load failed, go slow (but don't miss). |
| 919 __ bind(&slow); | 919 __ bind(&slow); |
| 920 GenerateRuntimeGetProperty(masm); | 920 GenerateRuntimeGetProperty(masm); |
| 921 } | 921 } |
| 922 | 922 |
| 923 | 923 |
| 924 static void LoadIC_PushArgs(MacroAssembler* masm) { | 924 static void LoadIC_PushArgs(MacroAssembler* masm) { |
| 925 Register receiver = LoadIC::ReceiverRegister(); | 925 Register receiver = LoadIC::ReceiverRegister(); |
| 926 Register name = LoadIC::NameRegister(); | 926 Register name = LoadIC::NameRegister(); |
| 927 ASSERT(!ebx.is(receiver) && !ebx.is(name)); | 927 DCHECK(!ebx.is(receiver) && !ebx.is(name)); |
| 928 | 928 |
| 929 __ pop(ebx); | 929 __ pop(ebx); |
| 930 __ push(receiver); | 930 __ push(receiver); |
| 931 __ push(name); | 931 __ push(name); |
| 932 __ push(ebx); | 932 __ push(ebx); |
| 933 } | 933 } |
| 934 | 934 |
| 935 | 935 |
| 936 void LoadIC::GenerateMiss(MacroAssembler* masm) { | 936 void LoadIC::GenerateMiss(MacroAssembler* masm) { |
| 937 // Return address is on the stack. | 937 // Return address is on the stack. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 967 __ TailCallExternalReference(ref, 2, 1); | 967 __ TailCallExternalReference(ref, 2, 1); |
| 968 } | 968 } |
| 969 | 969 |
| 970 | 970 |
| 971 // IC register specifications | 971 // IC register specifications |
| 972 const Register LoadIC::ReceiverRegister() { return edx; } | 972 const Register LoadIC::ReceiverRegister() { return edx; } |
| 973 const Register LoadIC::NameRegister() { return ecx; } | 973 const Register LoadIC::NameRegister() { return ecx; } |
| 974 | 974 |
| 975 | 975 |
| 976 const Register LoadIC::SlotRegister() { | 976 const Register LoadIC::SlotRegister() { |
| 977 ASSERT(FLAG_vector_ics); | 977 DCHECK(FLAG_vector_ics); |
| 978 return eax; | 978 return eax; |
| 979 } | 979 } |
| 980 | 980 |
| 981 | 981 |
| 982 const Register LoadIC::VectorRegister() { | 982 const Register LoadIC::VectorRegister() { |
| 983 ASSERT(FLAG_vector_ics); | 983 DCHECK(FLAG_vector_ics); |
| 984 return ebx; | 984 return ebx; |
| 985 } | 985 } |
| 986 | 986 |
| 987 | 987 |
| 988 const Register StoreIC::ReceiverRegister() { return edx; } | 988 const Register StoreIC::ReceiverRegister() { return edx; } |
| 989 const Register StoreIC::NameRegister() { return ecx; } | 989 const Register StoreIC::NameRegister() { return ecx; } |
| 990 const Register StoreIC::ValueRegister() { return eax; } | 990 const Register StoreIC::ValueRegister() { return eax; } |
| 991 | 991 |
| 992 | 992 |
| 993 const Register KeyedStoreIC::MapRegister() { | 993 const Register KeyedStoreIC::MapRegister() { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1015 // Cache miss: Jump to runtime. | 1015 // Cache miss: Jump to runtime. |
| 1016 GenerateMiss(masm); | 1016 GenerateMiss(masm); |
| 1017 } | 1017 } |
| 1018 | 1018 |
| 1019 | 1019 |
| 1020 static void StoreIC_PushArgs(MacroAssembler* masm) { | 1020 static void StoreIC_PushArgs(MacroAssembler* masm) { |
| 1021 Register receiver = StoreIC::ReceiverRegister(); | 1021 Register receiver = StoreIC::ReceiverRegister(); |
| 1022 Register name = StoreIC::NameRegister(); | 1022 Register name = StoreIC::NameRegister(); |
| 1023 Register value = StoreIC::ValueRegister(); | 1023 Register value = StoreIC::ValueRegister(); |
| 1024 | 1024 |
| 1025 ASSERT(!ebx.is(receiver) && !ebx.is(name) && !ebx.is(value)); | 1025 DCHECK(!ebx.is(receiver) && !ebx.is(name) && !ebx.is(value)); |
| 1026 | 1026 |
| 1027 __ pop(ebx); | 1027 __ pop(ebx); |
| 1028 __ push(receiver); | 1028 __ push(receiver); |
| 1029 __ push(name); | 1029 __ push(name); |
| 1030 __ push(value); | 1030 __ push(value); |
| 1031 __ push(ebx); | 1031 __ push(ebx); |
| 1032 } | 1032 } |
| 1033 | 1033 |
| 1034 | 1034 |
| 1035 void StoreIC::GenerateMiss(MacroAssembler* masm) { | 1035 void StoreIC::GenerateMiss(MacroAssembler* masm) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1066 __ bind(&restore_miss); | 1066 __ bind(&restore_miss); |
| 1067 __ pop(receiver); | 1067 __ pop(receiver); |
| 1068 __ IncrementCounter(counters->store_normal_miss(), 1); | 1068 __ IncrementCounter(counters->store_normal_miss(), 1); |
| 1069 GenerateMiss(masm); | 1069 GenerateMiss(masm); |
| 1070 } | 1070 } |
| 1071 | 1071 |
| 1072 | 1072 |
| 1073 void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, | 1073 void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, |
| 1074 StrictMode strict_mode) { | 1074 StrictMode strict_mode) { |
| 1075 // Return address is on the stack. | 1075 // Return address is on the stack. |
| 1076 ASSERT(!ebx.is(ReceiverRegister()) && !ebx.is(NameRegister()) && | 1076 DCHECK(!ebx.is(ReceiverRegister()) && !ebx.is(NameRegister()) && |
| 1077 !ebx.is(ValueRegister())); | 1077 !ebx.is(ValueRegister())); |
| 1078 __ pop(ebx); | 1078 __ pop(ebx); |
| 1079 __ push(ReceiverRegister()); | 1079 __ push(ReceiverRegister()); |
| 1080 __ push(NameRegister()); | 1080 __ push(NameRegister()); |
| 1081 __ push(ValueRegister()); | 1081 __ push(ValueRegister()); |
| 1082 __ push(Immediate(Smi::FromInt(strict_mode))); | 1082 __ push(Immediate(Smi::FromInt(strict_mode))); |
| 1083 __ push(ebx); // return address | 1083 __ push(ebx); // return address |
| 1084 | 1084 |
| 1085 // Do tail-call to runtime routine. | 1085 // Do tail-call to runtime routine. |
| 1086 __ TailCallRuntime(Runtime::kSetProperty, 4, 1); | 1086 __ TailCallRuntime(Runtime::kSetProperty, 4, 1); |
| 1087 } | 1087 } |
| 1088 | 1088 |
| 1089 | 1089 |
| 1090 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, | 1090 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, |
| 1091 StrictMode strict_mode) { | 1091 StrictMode strict_mode) { |
| 1092 // Return address is on the stack. | 1092 // Return address is on the stack. |
| 1093 ASSERT(!ebx.is(ReceiverRegister()) && !ebx.is(NameRegister()) && | 1093 DCHECK(!ebx.is(ReceiverRegister()) && !ebx.is(NameRegister()) && |
| 1094 !ebx.is(ValueRegister())); | 1094 !ebx.is(ValueRegister())); |
| 1095 __ pop(ebx); | 1095 __ pop(ebx); |
| 1096 __ push(ReceiverRegister()); | 1096 __ push(ReceiverRegister()); |
| 1097 __ push(NameRegister()); | 1097 __ push(NameRegister()); |
| 1098 __ push(ValueRegister()); | 1098 __ push(ValueRegister()); |
| 1099 __ push(Immediate(Smi::FromInt(strict_mode))); | 1099 __ push(Immediate(Smi::FromInt(strict_mode))); |
| 1100 __ push(ebx); // return address | 1100 __ push(ebx); // return address |
| 1101 | 1101 |
| 1102 // Do tail-call to runtime routine. | 1102 // Do tail-call to runtime routine. |
| 1103 __ TailCallRuntime(Runtime::kSetProperty, 4, 1); | 1103 __ TailCallRuntime(Runtime::kSetProperty, 4, 1); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1170 | 1170 |
| 1171 | 1171 |
| 1172 void PatchInlinedSmiCode(Address address, InlinedSmiCheck check) { | 1172 void PatchInlinedSmiCode(Address address, InlinedSmiCheck check) { |
| 1173 // The address of the instruction following the call. | 1173 // The address of the instruction following the call. |
| 1174 Address test_instruction_address = | 1174 Address test_instruction_address = |
| 1175 address + Assembler::kCallTargetAddressOffset; | 1175 address + Assembler::kCallTargetAddressOffset; |
| 1176 | 1176 |
| 1177 // If the instruction following the call is not a test al, nothing | 1177 // If the instruction following the call is not a test al, nothing |
| 1178 // was inlined. | 1178 // was inlined. |
| 1179 if (*test_instruction_address != Assembler::kTestAlByte) { | 1179 if (*test_instruction_address != Assembler::kTestAlByte) { |
| 1180 ASSERT(*test_instruction_address == Assembler::kNopByte); | 1180 DCHECK(*test_instruction_address == Assembler::kNopByte); |
| 1181 return; | 1181 return; |
| 1182 } | 1182 } |
| 1183 | 1183 |
| 1184 Address delta_address = test_instruction_address + 1; | 1184 Address delta_address = test_instruction_address + 1; |
| 1185 // The delta to the start of the map check instruction and the | 1185 // The delta to the start of the map check instruction and the |
| 1186 // condition code uses at the patched jump. | 1186 // condition code uses at the patched jump. |
| 1187 uint8_t delta = *reinterpret_cast<uint8_t*>(delta_address); | 1187 uint8_t delta = *reinterpret_cast<uint8_t*>(delta_address); |
| 1188 if (FLAG_trace_ic) { | 1188 if (FLAG_trace_ic) { |
| 1189 PrintF("[ patching ic at %p, test=%p, delta=%d\n", | 1189 PrintF("[ patching ic at %p, test=%p, delta=%d\n", |
| 1190 address, test_instruction_address, delta); | 1190 address, test_instruction_address, delta); |
| 1191 } | 1191 } |
| 1192 | 1192 |
| 1193 // Patch with a short conditional jump. Enabling means switching from a short | 1193 // Patch with a short conditional jump. Enabling means switching from a short |
| 1194 // jump-if-carry/not-carry to jump-if-zero/not-zero, whereas disabling is the | 1194 // jump-if-carry/not-carry to jump-if-zero/not-zero, whereas disabling is the |
| 1195 // reverse operation of that. | 1195 // reverse operation of that. |
| 1196 Address jmp_address = test_instruction_address - delta; | 1196 Address jmp_address = test_instruction_address - delta; |
| 1197 ASSERT((check == ENABLE_INLINED_SMI_CHECK) | 1197 DCHECK((check == ENABLE_INLINED_SMI_CHECK) |
| 1198 ? (*jmp_address == Assembler::kJncShortOpcode || | 1198 ? (*jmp_address == Assembler::kJncShortOpcode || |
| 1199 *jmp_address == Assembler::kJcShortOpcode) | 1199 *jmp_address == Assembler::kJcShortOpcode) |
| 1200 : (*jmp_address == Assembler::kJnzShortOpcode || | 1200 : (*jmp_address == Assembler::kJnzShortOpcode || |
| 1201 *jmp_address == Assembler::kJzShortOpcode)); | 1201 *jmp_address == Assembler::kJzShortOpcode)); |
| 1202 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) | 1202 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) |
| 1203 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) | 1203 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) |
| 1204 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); | 1204 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); |
| 1205 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1205 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
| 1206 } | 1206 } |
| 1207 | 1207 |
| 1208 | 1208 |
| 1209 } } // namespace v8::internal | 1209 } } // namespace v8::internal |
| 1210 | 1210 |
| 1211 #endif // V8_TARGET_ARCH_IA32 | 1211 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |