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 |