OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 | 75 |
76 __ bind(&miss); | 76 __ bind(&miss); |
77 } | 77 } |
78 | 78 |
79 | 79 |
80 // Helper function used to check that the dictionary doesn't contain | 80 // Helper function used to check that the dictionary doesn't contain |
81 // the property. This function may return false negatives, so miss_label | 81 // the property. This function may return false negatives, so miss_label |
82 // must always call a backup property check that is complete. | 82 // must always call a backup property check that is complete. |
83 // This function is safe to call if the receiver has fast properties. | 83 // This function is safe to call if the receiver has fast properties. |
84 // Name must be a symbol and receiver must be a heap object. | 84 // Name must be a symbol and receiver must be a heap object. |
85 MUST_USE_RESULT static MaybeObject* GenerateDictionaryNegativeLookup( | 85 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, |
| 86 Label* miss_label, |
| 87 Register receiver, |
| 88 Handle<String> name, |
| 89 Register r0, |
| 90 Register r1) { |
| 91 ASSERT(name->IsSymbol()); |
| 92 Counters* counters = masm->isolate()->counters(); |
| 93 __ IncrementCounter(counters->negative_lookups(), 1); |
| 94 __ IncrementCounter(counters->negative_lookups_miss(), 1); |
| 95 |
| 96 __ movq(r0, FieldOperand(receiver, HeapObject::kMapOffset)); |
| 97 |
| 98 const int kInterceptorOrAccessCheckNeededMask = |
| 99 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); |
| 100 |
| 101 // Bail out if the receiver has a named interceptor or requires access checks. |
| 102 __ testb(FieldOperand(r0, Map::kBitFieldOffset), |
| 103 Immediate(kInterceptorOrAccessCheckNeededMask)); |
| 104 __ j(not_zero, miss_label); |
| 105 |
| 106 // Check that receiver is a JSObject. |
| 107 __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE); |
| 108 __ j(below, miss_label); |
| 109 |
| 110 // Load properties array. |
| 111 Register properties = r0; |
| 112 __ movq(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); |
| 113 |
| 114 // Check that the properties array is a dictionary. |
| 115 __ CompareRoot(FieldOperand(properties, HeapObject::kMapOffset), |
| 116 Heap::kHashTableMapRootIndex); |
| 117 __ j(not_equal, miss_label); |
| 118 |
| 119 Label done; |
| 120 StringDictionaryLookupStub::GenerateNegativeLookup(masm, |
| 121 miss_label, |
| 122 &done, |
| 123 properties, |
| 124 name, |
| 125 r1); |
| 126 __ bind(&done); |
| 127 __ DecrementCounter(counters->negative_lookups_miss(), 1); |
| 128 } |
| 129 |
| 130 |
| 131 // TODO(kmillikin): Eliminate this function when the stub cache is fully |
| 132 // handlified. |
| 133 MUST_USE_RESULT static MaybeObject* TryGenerateDictionaryNegativeLookup( |
86 MacroAssembler* masm, | 134 MacroAssembler* masm, |
87 Label* miss_label, | 135 Label* miss_label, |
88 Register receiver, | 136 Register receiver, |
89 String* name, | 137 String* name, |
90 Register r0, | 138 Register r0, |
91 Register r1) { | 139 Register r1) { |
92 ASSERT(name->IsSymbol()); | 140 ASSERT(name->IsSymbol()); |
93 Counters* counters = masm->isolate()->counters(); | 141 Counters* counters = masm->isolate()->counters(); |
94 __ IncrementCounter(counters->negative_lookups(), 1); | 142 __ IncrementCounter(counters->negative_lookups(), 1); |
95 __ IncrementCounter(counters->negative_lookups_miss(), 1); | 143 __ IncrementCounter(counters->negative_lookups_miss(), 1); |
(...skipping 15 matching lines...) Expand all Loading... |
111 // Load properties array. | 159 // Load properties array. |
112 Register properties = r0; | 160 Register properties = r0; |
113 __ movq(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 161 __ movq(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); |
114 | 162 |
115 // Check that the properties array is a dictionary. | 163 // Check that the properties array is a dictionary. |
116 __ CompareRoot(FieldOperand(properties, HeapObject::kMapOffset), | 164 __ CompareRoot(FieldOperand(properties, HeapObject::kMapOffset), |
117 Heap::kHashTableMapRootIndex); | 165 Heap::kHashTableMapRootIndex); |
118 __ j(not_equal, miss_label); | 166 __ j(not_equal, miss_label); |
119 | 167 |
120 Label done; | 168 Label done; |
121 MaybeObject* result = StringDictionaryLookupStub::GenerateNegativeLookup( | 169 MaybeObject* result = StringDictionaryLookupStub::TryGenerateNegativeLookup( |
122 masm, | 170 masm, |
123 miss_label, | 171 miss_label, |
124 &done, | 172 &done, |
125 properties, | 173 properties, |
126 name, | 174 name, |
127 r1); | 175 r1); |
128 if (result->IsFailure()) return result; | 176 if (result->IsFailure()) return result; |
129 | 177 |
130 __ bind(&done); | 178 __ bind(&done); |
131 __ DecrementCounter(counters->negative_lookups_miss(), 1); | 179 __ DecrementCounter(counters->negative_lookups_miss(), 1); |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 __ TryGetFunctionPrototype(receiver, result, miss_label); | 353 __ TryGetFunctionPrototype(receiver, result, miss_label); |
306 if (!result.is(rax)) __ movq(rax, result); | 354 if (!result.is(rax)) __ movq(rax, result); |
307 __ ret(0); | 355 __ ret(0); |
308 } | 356 } |
309 | 357 |
310 | 358 |
311 // Load a fast property out of a holder object (src). In-object properties | 359 // Load a fast property out of a holder object (src). In-object properties |
312 // are loaded directly otherwise the property is loaded from the properties | 360 // are loaded directly otherwise the property is loaded from the properties |
313 // fixed array. | 361 // fixed array. |
314 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, | 362 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, |
315 Register dst, Register src, | 363 Register dst, |
316 JSObject* holder, int index) { | 364 Register src, |
| 365 Handle<JSObject> holder, |
| 366 int index) { |
317 // Adjust for the number of properties stored in the holder. | 367 // Adjust for the number of properties stored in the holder. |
318 index -= holder->map()->inobject_properties(); | 368 index -= holder->map()->inobject_properties(); |
319 if (index < 0) { | 369 if (index < 0) { |
320 // Get the property straight out of the holder. | 370 // Get the property straight out of the holder. |
321 int offset = holder->map()->instance_size() + (index * kPointerSize); | 371 int offset = holder->map()->instance_size() + (index * kPointerSize); |
322 __ movq(dst, FieldOperand(src, offset)); | 372 __ movq(dst, FieldOperand(src, offset)); |
323 } else { | 373 } else { |
324 // Calculate the offset into the properties array. | 374 // Calculate the offset into the properties array. |
325 int offset = index * kPointerSize + FixedArray::kHeaderSize; | 375 int offset = index * kPointerSize + FixedArray::kHeaderSize; |
326 __ movq(dst, FieldOperand(src, JSObject::kPropertiesOffset)); | 376 __ movq(dst, FieldOperand(src, JSObject::kPropertiesOffset)); |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 | 743 |
694 StubCompiler* stub_compiler_; | 744 StubCompiler* stub_compiler_; |
695 const ParameterCount& arguments_; | 745 const ParameterCount& arguments_; |
696 Register name_; | 746 Register name_; |
697 Code::ExtraICState extra_ic_state_; | 747 Code::ExtraICState extra_ic_state_; |
698 }; | 748 }; |
699 | 749 |
700 | 750 |
701 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { | 751 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { |
702 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); | 752 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); |
703 Code* code = NULL; | 753 Handle<Code> code = (kind == Code::LOAD_IC) |
704 if (kind == Code::LOAD_IC) { | 754 ? masm->isolate()->builtins()->LoadIC_Miss() |
705 code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss); | 755 : masm->isolate()->builtins()->KeyedLoadIC_Miss(); |
706 } else { | 756 __ Jump(code, RelocInfo::CODE_TARGET); |
707 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss); | |
708 } | |
709 | |
710 Handle<Code> ic(code); | |
711 __ Jump(ic, RelocInfo::CODE_TARGET); | |
712 } | 757 } |
713 | 758 |
714 | 759 |
715 void StubCompiler::GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm) { | 760 void StubCompiler::GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm) { |
716 Code* code = masm->isolate()->builtins()->builtin( | 761 Code* code = masm->isolate()->builtins()->builtin( |
717 Builtins::kKeyedLoadIC_MissForceGeneric); | 762 Builtins::kKeyedLoadIC_MissForceGeneric); |
718 Handle<Code> ic(code); | 763 Handle<Code> ic(code); |
719 __ Jump(ic, RelocInfo::CODE_TARGET); | 764 __ Jump(ic, RelocInfo::CODE_TARGET); |
720 } | 765 } |
721 | 766 |
722 | 767 |
723 // Both name_reg and receiver_reg are preserved on jumps to miss_label, | 768 // Both name_reg and receiver_reg are preserved on jumps to miss_label, |
724 // but may be destroyed if store is successful. | 769 // but may be destroyed if store is successful. |
725 void StubCompiler::GenerateStoreField(MacroAssembler* masm, | 770 void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
726 JSObject* object, | 771 Handle<JSObject> object, |
727 int index, | 772 int index, |
728 Map* transition, | 773 Handle<Map> transition, |
729 Register receiver_reg, | 774 Register receiver_reg, |
730 Register name_reg, | 775 Register name_reg, |
731 Register scratch, | 776 Register scratch, |
732 Label* miss_label) { | 777 Label* miss_label) { |
733 // Check that the object isn't a smi. | 778 // Check that the object isn't a smi. |
734 __ JumpIfSmi(receiver_reg, miss_label); | 779 __ JumpIfSmi(receiver_reg, miss_label); |
735 | 780 |
736 // Check that the map of the object hasn't changed. | 781 // Check that the map of the object hasn't changed. |
737 __ Cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset), | 782 __ Cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset), |
738 Handle<Map>(object->map())); | 783 Handle<Map>(object->map())); |
739 __ j(not_equal, miss_label); | 784 __ j(not_equal, miss_label); |
740 | 785 |
741 // Perform global security token check if needed. | 786 // Perform global security token check if needed. |
742 if (object->IsJSGlobalProxy()) { | 787 if (object->IsJSGlobalProxy()) { |
743 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); | 788 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); |
744 } | 789 } |
745 | 790 |
746 // Stub never generated for non-global objects that require access | 791 // Stub never generated for non-global objects that require access |
747 // checks. | 792 // checks. |
748 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 793 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
749 | 794 |
750 // Perform map transition for the receiver if necessary. | 795 // Perform map transition for the receiver if necessary. |
751 if ((transition != NULL) && (object->map()->unused_property_fields() == 0)) { | 796 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) { |
752 // The properties must be extended before we can store the value. | 797 // The properties must be extended before we can store the value. |
753 // We jump to a runtime call that extends the properties array. | 798 // We jump to a runtime call that extends the properties array. |
754 __ pop(scratch); // Return address. | 799 __ pop(scratch); // Return address. |
755 __ push(receiver_reg); | 800 __ push(receiver_reg); |
756 __ Push(Handle<Map>(transition)); | 801 __ Push(transition); |
757 __ push(rax); | 802 __ push(rax); |
758 __ push(scratch); | 803 __ push(scratch); |
759 __ TailCallExternalReference( | 804 __ TailCallExternalReference( |
760 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), | 805 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), |
761 masm->isolate()), | 806 masm->isolate()), |
762 3, | 807 3, |
763 1); | 808 1); |
764 return; | 809 return; |
765 } | 810 } |
766 | 811 |
767 if (transition != NULL) { | 812 if (!transition.is_null()) { |
768 // Update the map of the object; no write barrier updating is | 813 // Update the map of the object; no write barrier updating is |
769 // needed because the map is never in new space. | 814 // needed because the map is never in new space. |
770 __ Move(FieldOperand(receiver_reg, HeapObject::kMapOffset), | 815 __ Move(FieldOperand(receiver_reg, HeapObject::kMapOffset), transition); |
771 Handle<Map>(transition)); | |
772 } | 816 } |
773 | 817 |
774 // Adjust for the number of properties stored in the object. Even in the | 818 // Adjust for the number of properties stored in the object. Even in the |
775 // face of a transition we can use the old map here because the size of the | 819 // face of a transition we can use the old map here because the size of the |
776 // object and the number of in-object properties is not going to change. | 820 // object and the number of in-object properties is not going to change. |
777 index -= object->map()->inobject_properties(); | 821 index -= object->map()->inobject_properties(); |
778 | 822 |
779 if (index < 0) { | 823 if (index < 0) { |
780 // Set the property straight into the object. | 824 // Set the property straight into the object. |
781 int offset = object->map()->instance_size() + (index * kPointerSize); | 825 int offset = object->map()->instance_size() + (index * kPointerSize); |
(...skipping 19 matching lines...) Expand all Loading... |
801 } | 845 } |
802 | 846 |
803 // Return the value (register rax). | 847 // Return the value (register rax). |
804 __ ret(0); | 848 __ ret(0); |
805 } | 849 } |
806 | 850 |
807 | 851 |
808 // Generate code to check that a global property cell is empty. Create | 852 // Generate code to check that a global property cell is empty. Create |
809 // the property cell at compilation time if no cell exists for the | 853 // the property cell at compilation time if no cell exists for the |
810 // property. | 854 // property. |
811 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCell( | 855 static void GenerateCheckPropertyCell(MacroAssembler* masm, |
| 856 Handle<GlobalObject> global, |
| 857 Handle<String> name, |
| 858 Register scratch, |
| 859 Label* miss) { |
| 860 Handle<JSGlobalPropertyCell> cell = |
| 861 GlobalObject::EnsurePropertyCell(global, name); |
| 862 ASSERT(cell->value()->IsTheHole()); |
| 863 __ Move(scratch, cell); |
| 864 __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), |
| 865 masm->isolate()->factory()->the_hole_value()); |
| 866 __ j(not_equal, miss); |
| 867 } |
| 868 |
| 869 |
| 870 // TODO(kmillikin): Eliminate this function when the stub cache is fully |
| 871 // handlified. |
| 872 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCell( |
812 MacroAssembler* masm, | 873 MacroAssembler* masm, |
813 GlobalObject* global, | 874 GlobalObject* global, |
814 String* name, | 875 String* name, |
815 Register scratch, | 876 Register scratch, |
816 Label* miss) { | 877 Label* miss) { |
817 Object* probe; | 878 Object* probe; |
818 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); | 879 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); |
819 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 880 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
820 } | 881 } |
821 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); | 882 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); |
822 ASSERT(cell->value()->IsTheHole()); | 883 ASSERT(cell->value()->IsTheHole()); |
823 __ Move(scratch, Handle<Object>(cell)); | 884 __ Move(scratch, Handle<Object>(cell)); |
824 __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), | 885 __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), |
825 masm->isolate()->factory()->the_hole_value()); | 886 masm->isolate()->factory()->the_hole_value()); |
826 __ j(not_equal, miss); | 887 __ j(not_equal, miss); |
827 return cell; | 888 return cell; |
828 } | 889 } |
829 | 890 |
830 | 891 |
| 892 // Calls GenerateCheckPropertyCell for each global object in the prototype chain |
| 893 // from object to (but not including) holder. |
| 894 static void GenerateCheckPropertyCells(MacroAssembler* masm, |
| 895 Handle<JSObject> object, |
| 896 Handle<JSObject> holder, |
| 897 Handle<String> name, |
| 898 Register scratch, |
| 899 Label* miss) { |
| 900 Handle<JSObject> current = object; |
| 901 while (!current.is_identical_to(holder)) { |
| 902 if (current->IsGlobalObject()) { |
| 903 GenerateCheckPropertyCell(masm, |
| 904 Handle<GlobalObject>::cast(current), |
| 905 name, |
| 906 scratch, |
| 907 miss); |
| 908 } |
| 909 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); |
| 910 } |
| 911 } |
| 912 |
| 913 |
| 914 // TODO(kmillikin): Eliminate this function when the stub cache is fully |
| 915 // handlified. |
| 916 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCells( |
| 917 MacroAssembler* masm, |
| 918 JSObject* object, |
| 919 JSObject* holder, |
| 920 String* name, |
| 921 Register scratch, |
| 922 Label* miss) { |
| 923 JSObject* current = object; |
| 924 while (current != holder) { |
| 925 if (current->IsGlobalObject()) { |
| 926 // Returns a cell or a failure. |
| 927 MaybeObject* result = TryGenerateCheckPropertyCell( |
| 928 masm, |
| 929 GlobalObject::cast(current), |
| 930 name, |
| 931 scratch, |
| 932 miss); |
| 933 if (result->IsFailure()) return result; |
| 934 } |
| 935 ASSERT(current->IsJSObject()); |
| 936 current = JSObject::cast(current->GetPrototype()); |
| 937 } |
| 938 return NULL; |
| 939 } |
| 940 |
| 941 |
831 #undef __ | 942 #undef __ |
832 #define __ ACCESS_MASM((masm())) | 943 #define __ ACCESS_MASM((masm())) |
833 | 944 |
834 | 945 |
| 946 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, |
| 947 Register object_reg, |
| 948 Handle<JSObject> holder, |
| 949 Register holder_reg, |
| 950 Register scratch1, |
| 951 Register scratch2, |
| 952 Handle<String> name, |
| 953 int save_at_depth, |
| 954 Label* miss) { |
| 955 // Make sure there's no overlap between holder and object registers. |
| 956 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
| 957 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
| 958 && !scratch2.is(scratch1)); |
| 959 |
| 960 // Keep track of the current object in register reg. On the first |
| 961 // iteration, reg is an alias for object_reg, on later iterations, |
| 962 // it is an alias for holder_reg. |
| 963 Register reg = object_reg; |
| 964 int depth = 0; |
| 965 |
| 966 if (save_at_depth == depth) { |
| 967 __ movq(Operand(rsp, kPointerSize), object_reg); |
| 968 } |
| 969 |
| 970 // Check the maps in the prototype chain. |
| 971 // Traverse the prototype chain from the object and do map checks. |
| 972 Handle<JSObject> current = object; |
| 973 while (!current.is_identical_to(holder)) { |
| 974 ++depth; |
| 975 |
| 976 // Only global objects and objects that do not require access |
| 977 // checks are allowed in stubs. |
| 978 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); |
| 979 |
| 980 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); |
| 981 if (!current->HasFastProperties() && |
| 982 !current->IsJSGlobalObject() && |
| 983 !current->IsJSGlobalProxy()) { |
| 984 if (!name->IsSymbol()) { |
| 985 name = factory()->LookupSymbol(name); |
| 986 } |
| 987 ASSERT(current->property_dictionary()->FindEntry(*name) == |
| 988 StringDictionary::kNotFound); |
| 989 |
| 990 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, |
| 991 scratch1, scratch2); |
| 992 |
| 993 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
| 994 reg = holder_reg; // From now on the object will be in holder_reg. |
| 995 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); |
| 996 } else { |
| 997 bool in_new_space = heap()->InNewSpace(*prototype); |
| 998 Handle<Map> current_map(current->map()); |
| 999 if (in_new_space) { |
| 1000 // Save the map in scratch1 for later. |
| 1001 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
| 1002 __ Cmp(scratch1, current_map); |
| 1003 } else { |
| 1004 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), current_map); |
| 1005 } |
| 1006 // Branch on the result of the map check. |
| 1007 __ j(not_equal, miss); |
| 1008 // Check access rights to the global object. This has to happen after |
| 1009 // the map check so that we know that the object is actually a global |
| 1010 // object. |
| 1011 if (current->IsJSGlobalProxy()) { |
| 1012 __ CheckAccessGlobalProxy(reg, scratch2, miss); |
| 1013 } |
| 1014 reg = holder_reg; // From now on the object will be in holder_reg. |
| 1015 |
| 1016 if (in_new_space) { |
| 1017 // The prototype is in new space; we cannot store a reference to it |
| 1018 // in the code. Load it from the map. |
| 1019 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); |
| 1020 } else { |
| 1021 // The prototype is in old space; load it directly. |
| 1022 __ Move(reg, prototype); |
| 1023 } |
| 1024 } |
| 1025 |
| 1026 if (save_at_depth == depth) { |
| 1027 __ movq(Operand(rsp, kPointerSize), reg); |
| 1028 } |
| 1029 |
| 1030 // Go to the next object in the prototype chain. |
| 1031 current = prototype; |
| 1032 } |
| 1033 ASSERT(current.is_identical_to(holder)); |
| 1034 |
| 1035 // Log the check depth. |
| 1036 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); |
| 1037 |
| 1038 // Check the holder map. |
| 1039 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), Handle<Map>(holder->map())); |
| 1040 __ j(not_equal, miss); |
| 1041 |
| 1042 // Perform security check for access to the global object. |
| 1043 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); |
| 1044 if (current->IsJSGlobalProxy()) { |
| 1045 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
| 1046 } |
| 1047 |
| 1048 // If we've skipped any global objects, it's not enough to verify that |
| 1049 // their maps haven't changed. We also need to check that the property |
| 1050 // cell for the property is still empty. |
| 1051 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); |
| 1052 |
| 1053 // Return the register containing the holder. |
| 1054 return reg; |
| 1055 } |
| 1056 |
| 1057 |
835 Register StubCompiler::CheckPrototypes(JSObject* object, | 1058 Register StubCompiler::CheckPrototypes(JSObject* object, |
836 Register object_reg, | 1059 Register object_reg, |
837 JSObject* holder, | 1060 JSObject* holder, |
838 Register holder_reg, | 1061 Register holder_reg, |
839 Register scratch1, | 1062 Register scratch1, |
840 Register scratch2, | 1063 Register scratch2, |
841 String* name, | 1064 String* name, |
842 int save_at_depth, | 1065 int save_at_depth, |
843 Label* miss) { | 1066 Label* miss) { |
844 // Make sure there's no overlap between holder and object registers. | 1067 // Make sure there's no overlap between holder and object registers. |
(...skipping 30 matching lines...) Expand all Loading... |
875 if (lookup_result->IsFailure()) { | 1098 if (lookup_result->IsFailure()) { |
876 set_failure(Failure::cast(lookup_result)); | 1099 set_failure(Failure::cast(lookup_result)); |
877 return reg; | 1100 return reg; |
878 } else { | 1101 } else { |
879 name = String::cast(lookup_result->ToObjectUnchecked()); | 1102 name = String::cast(lookup_result->ToObjectUnchecked()); |
880 } | 1103 } |
881 } | 1104 } |
882 ASSERT(current->property_dictionary()->FindEntry(name) == | 1105 ASSERT(current->property_dictionary()->FindEntry(name) == |
883 StringDictionary::kNotFound); | 1106 StringDictionary::kNotFound); |
884 | 1107 |
885 MaybeObject* negative_lookup = GenerateDictionaryNegativeLookup(masm(), | 1108 MaybeObject* negative_lookup = |
886 miss, | 1109 TryGenerateDictionaryNegativeLookup(masm(), |
887 reg, | 1110 miss, |
888 name, | 1111 reg, |
889 scratch1, | 1112 name, |
890 scratch2); | 1113 scratch1, |
| 1114 scratch2); |
891 if (negative_lookup->IsFailure()) { | 1115 if (negative_lookup->IsFailure()) { |
892 set_failure(Failure::cast(negative_lookup)); | 1116 set_failure(Failure::cast(negative_lookup)); |
893 return reg; | 1117 return reg; |
894 } | 1118 } |
895 | 1119 |
896 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 1120 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
897 reg = holder_reg; // from now the object is in holder_reg | 1121 reg = holder_reg; // from now the object is in holder_reg |
898 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); | 1122 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); |
899 } else if (heap()->InNewSpace(prototype)) { | 1123 } else if (heap()->InNewSpace(prototype)) { |
900 // Get the map of the current object. | 1124 // Get the map of the current object. |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
953 // the holder register. | 1177 // the holder register. |
954 ASSERT(current == holder); | 1178 ASSERT(current == holder); |
955 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 1179 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); |
956 if (current->IsJSGlobalProxy()) { | 1180 if (current->IsJSGlobalProxy()) { |
957 __ CheckAccessGlobalProxy(reg, scratch1, miss); | 1181 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
958 } | 1182 } |
959 | 1183 |
960 // If we've skipped any global objects, it's not enough to verify | 1184 // If we've skipped any global objects, it's not enough to verify |
961 // that their maps haven't changed. We also need to check that the | 1185 // that their maps haven't changed. We also need to check that the |
962 // property cell for the property is still empty. | 1186 // property cell for the property is still empty. |
963 current = object; | 1187 MaybeObject* result = TryGenerateCheckPropertyCells(masm(), |
964 while (current != holder) { | 1188 object, |
965 if (current->IsGlobalObject()) { | 1189 holder, |
966 MaybeObject* cell = GenerateCheckPropertyCell(masm(), | 1190 name, |
967 GlobalObject::cast(current), | 1191 scratch1, |
968 name, | 1192 miss); |
969 scratch1, | 1193 if (result->IsFailure()) set_failure(Failure::cast(result)); |
970 miss); | |
971 if (cell->IsFailure()) { | |
972 set_failure(Failure::cast(cell)); | |
973 return reg; | |
974 } | |
975 } | |
976 current = JSObject::cast(current->GetPrototype()); | |
977 } | |
978 | 1194 |
979 // Return the register containing the holder. | 1195 // Return the register containing the holder. |
980 return reg; | 1196 return reg; |
981 } | 1197 } |
982 | 1198 |
983 | 1199 |
984 void StubCompiler::GenerateLoadField(JSObject* object, | 1200 void StubCompiler::GenerateLoadField(Handle<JSObject> object, |
985 JSObject* holder, | 1201 Handle<JSObject> holder, |
986 Register receiver, | 1202 Register receiver, |
987 Register scratch1, | 1203 Register scratch1, |
988 Register scratch2, | 1204 Register scratch2, |
989 Register scratch3, | 1205 Register scratch3, |
990 int index, | 1206 int index, |
991 String* name, | 1207 Handle<String> name, |
992 Label* miss) { | 1208 Label* miss) { |
993 // Check that the receiver isn't a smi. | 1209 // Check that the receiver isn't a smi. |
994 __ JumpIfSmi(receiver, miss); | 1210 __ JumpIfSmi(receiver, miss); |
995 | 1211 |
996 // Check the prototype chain. | 1212 // Check the prototype chain. |
997 Register reg = | 1213 Register reg = CheckPrototypes( |
998 CheckPrototypes(object, receiver, holder, | 1214 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); |
999 scratch1, scratch2, scratch3, name, miss); | |
1000 | 1215 |
1001 // Get the value from the properties. | 1216 // Get the value from the properties. |
1002 GenerateFastPropertyLoad(masm(), rax, reg, holder, index); | 1217 GenerateFastPropertyLoad(masm(), rax, reg, holder, index); |
1003 __ ret(0); | 1218 __ ret(0); |
1004 } | 1219 } |
1005 | 1220 |
1006 | 1221 |
1007 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, | 1222 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, |
1008 JSObject* holder, | 1223 JSObject* holder, |
1009 Register receiver, | 1224 Register receiver, |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1074 __ lea(accessor_info_arg, StackSpaceOperand(0)); | 1289 __ lea(accessor_info_arg, StackSpaceOperand(0)); |
1075 | 1290 |
1076 // Emitting a stub call may try to allocate (if the code is not | 1291 // Emitting a stub call may try to allocate (if the code is not |
1077 // already generated). Do not allow the assembler to perform a | 1292 // already generated). Do not allow the assembler to perform a |
1078 // garbage collection but instead return the allocation failure | 1293 // garbage collection but instead return the allocation failure |
1079 // object. | 1294 // object. |
1080 return masm()->TryCallApiFunctionAndReturn(&fun, kStackSpace); | 1295 return masm()->TryCallApiFunctionAndReturn(&fun, kStackSpace); |
1081 } | 1296 } |
1082 | 1297 |
1083 | 1298 |
1084 void StubCompiler::GenerateLoadConstant(JSObject* object, | 1299 void StubCompiler::GenerateLoadConstant(Handle<JSObject> object, |
1085 JSObject* holder, | 1300 Handle<JSObject> holder, |
1086 Register receiver, | 1301 Register receiver, |
1087 Register scratch1, | 1302 Register scratch1, |
1088 Register scratch2, | 1303 Register scratch2, |
1089 Register scratch3, | 1304 Register scratch3, |
1090 Object* value, | 1305 Handle<Object> value, |
1091 String* name, | 1306 Handle<String> name, |
1092 Label* miss) { | 1307 Label* miss) { |
1093 // Check that the receiver isn't a smi. | 1308 // Check that the receiver isn't a smi. |
1094 __ JumpIfSmi(receiver, miss); | 1309 __ JumpIfSmi(receiver, miss); |
1095 | 1310 |
1096 // Check that the maps haven't changed. | 1311 // Check that the maps haven't changed. |
1097 CheckPrototypes(object, receiver, holder, | 1312 CheckPrototypes( |
1098 scratch1, scratch2, scratch3, name, miss); | 1313 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); |
1099 | 1314 |
1100 // Return the constant value. | 1315 // Return the constant value. |
1101 __ Move(rax, Handle<Object>(value)); | 1316 __ Move(rax, value); |
1102 __ ret(0); | 1317 __ ret(0); |
1103 } | 1318 } |
1104 | 1319 |
1105 | 1320 |
1106 void StubCompiler::GenerateLoadInterceptor(JSObject* object, | 1321 void StubCompiler::GenerateLoadInterceptor(JSObject* object, |
1107 JSObject* interceptor_holder, | 1322 JSObject* interceptor_holder, |
1108 LookupResult* lookup, | 1323 LookupResult* lookup, |
1109 Register receiver, | 1324 Register receiver, |
1110 Register name_reg, | 1325 Register name_reg, |
1111 Register scratch1, | 1326 Register scratch1, |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1191 scratch2, | 1406 scratch2, |
1192 scratch3, | 1407 scratch3, |
1193 name, | 1408 name, |
1194 miss); | 1409 miss); |
1195 } | 1410 } |
1196 | 1411 |
1197 if (lookup->type() == FIELD) { | 1412 if (lookup->type() == FIELD) { |
1198 // We found FIELD property in prototype chain of interceptor's holder. | 1413 // We found FIELD property in prototype chain of interceptor's holder. |
1199 // Retrieve a field from field's holder. | 1414 // Retrieve a field from field's holder. |
1200 GenerateFastPropertyLoad(masm(), rax, holder_reg, | 1415 GenerateFastPropertyLoad(masm(), rax, holder_reg, |
1201 lookup->holder(), lookup->GetFieldIndex()); | 1416 Handle<JSObject>(lookup->holder()), |
| 1417 lookup->GetFieldIndex()); |
1202 __ ret(0); | 1418 __ ret(0); |
1203 } else { | 1419 } else { |
1204 // We found CALLBACKS property in prototype chain of interceptor's | 1420 // We found CALLBACKS property in prototype chain of interceptor's |
1205 // holder. | 1421 // holder. |
1206 ASSERT(lookup->type() == CALLBACKS); | 1422 ASSERT(lookup->type() == CALLBACKS); |
1207 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); | 1423 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); |
1208 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); | 1424 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); |
1209 ASSERT(callback != NULL); | 1425 ASSERT(callback != NULL); |
1210 ASSERT(callback->getter() != NULL); | 1426 ASSERT(callback->getter() != NULL); |
1211 | 1427 |
(...skipping 25 matching lines...) Expand all Loading... |
1237 name_reg, interceptor_holder); | 1453 name_reg, interceptor_holder); |
1238 __ push(scratch2); // restore old return address | 1454 __ push(scratch2); // restore old return address |
1239 | 1455 |
1240 ExternalReference ref = ExternalReference( | 1456 ExternalReference ref = ExternalReference( |
1241 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate()); | 1457 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate()); |
1242 __ TailCallExternalReference(ref, 5, 1); | 1458 __ TailCallExternalReference(ref, 5, 1); |
1243 } | 1459 } |
1244 } | 1460 } |
1245 | 1461 |
1246 | 1462 |
1247 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { | 1463 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) { |
1248 if (kind_ == Code::KEYED_CALL_IC) { | 1464 if (kind_ == Code::KEYED_CALL_IC) { |
1249 __ Cmp(rcx, Handle<String>(name)); | 1465 __ Cmp(rcx, name); |
1250 __ j(not_equal, miss); | 1466 __ j(not_equal, miss); |
1251 } | 1467 } |
1252 } | 1468 } |
1253 | 1469 |
1254 | 1470 |
1255 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, | 1471 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, |
1256 JSObject* holder, | 1472 JSObject* holder, |
1257 String* name, | 1473 String* name, |
1258 Label* miss) { | 1474 Label* miss) { |
1259 ASSERT(holder->IsGlobalObject()); | 1475 ASSERT(holder->IsGlobalObject()); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1298 __ Move(rax, Handle<SharedFunctionInfo>(function->shared())); | 1514 __ Move(rax, Handle<SharedFunctionInfo>(function->shared())); |
1299 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax); | 1515 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax); |
1300 __ j(not_equal, miss); | 1516 __ j(not_equal, miss); |
1301 } else { | 1517 } else { |
1302 __ Cmp(rdi, Handle<JSFunction>(function)); | 1518 __ Cmp(rdi, Handle<JSFunction>(function)); |
1303 __ j(not_equal, miss); | 1519 __ j(not_equal, miss); |
1304 } | 1520 } |
1305 } | 1521 } |
1306 | 1522 |
1307 | 1523 |
1308 MaybeObject* CallStubCompiler::GenerateMissBranch() { | 1524 void CallStubCompiler::GenerateMissBranch() { |
1309 MaybeObject* maybe_obj = | 1525 Handle<Code> code = |
1310 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), | 1526 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), |
1311 kind_, | 1527 kind_, |
1312 extra_ic_state_); | 1528 extra_state_); |
| 1529 __ Jump(code, RelocInfo::CODE_TARGET); |
| 1530 } |
| 1531 |
| 1532 |
| 1533 // TODO(kmillikin): Eliminate this function when the stub cache is fully |
| 1534 // handlified. |
| 1535 MaybeObject* CallStubCompiler::TryGenerateMissBranch() { |
| 1536 MaybeObject* maybe_obj = |
| 1537 isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(), |
| 1538 kind_, |
| 1539 extra_state_); |
1313 Object* obj; | 1540 Object* obj; |
1314 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1541 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
1315 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); | 1542 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); |
1316 return obj; | 1543 return obj; |
1317 } | 1544 } |
1318 | 1545 |
1319 | 1546 |
1320 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object, | 1547 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, |
1321 JSObject* holder, | 1548 Handle<JSObject> holder, |
1322 int index, | 1549 int index, |
1323 String* name) { | 1550 Handle<String> name) { |
1324 // ----------- S t a t e ------------- | 1551 // ----------- S t a t e ------------- |
1325 // rcx : function name | 1552 // rcx : function name |
1326 // rsp[0] : return address | 1553 // rsp[0] : return address |
1327 // rsp[8] : argument argc | 1554 // rsp[8] : argument argc |
1328 // rsp[16] : argument argc - 1 | 1555 // rsp[16] : argument argc - 1 |
1329 // ... | 1556 // ... |
1330 // rsp[argc * 8] : argument 1 | 1557 // rsp[argc * 8] : argument 1 |
1331 // rsp[(argc + 1) * 8] : argument 0 = receiver | 1558 // rsp[(argc + 1) * 8] : argument 0 = receiver |
1332 // ----------------------------------- | 1559 // ----------------------------------- |
1333 Label miss; | 1560 Label miss; |
(...skipping 19 matching lines...) Expand all Loading... |
1353 __ j(not_equal, &miss); | 1580 __ j(not_equal, &miss); |
1354 | 1581 |
1355 // Patch the receiver on the stack with the global proxy if | 1582 // Patch the receiver on the stack with the global proxy if |
1356 // necessary. | 1583 // necessary. |
1357 if (object->IsGlobalObject()) { | 1584 if (object->IsGlobalObject()) { |
1358 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | 1585 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); |
1359 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); | 1586 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); |
1360 } | 1587 } |
1361 | 1588 |
1362 // Invoke the function. | 1589 // Invoke the function. |
1363 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 1590 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
1364 ? CALL_AS_FUNCTION | 1591 ? CALL_AS_FUNCTION |
1365 : CALL_AS_METHOD; | 1592 : CALL_AS_METHOD; |
1366 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, | 1593 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, |
1367 NullCallWrapper(), call_kind); | 1594 NullCallWrapper(), call_kind); |
1368 | 1595 |
1369 // Handle call cache miss. | 1596 // Handle call cache miss. |
1370 __ bind(&miss); | 1597 __ bind(&miss); |
1371 MaybeObject* maybe_result = GenerateMissBranch(); | 1598 GenerateMissBranch(); |
1372 if (maybe_result->IsFailure()) return maybe_result; | |
1373 | 1599 |
1374 // Return the generated code. | 1600 // Return the generated code. |
1375 return GetCode(FIELD, name); | 1601 return GetCode(FIELD, name); |
1376 } | 1602 } |
1377 | 1603 |
1378 | 1604 |
1379 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, | 1605 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, |
1380 JSObject* holder, | 1606 JSObject* holder, |
1381 JSGlobalPropertyCell* cell, | 1607 JSGlobalPropertyCell* cell, |
1382 JSFunction* function, | 1608 JSFunction* function, |
1383 String* name) { | 1609 String* name) { |
1384 // ----------- S t a t e ------------- | 1610 // ----------- S t a t e ------------- |
1385 // -- rcx : name | 1611 // -- rcx : name |
1386 // -- rsp[0] : return address | 1612 // -- rsp[0] : return address |
1387 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1613 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1388 // -- ... | 1614 // -- ... |
1389 // -- rsp[(argc + 1) * 8] : receiver | 1615 // -- rsp[(argc + 1) * 8] : receiver |
1390 // ----------------------------------- | 1616 // ----------------------------------- |
1391 | 1617 |
1392 // If object is not an array, bail out to regular call. | 1618 // If object is not an array, bail out to regular call. |
1393 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); | 1619 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); |
1394 | 1620 |
1395 Label miss; | 1621 Label miss; |
1396 | 1622 |
1397 GenerateNameCheck(name, &miss); | 1623 GenerateNameCheck(Handle<String>(name), &miss); |
1398 | 1624 |
1399 // Get the receiver from the stack. | 1625 // Get the receiver from the stack. |
1400 const int argc = arguments().immediate(); | 1626 const int argc = arguments().immediate(); |
1401 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 1627 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
1402 | 1628 |
1403 // Check that the receiver isn't a smi. | 1629 // Check that the receiver isn't a smi. |
1404 __ JumpIfSmi(rdx, &miss); | 1630 __ JumpIfSmi(rdx, &miss); |
1405 | 1631 |
1406 CheckPrototypes(JSObject::cast(object), | 1632 CheckPrototypes(JSObject::cast(object), |
1407 rdx, | 1633 rdx, |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1481 __ bind(&attempt_to_grow_elements); | 1707 __ bind(&attempt_to_grow_elements); |
1482 if (!FLAG_inline_new) { | 1708 if (!FLAG_inline_new) { |
1483 __ jmp(&call_builtin); | 1709 __ jmp(&call_builtin); |
1484 } | 1710 } |
1485 | 1711 |
1486 __ movq(rdi, Operand(rsp, argc * kPointerSize)); | 1712 __ movq(rdi, Operand(rsp, argc * kPointerSize)); |
1487 // Growing elements that are SMI-only requires special handling in case | 1713 // Growing elements that are SMI-only requires special handling in case |
1488 // the new element is non-Smi. For now, delegate to the builtin. | 1714 // the new element is non-Smi. For now, delegate to the builtin. |
1489 Label no_fast_elements_check; | 1715 Label no_fast_elements_check; |
1490 __ JumpIfSmi(rdi, &no_fast_elements_check); | 1716 __ JumpIfSmi(rdi, &no_fast_elements_check); |
1491 __ movq(rsi, FieldOperand(rdx, HeapObject::kMapOffset)); | 1717 __ movq(rcx, FieldOperand(rdx, HeapObject::kMapOffset)); |
1492 __ CheckFastObjectElements(rsi, &call_builtin, Label::kFar); | 1718 __ CheckFastObjectElements(rcx, &call_builtin, Label::kFar); |
1493 __ bind(&no_fast_elements_check); | 1719 __ bind(&no_fast_elements_check); |
1494 | 1720 |
1495 ExternalReference new_space_allocation_top = | 1721 ExternalReference new_space_allocation_top = |
1496 ExternalReference::new_space_allocation_top_address(isolate()); | 1722 ExternalReference::new_space_allocation_top_address(isolate()); |
1497 ExternalReference new_space_allocation_limit = | 1723 ExternalReference new_space_allocation_limit = |
1498 ExternalReference::new_space_allocation_limit_address(isolate()); | 1724 ExternalReference::new_space_allocation_limit_address(isolate()); |
1499 | 1725 |
1500 const int kAllocationDelta = 4; | 1726 const int kAllocationDelta = 4; |
1501 // Load top. | 1727 // Load top. |
1502 __ Load(rcx, new_space_allocation_top); | 1728 __ Load(rcx, new_space_allocation_top); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1546 } | 1772 } |
1547 | 1773 |
1548 __ bind(&call_builtin); | 1774 __ bind(&call_builtin); |
1549 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, | 1775 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, |
1550 isolate()), | 1776 isolate()), |
1551 argc + 1, | 1777 argc + 1, |
1552 1); | 1778 1); |
1553 } | 1779 } |
1554 | 1780 |
1555 __ bind(&miss); | 1781 __ bind(&miss); |
1556 MaybeObject* maybe_result = GenerateMissBranch(); | 1782 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1557 if (maybe_result->IsFailure()) return maybe_result; | 1783 if (maybe_result->IsFailure()) return maybe_result; |
1558 | 1784 |
1559 // Return the generated code. | 1785 // Return the generated code. |
1560 return GetCode(function); | 1786 return TryGetCode(function); |
1561 } | 1787 } |
1562 | 1788 |
1563 | 1789 |
1564 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, | 1790 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, |
1565 JSObject* holder, | 1791 JSObject* holder, |
1566 JSGlobalPropertyCell* cell, | 1792 JSGlobalPropertyCell* cell, |
1567 JSFunction* function, | 1793 JSFunction* function, |
1568 String* name) { | 1794 String* name) { |
1569 // ----------- S t a t e ------------- | 1795 // ----------- S t a t e ------------- |
1570 // -- rcx : name | 1796 // -- rcx : name |
1571 // -- rsp[0] : return address | 1797 // -- rsp[0] : return address |
1572 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1798 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1573 // -- ... | 1799 // -- ... |
1574 // -- rsp[(argc + 1) * 8] : receiver | 1800 // -- rsp[(argc + 1) * 8] : receiver |
1575 // ----------------------------------- | 1801 // ----------------------------------- |
1576 | 1802 |
1577 // If object is not an array, bail out to regular call. | 1803 // If object is not an array, bail out to regular call. |
1578 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); | 1804 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); |
1579 | 1805 |
1580 Label miss, return_undefined, call_builtin; | 1806 Label miss, return_undefined, call_builtin; |
1581 | 1807 |
1582 GenerateNameCheck(name, &miss); | 1808 GenerateNameCheck(Handle<String>(name), &miss); |
1583 | 1809 |
1584 // Get the receiver from the stack. | 1810 // Get the receiver from the stack. |
1585 const int argc = arguments().immediate(); | 1811 const int argc = arguments().immediate(); |
1586 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 1812 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
1587 | 1813 |
1588 // Check that the receiver isn't a smi. | 1814 // Check that the receiver isn't a smi. |
1589 __ JumpIfSmi(rdx, &miss); | 1815 __ JumpIfSmi(rdx, &miss); |
1590 | 1816 |
1591 CheckPrototypes(JSObject::cast(object), rdx, | 1817 CheckPrototypes(JSObject::cast(object), rdx, |
1592 holder, rbx, | 1818 holder, rbx, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1629 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); | 1855 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); |
1630 __ ret((argc + 1) * kPointerSize); | 1856 __ ret((argc + 1) * kPointerSize); |
1631 | 1857 |
1632 __ bind(&call_builtin); | 1858 __ bind(&call_builtin); |
1633 __ TailCallExternalReference( | 1859 __ TailCallExternalReference( |
1634 ExternalReference(Builtins::c_ArrayPop, isolate()), | 1860 ExternalReference(Builtins::c_ArrayPop, isolate()), |
1635 argc + 1, | 1861 argc + 1, |
1636 1); | 1862 1); |
1637 | 1863 |
1638 __ bind(&miss); | 1864 __ bind(&miss); |
1639 MaybeObject* maybe_result = GenerateMissBranch(); | 1865 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1640 if (maybe_result->IsFailure()) return maybe_result; | 1866 if (maybe_result->IsFailure()) return maybe_result; |
1641 | 1867 |
1642 // Return the generated code. | 1868 // Return the generated code. |
1643 return GetCode(function); | 1869 return TryGetCode(function); |
1644 } | 1870 } |
1645 | 1871 |
1646 | 1872 |
1647 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( | 1873 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( |
1648 Object* object, | 1874 Object* object, |
1649 JSObject* holder, | 1875 JSObject* holder, |
1650 JSGlobalPropertyCell* cell, | 1876 JSGlobalPropertyCell* cell, |
1651 JSFunction* function, | 1877 JSFunction* function, |
1652 String* name) { | 1878 String* name) { |
1653 // ----------- S t a t e ------------- | 1879 // ----------- S t a t e ------------- |
1654 // -- rcx : function name | 1880 // -- rcx : function name |
1655 // -- rsp[0] : return address | 1881 // -- rsp[0] : return address |
1656 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1882 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1657 // -- ... | 1883 // -- ... |
1658 // -- rsp[(argc + 1) * 8] : receiver | 1884 // -- rsp[(argc + 1) * 8] : receiver |
1659 // ----------------------------------- | 1885 // ----------------------------------- |
1660 | 1886 |
1661 // If object is not a string, bail out to regular call. | 1887 // If object is not a string, bail out to regular call. |
1662 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); | 1888 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); |
1663 | 1889 |
1664 const int argc = arguments().immediate(); | 1890 const int argc = arguments().immediate(); |
1665 | 1891 |
1666 Label miss; | 1892 Label miss; |
1667 Label name_miss; | 1893 Label name_miss; |
1668 Label index_out_of_range; | 1894 Label index_out_of_range; |
1669 Label* index_out_of_range_label = &index_out_of_range; | 1895 Label* index_out_of_range_label = &index_out_of_range; |
1670 | 1896 |
1671 if (kind_ == Code::CALL_IC && | 1897 if (kind_ == Code::CALL_IC && |
1672 (CallICBase::StringStubState::decode(extra_ic_state_) == | 1898 (CallICBase::StringStubState::decode(extra_state_) == |
1673 DEFAULT_STRING_STUB)) { | 1899 DEFAULT_STRING_STUB)) { |
1674 index_out_of_range_label = &miss; | 1900 index_out_of_range_label = &miss; |
1675 } | 1901 } |
1676 | 1902 |
1677 GenerateNameCheck(name, &name_miss); | 1903 GenerateNameCheck(Handle<String>(name), &name_miss); |
1678 | 1904 |
1679 // Check that the maps starting from the prototype haven't changed. | 1905 // Check that the maps starting from the prototype haven't changed. |
1680 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 1906 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
1681 Context::STRING_FUNCTION_INDEX, | 1907 Context::STRING_FUNCTION_INDEX, |
1682 rax, | 1908 rax, |
1683 &miss); | 1909 &miss); |
1684 ASSERT(object != holder); | 1910 ASSERT(object != holder); |
1685 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, | 1911 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, |
1686 rbx, rdx, rdi, name, &miss); | 1912 rbx, rdx, rdi, name, &miss); |
1687 | 1913 |
(...skipping 25 matching lines...) Expand all Loading... |
1713 if (index_out_of_range.is_linked()) { | 1939 if (index_out_of_range.is_linked()) { |
1714 __ bind(&index_out_of_range); | 1940 __ bind(&index_out_of_range); |
1715 __ LoadRoot(rax, Heap::kNanValueRootIndex); | 1941 __ LoadRoot(rax, Heap::kNanValueRootIndex); |
1716 __ ret((argc + 1) * kPointerSize); | 1942 __ ret((argc + 1) * kPointerSize); |
1717 } | 1943 } |
1718 | 1944 |
1719 __ bind(&miss); | 1945 __ bind(&miss); |
1720 // Restore function name in rcx. | 1946 // Restore function name in rcx. |
1721 __ Move(rcx, Handle<String>(name)); | 1947 __ Move(rcx, Handle<String>(name)); |
1722 __ bind(&name_miss); | 1948 __ bind(&name_miss); |
1723 MaybeObject* maybe_result = GenerateMissBranch(); | 1949 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1724 if (maybe_result->IsFailure()) return maybe_result; | 1950 if (maybe_result->IsFailure()) return maybe_result; |
1725 | 1951 |
1726 // Return the generated code. | 1952 // Return the generated code. |
1727 return GetCode(function); | 1953 return TryGetCode(function); |
1728 } | 1954 } |
1729 | 1955 |
1730 | 1956 |
1731 MaybeObject* CallStubCompiler::CompileStringCharAtCall( | 1957 MaybeObject* CallStubCompiler::CompileStringCharAtCall( |
1732 Object* object, | 1958 Object* object, |
1733 JSObject* holder, | 1959 JSObject* holder, |
1734 JSGlobalPropertyCell* cell, | 1960 JSGlobalPropertyCell* cell, |
1735 JSFunction* function, | 1961 JSFunction* function, |
1736 String* name) { | 1962 String* name) { |
1737 // ----------- S t a t e ------------- | 1963 // ----------- S t a t e ------------- |
1738 // -- rcx : function name | 1964 // -- rcx : function name |
1739 // -- rsp[0] : return address | 1965 // -- rsp[0] : return address |
1740 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1966 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1741 // -- ... | 1967 // -- ... |
1742 // -- rsp[(argc + 1) * 8] : receiver | 1968 // -- rsp[(argc + 1) * 8] : receiver |
1743 // ----------------------------------- | 1969 // ----------------------------------- |
1744 | 1970 |
1745 // If object is not a string, bail out to regular call. | 1971 // If object is not a string, bail out to regular call. |
1746 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); | 1972 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); |
1747 | 1973 |
1748 const int argc = arguments().immediate(); | 1974 const int argc = arguments().immediate(); |
1749 | 1975 |
1750 Label miss; | 1976 Label miss; |
1751 Label name_miss; | 1977 Label name_miss; |
1752 Label index_out_of_range; | 1978 Label index_out_of_range; |
1753 Label* index_out_of_range_label = &index_out_of_range; | 1979 Label* index_out_of_range_label = &index_out_of_range; |
1754 | 1980 |
1755 if (kind_ == Code::CALL_IC && | 1981 if (kind_ == Code::CALL_IC && |
1756 (CallICBase::StringStubState::decode(extra_ic_state_) == | 1982 (CallICBase::StringStubState::decode(extra_state_) == |
1757 DEFAULT_STRING_STUB)) { | 1983 DEFAULT_STRING_STUB)) { |
1758 index_out_of_range_label = &miss; | 1984 index_out_of_range_label = &miss; |
1759 } | 1985 } |
1760 | 1986 |
1761 GenerateNameCheck(name, &name_miss); | 1987 GenerateNameCheck(Handle<String>(name), &name_miss); |
1762 | 1988 |
1763 // Check that the maps starting from the prototype haven't changed. | 1989 // Check that the maps starting from the prototype haven't changed. |
1764 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 1990 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
1765 Context::STRING_FUNCTION_INDEX, | 1991 Context::STRING_FUNCTION_INDEX, |
1766 rax, | 1992 rax, |
1767 &miss); | 1993 &miss); |
1768 ASSERT(object != holder); | 1994 ASSERT(object != holder); |
1769 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, | 1995 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, |
1770 rbx, rdx, rdi, name, &miss); | 1996 rbx, rdx, rdi, name, &miss); |
1771 | 1997 |
(...skipping 27 matching lines...) Expand all Loading... |
1799 if (index_out_of_range.is_linked()) { | 2025 if (index_out_of_range.is_linked()) { |
1800 __ bind(&index_out_of_range); | 2026 __ bind(&index_out_of_range); |
1801 __ LoadRoot(rax, Heap::kEmptyStringRootIndex); | 2027 __ LoadRoot(rax, Heap::kEmptyStringRootIndex); |
1802 __ ret((argc + 1) * kPointerSize); | 2028 __ ret((argc + 1) * kPointerSize); |
1803 } | 2029 } |
1804 | 2030 |
1805 __ bind(&miss); | 2031 __ bind(&miss); |
1806 // Restore function name in rcx. | 2032 // Restore function name in rcx. |
1807 __ Move(rcx, Handle<String>(name)); | 2033 __ Move(rcx, Handle<String>(name)); |
1808 __ bind(&name_miss); | 2034 __ bind(&name_miss); |
1809 MaybeObject* maybe_result = GenerateMissBranch(); | 2035 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1810 if (maybe_result->IsFailure()) return maybe_result; | 2036 if (maybe_result->IsFailure()) return maybe_result; |
1811 | 2037 |
1812 // Return the generated code. | 2038 // Return the generated code. |
1813 return GetCode(function); | 2039 return TryGetCode(function); |
1814 } | 2040 } |
1815 | 2041 |
1816 | 2042 |
1817 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( | 2043 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( |
1818 Object* object, | 2044 Object* object, |
1819 JSObject* holder, | 2045 JSObject* holder, |
1820 JSGlobalPropertyCell* cell, | 2046 JSGlobalPropertyCell* cell, |
1821 JSFunction* function, | 2047 JSFunction* function, |
1822 String* name) { | 2048 String* name) { |
1823 // ----------- S t a t e ------------- | 2049 // ----------- S t a t e ------------- |
1824 // -- rcx : function name | 2050 // -- rcx : function name |
1825 // -- rsp[0] : return address | 2051 // -- rsp[0] : return address |
1826 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 2052 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1827 // -- ... | 2053 // -- ... |
1828 // -- rsp[(argc + 1) * 8] : receiver | 2054 // -- rsp[(argc + 1) * 8] : receiver |
1829 // ----------------------------------- | 2055 // ----------------------------------- |
1830 | 2056 |
1831 const int argc = arguments().immediate(); | 2057 const int argc = arguments().immediate(); |
1832 | 2058 |
1833 // If the object is not a JSObject or we got an unexpected number of | 2059 // If the object is not a JSObject or we got an unexpected number of |
1834 // arguments, bail out to the regular call. | 2060 // arguments, bail out to the regular call. |
1835 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 2061 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); |
1836 | 2062 |
1837 Label miss; | 2063 Label miss; |
1838 GenerateNameCheck(name, &miss); | 2064 GenerateNameCheck(Handle<String>(name), &miss); |
1839 | 2065 |
1840 if (cell == NULL) { | 2066 if (cell == NULL) { |
1841 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); | 2067 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); |
1842 | 2068 |
1843 __ JumpIfSmi(rdx, &miss); | 2069 __ JumpIfSmi(rdx, &miss); |
1844 | 2070 |
1845 CheckPrototypes(JSObject::cast(object), rdx, holder, rbx, rax, rdi, name, | 2071 CheckPrototypes(JSObject::cast(object), rdx, holder, rbx, rax, rdi, name, |
1846 &miss); | 2072 &miss); |
1847 } else { | 2073 } else { |
1848 ASSERT(cell->value() == function); | 2074 ASSERT(cell->value() == function); |
(...skipping 15 matching lines...) Expand all Loading... |
1864 StringCharFromCodeGenerator char_from_code_generator(code, rax); | 2090 StringCharFromCodeGenerator char_from_code_generator(code, rax); |
1865 char_from_code_generator.GenerateFast(masm()); | 2091 char_from_code_generator.GenerateFast(masm()); |
1866 __ ret(2 * kPointerSize); | 2092 __ ret(2 * kPointerSize); |
1867 | 2093 |
1868 StubRuntimeCallHelper call_helper; | 2094 StubRuntimeCallHelper call_helper; |
1869 char_from_code_generator.GenerateSlow(masm(), call_helper); | 2095 char_from_code_generator.GenerateSlow(masm(), call_helper); |
1870 | 2096 |
1871 // Tail call the full function. We do not have to patch the receiver | 2097 // Tail call the full function. We do not have to patch the receiver |
1872 // because the function makes no use of it. | 2098 // because the function makes no use of it. |
1873 __ bind(&slow); | 2099 __ bind(&slow); |
1874 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 2100 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
1875 ? CALL_AS_FUNCTION | 2101 ? CALL_AS_FUNCTION |
1876 : CALL_AS_METHOD; | 2102 : CALL_AS_METHOD; |
1877 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, | 2103 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, |
1878 NullCallWrapper(), call_kind); | 2104 NullCallWrapper(), call_kind); |
1879 | 2105 |
1880 __ bind(&miss); | 2106 __ bind(&miss); |
1881 // rcx: function name. | 2107 // rcx: function name. |
1882 MaybeObject* maybe_result = GenerateMissBranch(); | 2108 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1883 if (maybe_result->IsFailure()) return maybe_result; | 2109 if (maybe_result->IsFailure()) return maybe_result; |
1884 | 2110 |
1885 // Return the generated code. | 2111 // Return the generated code. |
1886 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2112 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); |
1887 } | 2113 } |
1888 | 2114 |
1889 | 2115 |
1890 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, | 2116 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, |
1891 JSObject* holder, | 2117 JSObject* holder, |
1892 JSGlobalPropertyCell* cell, | 2118 JSGlobalPropertyCell* cell, |
1893 JSFunction* function, | 2119 JSFunction* function, |
1894 String* name) { | 2120 String* name) { |
1895 // TODO(872): implement this. | 2121 // TODO(872): implement this. |
1896 return heap()->undefined_value(); | 2122 return heap()->undefined_value(); |
(...skipping 13 matching lines...) Expand all Loading... |
1910 // -- rsp[(argc + 1) * 8] : receiver | 2136 // -- rsp[(argc + 1) * 8] : receiver |
1911 // ----------------------------------- | 2137 // ----------------------------------- |
1912 | 2138 |
1913 const int argc = arguments().immediate(); | 2139 const int argc = arguments().immediate(); |
1914 | 2140 |
1915 // If the object is not a JSObject or we got an unexpected number of | 2141 // If the object is not a JSObject or we got an unexpected number of |
1916 // arguments, bail out to the regular call. | 2142 // arguments, bail out to the regular call. |
1917 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 2143 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); |
1918 | 2144 |
1919 Label miss; | 2145 Label miss; |
1920 GenerateNameCheck(name, &miss); | 2146 GenerateNameCheck(Handle<String>(name), &miss); |
1921 | 2147 |
1922 if (cell == NULL) { | 2148 if (cell == NULL) { |
1923 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); | 2149 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); |
1924 | 2150 |
1925 __ JumpIfSmi(rdx, &miss); | 2151 __ JumpIfSmi(rdx, &miss); |
1926 | 2152 |
1927 CheckPrototypes(JSObject::cast(object), rdx, holder, rbx, rax, rdi, name, | 2153 CheckPrototypes(JSObject::cast(object), rdx, holder, rbx, rax, rdi, name, |
1928 &miss); | 2154 &miss); |
1929 } else { | 2155 } else { |
1930 ASSERT(cell->value() == function); | 2156 ASSERT(cell->value() == function); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1981 // number. We still have the sign mask in rdi. | 2207 // number. We still have the sign mask in rdi. |
1982 __ bind(&negative_sign); | 2208 __ bind(&negative_sign); |
1983 __ xor_(rbx, rdi); | 2209 __ xor_(rbx, rdi); |
1984 __ AllocateHeapNumber(rax, rdx, &slow); | 2210 __ AllocateHeapNumber(rax, rdx, &slow); |
1985 __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rbx); | 2211 __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rbx); |
1986 __ ret(2 * kPointerSize); | 2212 __ ret(2 * kPointerSize); |
1987 | 2213 |
1988 // Tail call the full function. We do not have to patch the receiver | 2214 // Tail call the full function. We do not have to patch the receiver |
1989 // because the function makes no use of it. | 2215 // because the function makes no use of it. |
1990 __ bind(&slow); | 2216 __ bind(&slow); |
1991 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 2217 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
1992 ? CALL_AS_FUNCTION | 2218 ? CALL_AS_FUNCTION |
1993 : CALL_AS_METHOD; | 2219 : CALL_AS_METHOD; |
1994 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, | 2220 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, |
1995 NullCallWrapper(), call_kind); | 2221 NullCallWrapper(), call_kind); |
1996 | 2222 |
1997 __ bind(&miss); | 2223 __ bind(&miss); |
1998 // rcx: function name. | 2224 // rcx: function name. |
1999 MaybeObject* maybe_result = GenerateMissBranch(); | 2225 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2000 if (maybe_result->IsFailure()) return maybe_result; | 2226 if (maybe_result->IsFailure()) return maybe_result; |
2001 | 2227 |
2002 // Return the generated code. | 2228 // Return the generated code. |
2003 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2229 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); |
2004 } | 2230 } |
2005 | 2231 |
2006 | 2232 |
2007 MaybeObject* CallStubCompiler::CompileFastApiCall( | 2233 MaybeObject* CallStubCompiler::CompileFastApiCall( |
2008 const CallOptimization& optimization, | 2234 const CallOptimization& optimization, |
2009 Object* object, | 2235 Object* object, |
2010 JSObject* holder, | 2236 JSObject* holder, |
2011 JSGlobalPropertyCell* cell, | 2237 JSGlobalPropertyCell* cell, |
2012 JSFunction* function, | 2238 JSFunction* function, |
2013 String* name) { | 2239 String* name) { |
2014 ASSERT(optimization.is_simple_api_call()); | 2240 ASSERT(optimization.is_simple_api_call()); |
2015 // Bail out if object is a global object as we don't want to | 2241 // Bail out if object is a global object as we don't want to |
2016 // repatch it to global receiver. | 2242 // repatch it to global receiver. |
2017 if (object->IsGlobalObject()) return heap()->undefined_value(); | 2243 if (object->IsGlobalObject()) return heap()->undefined_value(); |
2018 if (cell != NULL) return heap()->undefined_value(); | 2244 if (cell != NULL) return heap()->undefined_value(); |
2019 if (!object->IsJSObject()) return heap()->undefined_value(); | 2245 if (!object->IsJSObject()) return heap()->undefined_value(); |
2020 int depth = optimization.GetPrototypeDepthOfExpectedType( | 2246 int depth = optimization.GetPrototypeDepthOfExpectedType( |
2021 JSObject::cast(object), holder); | 2247 JSObject::cast(object), holder); |
2022 if (depth == kInvalidProtoDepth) return heap()->undefined_value(); | 2248 if (depth == kInvalidProtoDepth) return heap()->undefined_value(); |
2023 | 2249 |
2024 Label miss, miss_before_stack_reserved; | 2250 Label miss, miss_before_stack_reserved; |
2025 | 2251 |
2026 GenerateNameCheck(name, &miss_before_stack_reserved); | 2252 GenerateNameCheck(Handle<String>(name), &miss_before_stack_reserved); |
2027 | 2253 |
2028 // Get the receiver from the stack. | 2254 // Get the receiver from the stack. |
2029 const int argc = arguments().immediate(); | 2255 const int argc = arguments().immediate(); |
2030 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 2256 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
2031 | 2257 |
2032 // Check that the receiver isn't a smi. | 2258 // Check that the receiver isn't a smi. |
2033 __ JumpIfSmi(rdx, &miss_before_stack_reserved); | 2259 __ JumpIfSmi(rdx, &miss_before_stack_reserved); |
2034 | 2260 |
2035 Counters* counters = isolate()->counters(); | 2261 Counters* counters = isolate()->counters(); |
2036 __ IncrementCounter(counters->call_const(), 1); | 2262 __ IncrementCounter(counters->call_const(), 1); |
(...skipping 11 matching lines...) Expand all Loading... |
2048 __ movq(rax, Operand(rsp, 3 * kPointerSize)); | 2274 __ movq(rax, Operand(rsp, 3 * kPointerSize)); |
2049 __ movq(Operand(rsp, 0 * kPointerSize), rax); | 2275 __ movq(Operand(rsp, 0 * kPointerSize), rax); |
2050 | 2276 |
2051 MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc); | 2277 MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc); |
2052 if (result->IsFailure()) return result; | 2278 if (result->IsFailure()) return result; |
2053 | 2279 |
2054 __ bind(&miss); | 2280 __ bind(&miss); |
2055 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); | 2281 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); |
2056 | 2282 |
2057 __ bind(&miss_before_stack_reserved); | 2283 __ bind(&miss_before_stack_reserved); |
2058 MaybeObject* maybe_result = GenerateMissBranch(); | 2284 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2059 if (maybe_result->IsFailure()) return maybe_result; | 2285 if (maybe_result->IsFailure()) return maybe_result; |
2060 | 2286 |
2061 // Return the generated code. | 2287 // Return the generated code. |
2062 return GetCode(function); | 2288 return TryGetCode(function); |
2063 } | 2289 } |
2064 | 2290 |
2065 | 2291 |
2066 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, | 2292 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, |
2067 JSObject* holder, | 2293 JSObject* holder, |
2068 JSFunction* function, | 2294 JSFunction* function, |
2069 String* name, | 2295 String* name, |
2070 CheckType check) { | 2296 CheckType check) { |
2071 // ----------- S t a t e ------------- | 2297 // ----------- S t a t e ------------- |
2072 // rcx : function name | 2298 // rcx : function name |
2073 // rsp[0] : return address | 2299 // rsp[0] : return address |
2074 // rsp[8] : argument argc | 2300 // rsp[8] : argument argc |
2075 // rsp[16] : argument argc - 1 | 2301 // rsp[16] : argument argc - 1 |
2076 // ... | 2302 // ... |
2077 // rsp[argc * 8] : argument 1 | 2303 // rsp[argc * 8] : argument 1 |
2078 // rsp[(argc + 1) * 8] : argument 0 = receiver | 2304 // rsp[(argc + 1) * 8] : argument 0 = receiver |
2079 // ----------------------------------- | 2305 // ----------------------------------- |
2080 | 2306 |
2081 if (HasCustomCallGenerator(function)) { | 2307 if (HasCustomCallGenerator(function)) { |
2082 MaybeObject* maybe_result = CompileCustomCall( | 2308 MaybeObject* maybe_result = CompileCustomCall( |
2083 object, holder, NULL, function, name); | 2309 object, holder, NULL, function, name); |
2084 Object* result; | 2310 Object* result; |
2085 if (!maybe_result->ToObject(&result)) return maybe_result; | 2311 if (!maybe_result->ToObject(&result)) return maybe_result; |
2086 // undefined means bail out to regular compiler. | 2312 // undefined means bail out to regular compiler. |
2087 if (!result->IsUndefined()) return result; | 2313 if (!result->IsUndefined()) return result; |
2088 } | 2314 } |
2089 | 2315 |
2090 Label miss; | 2316 Label miss; |
2091 | 2317 |
2092 GenerateNameCheck(name, &miss); | 2318 GenerateNameCheck(Handle<String>(name), &miss); |
2093 | 2319 |
2094 // Get the receiver from the stack. | 2320 // Get the receiver from the stack. |
2095 const int argc = arguments().immediate(); | 2321 const int argc = arguments().immediate(); |
2096 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 2322 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
2097 | 2323 |
2098 // Check that the receiver isn't a smi. | 2324 // Check that the receiver isn't a smi. |
2099 if (check != NUMBER_CHECK) { | 2325 if (check != NUMBER_CHECK) { |
2100 __ JumpIfSmi(rdx, &miss); | 2326 __ JumpIfSmi(rdx, &miss); |
2101 } | 2327 } |
2102 | 2328 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2179 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, | 2405 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, |
2180 rbx, rdx, rdi, name, &miss); | 2406 rbx, rdx, rdi, name, &miss); |
2181 } | 2407 } |
2182 break; | 2408 break; |
2183 } | 2409 } |
2184 | 2410 |
2185 default: | 2411 default: |
2186 UNREACHABLE(); | 2412 UNREACHABLE(); |
2187 } | 2413 } |
2188 | 2414 |
2189 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 2415 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
2190 ? CALL_AS_FUNCTION | 2416 ? CALL_AS_FUNCTION |
2191 : CALL_AS_METHOD; | 2417 : CALL_AS_METHOD; |
2192 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, | 2418 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, |
2193 NullCallWrapper(), call_kind); | 2419 NullCallWrapper(), call_kind); |
2194 | 2420 |
2195 // Handle call cache miss. | 2421 // Handle call cache miss. |
2196 __ bind(&miss); | 2422 __ bind(&miss); |
2197 MaybeObject* maybe_result = GenerateMissBranch(); | 2423 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2198 if (maybe_result->IsFailure()) return maybe_result; | 2424 if (maybe_result->IsFailure()) return maybe_result; |
2199 | 2425 |
2200 // Return the generated code. | 2426 // Return the generated code. |
2201 return GetCode(function); | 2427 return TryGetCode(function); |
2202 } | 2428 } |
2203 | 2429 |
2204 | 2430 |
2205 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, | 2431 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, |
2206 JSObject* holder, | 2432 JSObject* holder, |
2207 String* name) { | 2433 String* name) { |
2208 // ----------- S t a t e ------------- | 2434 // ----------- S t a t e ------------- |
2209 // rcx : function name | 2435 // rcx : function name |
2210 // rsp[0] : return address | 2436 // rsp[0] : return address |
2211 // rsp[8] : argument argc | 2437 // rsp[8] : argument argc |
2212 // rsp[16] : argument argc - 1 | 2438 // rsp[16] : argument argc - 1 |
2213 // ... | 2439 // ... |
2214 // rsp[argc * 8] : argument 1 | 2440 // rsp[argc * 8] : argument 1 |
2215 // rsp[(argc + 1) * 8] : argument 0 = receiver | 2441 // rsp[(argc + 1) * 8] : argument 0 = receiver |
2216 // ----------------------------------- | 2442 // ----------------------------------- |
2217 Label miss; | 2443 Label miss; |
2218 | 2444 |
2219 GenerateNameCheck(name, &miss); | 2445 GenerateNameCheck(Handle<String>(name), &miss); |
2220 | 2446 |
2221 // Get the number of arguments. | 2447 // Get the number of arguments. |
2222 const int argc = arguments().immediate(); | 2448 const int argc = arguments().immediate(); |
2223 | 2449 |
2224 LookupResult lookup; | 2450 LookupResult lookup(isolate()); |
2225 LookupPostInterceptor(holder, name, &lookup); | 2451 LookupPostInterceptor(holder, name, &lookup); |
2226 | 2452 |
2227 // Get the receiver from the stack. | 2453 // Get the receiver from the stack. |
2228 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 2454 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
2229 | 2455 |
2230 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_ic_state_); | 2456 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_); |
2231 MaybeObject* result = compiler.Compile(masm(), | 2457 MaybeObject* result = compiler.Compile(masm(), |
2232 object, | 2458 object, |
2233 holder, | 2459 holder, |
2234 name, | 2460 name, |
2235 &lookup, | 2461 &lookup, |
2236 rdx, | 2462 rdx, |
2237 rbx, | 2463 rbx, |
2238 rdi, | 2464 rdi, |
2239 rax, | 2465 rax, |
2240 &miss); | 2466 &miss); |
2241 if (result->IsFailure()) return result; | 2467 if (result->IsFailure()) return result; |
2242 | 2468 |
2243 // Restore receiver. | 2469 // Restore receiver. |
2244 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 2470 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
2245 | 2471 |
2246 // Check that the function really is a function. | 2472 // Check that the function really is a function. |
2247 __ JumpIfSmi(rax, &miss); | 2473 __ JumpIfSmi(rax, &miss); |
2248 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); | 2474 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); |
2249 __ j(not_equal, &miss); | 2475 __ j(not_equal, &miss); |
2250 | 2476 |
2251 // Patch the receiver on the stack with the global proxy if | 2477 // Patch the receiver on the stack with the global proxy if |
2252 // necessary. | 2478 // necessary. |
2253 if (object->IsGlobalObject()) { | 2479 if (object->IsGlobalObject()) { |
2254 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | 2480 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); |
2255 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); | 2481 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); |
2256 } | 2482 } |
2257 | 2483 |
2258 // Invoke the function. | 2484 // Invoke the function. |
2259 __ movq(rdi, rax); | 2485 __ movq(rdi, rax); |
2260 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 2486 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
2261 ? CALL_AS_FUNCTION | 2487 ? CALL_AS_FUNCTION |
2262 : CALL_AS_METHOD; | 2488 : CALL_AS_METHOD; |
2263 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, | 2489 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, |
2264 NullCallWrapper(), call_kind); | 2490 NullCallWrapper(), call_kind); |
2265 | 2491 |
2266 // Handle load cache miss. | 2492 // Handle load cache miss. |
2267 __ bind(&miss); | 2493 __ bind(&miss); |
2268 MaybeObject* maybe_result = GenerateMissBranch(); | 2494 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2269 if (maybe_result->IsFailure()) return maybe_result; | 2495 if (maybe_result->IsFailure()) return maybe_result; |
2270 | 2496 |
2271 // Return the generated code. | 2497 // Return the generated code. |
2272 return GetCode(INTERCEPTOR, name); | 2498 return TryGetCode(INTERCEPTOR, name); |
2273 } | 2499 } |
2274 | 2500 |
2275 | 2501 |
2276 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, | 2502 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, |
2277 GlobalObject* holder, | 2503 GlobalObject* holder, |
2278 JSGlobalPropertyCell* cell, | 2504 JSGlobalPropertyCell* cell, |
2279 JSFunction* function, | 2505 JSFunction* function, |
2280 String* name) { | 2506 String* name) { |
2281 // ----------- S t a t e ------------- | 2507 // ----------- S t a t e ------------- |
2282 // rcx : function name | 2508 // rcx : function name |
2283 // rsp[0] : return address | 2509 // rsp[0] : return address |
2284 // rsp[8] : argument argc | 2510 // rsp[8] : argument argc |
2285 // rsp[16] : argument argc - 1 | 2511 // rsp[16] : argument argc - 1 |
2286 // ... | 2512 // ... |
2287 // rsp[argc * 8] : argument 1 | 2513 // rsp[argc * 8] : argument 1 |
2288 // rsp[(argc + 1) * 8] : argument 0 = receiver | 2514 // rsp[(argc + 1) * 8] : argument 0 = receiver |
2289 // ----------------------------------- | 2515 // ----------------------------------- |
2290 | 2516 |
2291 if (HasCustomCallGenerator(function)) { | 2517 if (HasCustomCallGenerator(function)) { |
2292 MaybeObject* maybe_result = CompileCustomCall( | 2518 MaybeObject* maybe_result = CompileCustomCall( |
2293 object, holder, cell, function, name); | 2519 object, holder, cell, function, name); |
2294 Object* result; | 2520 Object* result; |
2295 if (!maybe_result->ToObject(&result)) return maybe_result; | 2521 if (!maybe_result->ToObject(&result)) return maybe_result; |
2296 // undefined means bail out to regular compiler. | 2522 // undefined means bail out to regular compiler. |
2297 if (!result->IsUndefined()) return result; | 2523 if (!result->IsUndefined()) return result; |
2298 } | 2524 } |
2299 | 2525 |
2300 Label miss; | 2526 Label miss; |
2301 | 2527 |
2302 GenerateNameCheck(name, &miss); | 2528 GenerateNameCheck(Handle<String>(name), &miss); |
2303 | 2529 |
2304 // Get the number of arguments. | 2530 // Get the number of arguments. |
2305 const int argc = arguments().immediate(); | 2531 const int argc = arguments().immediate(); |
2306 | 2532 |
2307 GenerateGlobalReceiverCheck(object, holder, name, &miss); | 2533 GenerateGlobalReceiverCheck(object, holder, name, &miss); |
2308 | 2534 |
2309 GenerateLoadFunctionFromCell(cell, function, &miss); | 2535 GenerateLoadFunctionFromCell(cell, function, &miss); |
2310 | 2536 |
2311 // Patch the receiver on the stack with the global proxy. | 2537 // Patch the receiver on the stack with the global proxy. |
2312 if (object->IsGlobalObject()) { | 2538 if (object->IsGlobalObject()) { |
2313 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | 2539 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); |
2314 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); | 2540 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); |
2315 } | 2541 } |
2316 | 2542 |
2317 // Setup the context (function already in rdi). | 2543 // Setup the context (function already in rdi). |
2318 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | 2544 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
2319 | 2545 |
2320 // Jump to the cached code (tail call). | 2546 // Jump to the cached code (tail call). |
2321 Counters* counters = isolate()->counters(); | 2547 Counters* counters = isolate()->counters(); |
2322 __ IncrementCounter(counters->call_global_inline(), 1); | 2548 __ IncrementCounter(counters->call_global_inline(), 1); |
2323 ASSERT(function->is_compiled()); | |
2324 ParameterCount expected(function->shared()->formal_parameter_count()); | 2549 ParameterCount expected(function->shared()->formal_parameter_count()); |
2325 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 2550 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
2326 ? CALL_AS_FUNCTION | 2551 ? CALL_AS_FUNCTION |
2327 : CALL_AS_METHOD; | 2552 : CALL_AS_METHOD; |
2328 if (V8::UseCrankshaft()) { | 2553 // We call indirectly through the code field in the function to |
2329 // TODO(kasperl): For now, we always call indirectly through the | 2554 // allow recompilation to take effect without changing any of the |
2330 // code field in the function to allow recompilation to take effect | 2555 // call sites. |
2331 // without changing any of the call sites. | 2556 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
2332 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); | 2557 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION, |
2333 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION, | 2558 NullCallWrapper(), call_kind); |
2334 NullCallWrapper(), call_kind); | 2559 |
2335 } else { | |
2336 Handle<Code> code(function->code()); | |
2337 __ InvokeCode(code, expected, arguments(), | |
2338 RelocInfo::CODE_TARGET, JUMP_FUNCTION, | |
2339 NullCallWrapper(), call_kind); | |
2340 } | |
2341 // Handle call cache miss. | 2560 // Handle call cache miss. |
2342 __ bind(&miss); | 2561 __ bind(&miss); |
2343 __ IncrementCounter(counters->call_global_inline_miss(), 1); | 2562 __ IncrementCounter(counters->call_global_inline_miss(), 1); |
2344 MaybeObject* maybe_result = GenerateMissBranch(); | 2563 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2345 if (maybe_result->IsFailure()) return maybe_result; | 2564 if (maybe_result->IsFailure()) return maybe_result; |
2346 | 2565 |
2347 // Return the generated code. | 2566 // Return the generated code. |
2348 return GetCode(NORMAL, name); | 2567 return TryGetCode(NORMAL, name); |
2349 } | 2568 } |
2350 | 2569 |
2351 | 2570 |
2352 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, | 2571 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
2353 int index, | 2572 int index, |
2354 Map* transition, | 2573 Handle<Map> transition, |
2355 String* name) { | 2574 Handle<String> name) { |
2356 // ----------- S t a t e ------------- | 2575 // ----------- S t a t e ------------- |
2357 // -- rax : value | 2576 // -- rax : value |
2358 // -- rcx : name | 2577 // -- rcx : name |
2359 // -- rdx : receiver | 2578 // -- rdx : receiver |
2360 // -- rsp[0] : return address | 2579 // -- rsp[0] : return address |
2361 // ----------------------------------- | 2580 // ----------------------------------- |
2362 Label miss; | 2581 Label miss; |
2363 | 2582 |
2364 // Generate store field code. Preserves receiver and name on jump to miss. | 2583 // Generate store field code. Preserves receiver and name on jump to miss. |
2365 GenerateStoreField(masm(), | 2584 GenerateStoreField(masm(), object, index, transition, rdx, rcx, rbx, &miss); |
2366 object, | |
2367 index, | |
2368 transition, | |
2369 rdx, rcx, rbx, | |
2370 &miss); | |
2371 | 2585 |
2372 // Handle store cache miss. | 2586 // Handle store cache miss. |
2373 __ bind(&miss); | 2587 __ bind(&miss); |
2374 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); | 2588 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); |
2375 __ Jump(ic, RelocInfo::CODE_TARGET); | 2589 __ Jump(ic, RelocInfo::CODE_TARGET); |
2376 | 2590 |
2377 // Return the generated code. | 2591 // Return the generated code. |
2378 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 2592 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name); |
2379 } | 2593 } |
2380 | 2594 |
2381 | 2595 |
2382 MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object, | 2596 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
2383 AccessorInfo* callback, | 2597 Handle<JSObject> object, |
2384 String* name) { | 2598 Handle<AccessorInfo> callback, |
| 2599 Handle<String> name) { |
2385 // ----------- S t a t e ------------- | 2600 // ----------- S t a t e ------------- |
2386 // -- rax : value | 2601 // -- rax : value |
2387 // -- rcx : name | 2602 // -- rcx : name |
2388 // -- rdx : receiver | 2603 // -- rdx : receiver |
2389 // -- rsp[0] : return address | 2604 // -- rsp[0] : return address |
2390 // ----------------------------------- | 2605 // ----------------------------------- |
2391 Label miss; | 2606 Label miss; |
2392 | 2607 |
2393 // Check that the object isn't a smi. | 2608 // Check that the object isn't a smi. |
2394 __ JumpIfSmi(rdx, &miss); | 2609 __ JumpIfSmi(rdx, &miss); |
2395 | 2610 |
2396 // Check that the map of the object hasn't changed. | 2611 // Check that the map of the object hasn't changed. |
2397 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), | 2612 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), |
2398 Handle<Map>(object->map())); | 2613 Handle<Map>(object->map())); |
2399 __ j(not_equal, &miss); | 2614 __ j(not_equal, &miss); |
2400 | 2615 |
2401 // Perform global security token check if needed. | 2616 // Perform global security token check if needed. |
2402 if (object->IsJSGlobalProxy()) { | 2617 if (object->IsJSGlobalProxy()) { |
2403 __ CheckAccessGlobalProxy(rdx, rbx, &miss); | 2618 __ CheckAccessGlobalProxy(rdx, rbx, &miss); |
2404 } | 2619 } |
2405 | 2620 |
2406 // Stub never generated for non-global objects that require access | 2621 // Stub never generated for non-global objects that require access |
2407 // checks. | 2622 // checks. |
2408 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 2623 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
2409 | 2624 |
2410 __ pop(rbx); // remove the return address | 2625 __ pop(rbx); // remove the return address |
2411 __ push(rdx); // receiver | 2626 __ push(rdx); // receiver |
2412 __ Push(Handle<AccessorInfo>(callback)); // callback info | 2627 __ Push(callback); // callback info |
2413 __ push(rcx); // name | 2628 __ push(rcx); // name |
2414 __ push(rax); // value | 2629 __ push(rax); // value |
2415 __ push(rbx); // restore return address | 2630 __ push(rbx); // restore return address |
2416 | 2631 |
2417 // Do tail-call to the runtime system. | 2632 // Do tail-call to the runtime system. |
2418 ExternalReference store_callback_property = | 2633 ExternalReference store_callback_property = |
2419 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); | 2634 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); |
2420 __ TailCallExternalReference(store_callback_property, 4, 1); | 2635 __ TailCallExternalReference(store_callback_property, 4, 1); |
2421 | 2636 |
2422 // Handle store cache miss. | 2637 // Handle store cache miss. |
2423 __ bind(&miss); | 2638 __ bind(&miss); |
2424 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); | 2639 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); |
2425 __ Jump(ic, RelocInfo::CODE_TARGET); | 2640 __ Jump(ic, RelocInfo::CODE_TARGET); |
2426 | 2641 |
2427 // Return the generated code. | 2642 // Return the generated code. |
2428 return GetCode(CALLBACKS, name); | 2643 return GetCode(CALLBACKS, name); |
2429 } | 2644 } |
2430 | 2645 |
2431 | 2646 |
2432 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, | 2647 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( |
2433 String* name) { | 2648 Handle<JSObject> receiver, |
| 2649 Handle<String> name) { |
2434 // ----------- S t a t e ------------- | 2650 // ----------- S t a t e ------------- |
2435 // -- rax : value | 2651 // -- rax : value |
2436 // -- rcx : name | 2652 // -- rcx : name |
2437 // -- rdx : receiver | 2653 // -- rdx : receiver |
2438 // -- rsp[0] : return address | 2654 // -- rsp[0] : return address |
2439 // ----------------------------------- | 2655 // ----------------------------------- |
2440 Label miss; | 2656 Label miss; |
2441 | 2657 |
2442 // Check that the object isn't a smi. | 2658 // Check that the object isn't a smi. |
2443 __ JumpIfSmi(rdx, &miss); | 2659 __ JumpIfSmi(rdx, &miss); |
(...skipping 27 matching lines...) Expand all Loading... |
2471 // Handle store cache miss. | 2687 // Handle store cache miss. |
2472 __ bind(&miss); | 2688 __ bind(&miss); |
2473 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); | 2689 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); |
2474 __ Jump(ic, RelocInfo::CODE_TARGET); | 2690 __ Jump(ic, RelocInfo::CODE_TARGET); |
2475 | 2691 |
2476 // Return the generated code. | 2692 // Return the generated code. |
2477 return GetCode(INTERCEPTOR, name); | 2693 return GetCode(INTERCEPTOR, name); |
2478 } | 2694 } |
2479 | 2695 |
2480 | 2696 |
2481 MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object, | 2697 Handle<Code> StoreStubCompiler::CompileStoreGlobal( |
2482 JSGlobalPropertyCell* cell, | 2698 Handle<GlobalObject> object, |
2483 String* name) { | 2699 Handle<JSGlobalPropertyCell> cell, |
| 2700 Handle<String> name) { |
2484 // ----------- S t a t e ------------- | 2701 // ----------- S t a t e ------------- |
2485 // -- rax : value | 2702 // -- rax : value |
2486 // -- rcx : name | 2703 // -- rcx : name |
2487 // -- rdx : receiver | 2704 // -- rdx : receiver |
2488 // -- rsp[0] : return address | 2705 // -- rsp[0] : return address |
2489 // ----------------------------------- | 2706 // ----------------------------------- |
2490 Label miss; | 2707 Label miss; |
2491 | 2708 |
2492 // Check that the map of the global has not changed. | 2709 // Check that the map of the global has not changed. |
2493 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), | 2710 __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), |
2494 Handle<Map>(object->map())); | 2711 Handle<Map>(object->map())); |
2495 __ j(not_equal, &miss); | 2712 __ j(not_equal, &miss); |
2496 | 2713 |
2497 // Compute the cell operand to use. | 2714 // Compute the cell operand to use. |
2498 __ Move(rbx, Handle<JSGlobalPropertyCell>(cell)); | 2715 __ Move(rbx, cell); |
2499 Operand cell_operand = FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset); | 2716 Operand cell_operand = FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset); |
2500 | 2717 |
2501 // Check that the value in the cell is not the hole. If it is, this | 2718 // Check that the value in the cell is not the hole. If it is, this |
2502 // cell could have been deleted and reintroducing the global needs | 2719 // cell could have been deleted and reintroducing the global needs |
2503 // to update the property details in the property dictionary of the | 2720 // to update the property details in the property dictionary of the |
2504 // global object. We bail out to the runtime system to do that. | 2721 // global object. We bail out to the runtime system to do that. |
2505 __ CompareRoot(cell_operand, Heap::kTheHoleValueRootIndex); | 2722 __ CompareRoot(cell_operand, Heap::kTheHoleValueRootIndex); |
2506 __ j(equal, &miss); | 2723 __ j(equal, &miss); |
2507 | 2724 |
2508 // Store the value in the cell. | 2725 // Store the value in the cell. |
(...skipping 23 matching lines...) Expand all Loading... |
2532 __ bind(&miss); | 2749 __ bind(&miss); |
2533 __ IncrementCounter(counters->named_store_global_inline_miss(), 1); | 2750 __ IncrementCounter(counters->named_store_global_inline_miss(), 1); |
2534 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); | 2751 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); |
2535 __ Jump(ic, RelocInfo::CODE_TARGET); | 2752 __ Jump(ic, RelocInfo::CODE_TARGET); |
2536 | 2753 |
2537 // Return the generated code. | 2754 // Return the generated code. |
2538 return GetCode(NORMAL, name); | 2755 return GetCode(NORMAL, name); |
2539 } | 2756 } |
2540 | 2757 |
2541 | 2758 |
2542 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, | 2759 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
2543 int index, | 2760 int index, |
2544 Map* transition, | 2761 Handle<Map> transition, |
2545 String* name) { | 2762 Handle<String> name) { |
2546 // ----------- S t a t e ------------- | 2763 // ----------- S t a t e ------------- |
2547 // -- rax : value | 2764 // -- rax : value |
2548 // -- rcx : key | 2765 // -- rcx : key |
2549 // -- rdx : receiver | 2766 // -- rdx : receiver |
2550 // -- rsp[0] : return address | 2767 // -- rsp[0] : return address |
2551 // ----------------------------------- | 2768 // ----------------------------------- |
2552 Label miss; | 2769 Label miss; |
2553 | 2770 |
2554 Counters* counters = isolate()->counters(); | 2771 Counters* counters = isolate()->counters(); |
2555 __ IncrementCounter(counters->keyed_store_field(), 1); | 2772 __ IncrementCounter(counters->keyed_store_field(), 1); |
2556 | 2773 |
2557 // Check that the name has not changed. | 2774 // Check that the name has not changed. |
2558 __ Cmp(rcx, Handle<String>(name)); | 2775 __ Cmp(rcx, name); |
2559 __ j(not_equal, &miss); | 2776 __ j(not_equal, &miss); |
2560 | 2777 |
2561 // Generate store field code. Preserves receiver and name on jump to miss. | 2778 // Generate store field code. Preserves receiver and name on jump to miss. |
2562 GenerateStoreField(masm(), | 2779 GenerateStoreField(masm(), object, index, transition, rdx, rcx, rbx, &miss); |
2563 object, | |
2564 index, | |
2565 transition, | |
2566 rdx, rcx, rbx, | |
2567 &miss); | |
2568 | 2780 |
2569 // Handle store cache miss. | 2781 // Handle store cache miss. |
2570 __ bind(&miss); | 2782 __ bind(&miss); |
2571 __ DecrementCounter(counters->keyed_store_field(), 1); | 2783 __ DecrementCounter(counters->keyed_store_field(), 1); |
2572 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 2784 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
2573 __ Jump(ic, RelocInfo::CODE_TARGET); | 2785 __ Jump(ic, RelocInfo::CODE_TARGET); |
2574 | 2786 |
2575 // Return the generated code. | 2787 // Return the generated code. |
2576 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 2788 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name); |
2577 } | 2789 } |
2578 | 2790 |
2579 | 2791 |
2580 MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(Map* receiver_map) { | 2792 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement( |
| 2793 Handle<Map> receiver_map) { |
2581 // ----------- S t a t e ------------- | 2794 // ----------- S t a t e ------------- |
2582 // -- rax : value | 2795 // -- rax : value |
2583 // -- rcx : key | 2796 // -- rcx : key |
2584 // -- rdx : receiver | 2797 // -- rdx : receiver |
2585 // -- rsp[0] : return address | 2798 // -- rsp[0] : return address |
2586 // ----------------------------------- | 2799 // ----------------------------------- |
2587 Code* stub; | 2800 |
2588 ElementsKind elements_kind = receiver_map->elements_kind(); | 2801 ElementsKind elements_kind = receiver_map->elements_kind(); |
2589 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; | 2802 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; |
2590 MaybeObject* maybe_stub = | 2803 Handle<Code> stub = |
2591 KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode(); | 2804 KeyedStoreElementStub(is_js_array, elements_kind).GetCode(); |
2592 if (!maybe_stub->To(&stub)) return maybe_stub; | 2805 |
2593 __ DispatchMap(rdx, | 2806 __ DispatchMap(rdx, receiver_map, stub, DO_SMI_CHECK); |
2594 Handle<Map>(receiver_map), | |
2595 Handle<Code>(stub), | |
2596 DO_SMI_CHECK); | |
2597 | 2807 |
2598 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 2808 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
2599 __ jmp(ic, RelocInfo::CODE_TARGET); | 2809 __ jmp(ic, RelocInfo::CODE_TARGET); |
2600 | 2810 |
2601 // Return the generated code. | 2811 // Return the generated code. |
2602 return GetCode(NORMAL, NULL); | 2812 return GetCode(NORMAL, factory()->empty_string()); |
2603 } | 2813 } |
2604 | 2814 |
2605 | 2815 |
2606 MaybeObject* KeyedStoreStubCompiler::CompileStorePolymorphic( | 2816 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( |
2607 MapList* receiver_maps, | 2817 MapHandleList* receiver_maps, |
2608 CodeList* handler_stubs, | 2818 CodeHandleList* handler_stubs, |
2609 MapList* transitioned_maps) { | 2819 MapHandleList* transitioned_maps) { |
2610 // ----------- S t a t e ------------- | 2820 // ----------- S t a t e ------------- |
2611 // -- rax : value | 2821 // -- rax : value |
2612 // -- rcx : key | 2822 // -- rcx : key |
2613 // -- rdx : receiver | 2823 // -- rdx : receiver |
2614 // -- rsp[0] : return address | 2824 // -- rsp[0] : return address |
2615 // ----------------------------------- | 2825 // ----------------------------------- |
2616 Label miss; | 2826 Label miss; |
2617 __ JumpIfSmi(rdx, &miss, Label::kNear); | 2827 __ JumpIfSmi(rdx, &miss, Label::kNear); |
2618 | 2828 |
2619 __ movq(rdi, FieldOperand(rdx, HeapObject::kMapOffset)); | 2829 __ movq(rdi, FieldOperand(rdx, HeapObject::kMapOffset)); |
2620 int receiver_count = receiver_maps->length(); | 2830 int receiver_count = receiver_maps->length(); |
2621 for (int i = 0; i < receiver_count; ++i) { | 2831 for (int i = 0; i < receiver_count; ++i) { |
2622 // Check map and tail call if there's a match | 2832 // Check map and tail call if there's a match |
2623 Handle<Map> map(receiver_maps->at(i)); | 2833 __ Cmp(rdi, receiver_maps->at(i)); |
2624 __ Cmp(rdi, map); | 2834 if (transitioned_maps->at(i).is_null()) { |
2625 if (transitioned_maps->at(i) == NULL) { | 2835 __ j(equal, handler_stubs->at(i), RelocInfo::CODE_TARGET); |
2626 __ j(equal, Handle<Code>(handler_stubs->at(i)), RelocInfo::CODE_TARGET); | |
2627 } else { | 2836 } else { |
2628 Label next_map; | 2837 Label next_map; |
2629 __ j(not_equal, &next_map, Label::kNear); | 2838 __ j(not_equal, &next_map, Label::kNear); |
2630 __ movq(rbx, | 2839 __ movq(rbx, transitioned_maps->at(i), RelocInfo::EMBEDDED_OBJECT); |
2631 Handle<Map>(transitioned_maps->at(i)), | 2840 __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET); |
2632 RelocInfo::EMBEDDED_OBJECT); | |
2633 __ jmp(Handle<Code>(handler_stubs->at(i)), RelocInfo::CODE_TARGET); | |
2634 __ bind(&next_map); | 2841 __ bind(&next_map); |
2635 } | 2842 } |
2636 } | 2843 } |
2637 | 2844 |
2638 __ bind(&miss); | 2845 __ bind(&miss); |
2639 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 2846 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
2640 __ jmp(ic, RelocInfo::CODE_TARGET); | 2847 __ jmp(ic, RelocInfo::CODE_TARGET); |
2641 | 2848 |
2642 // Return the generated code. | 2849 // Return the generated code. |
2643 return GetCode(NORMAL, NULL, MEGAMORPHIC); | 2850 return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC); |
2644 } | 2851 } |
2645 | 2852 |
2646 | 2853 |
2647 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, | 2854 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<String> name, |
2648 JSObject* object, | 2855 Handle<JSObject> object, |
2649 JSObject* last) { | 2856 Handle<JSObject> last) { |
2650 // ----------- S t a t e ------------- | 2857 // ----------- S t a t e ------------- |
2651 // -- rax : receiver | 2858 // -- rax : receiver |
2652 // -- rcx : name | 2859 // -- rcx : name |
2653 // -- rsp[0] : return address | 2860 // -- rsp[0] : return address |
2654 // ----------------------------------- | 2861 // ----------------------------------- |
2655 Label miss; | 2862 Label miss; |
2656 | 2863 |
2657 // Check that receiver is not a smi. | 2864 // Check that receiver is not a smi. |
2658 __ JumpIfSmi(rax, &miss); | 2865 __ JumpIfSmi(rax, &miss); |
2659 | 2866 |
2660 // Check the maps of the full prototype chain. Also check that | 2867 // Check the maps of the full prototype chain. Also check that |
2661 // global property cells up to (but not including) the last object | 2868 // global property cells up to (but not including) the last object |
2662 // in the prototype chain are empty. | 2869 // in the prototype chain are empty. |
2663 CheckPrototypes(object, rax, last, rbx, rdx, rdi, name, &miss); | 2870 CheckPrototypes(object, rax, last, rbx, rdx, rdi, name, &miss); |
2664 | 2871 |
2665 // If the last object in the prototype chain is a global object, | 2872 // If the last object in the prototype chain is a global object, |
2666 // check that the global property cell is empty. | 2873 // check that the global property cell is empty. |
2667 if (last->IsGlobalObject()) { | 2874 if (last->IsGlobalObject()) { |
2668 MaybeObject* cell = GenerateCheckPropertyCell(masm(), | 2875 GenerateCheckPropertyCell( |
2669 GlobalObject::cast(last), | 2876 masm(), Handle<GlobalObject>::cast(last), name, rdx, &miss); |
2670 name, | |
2671 rdx, | |
2672 &miss); | |
2673 if (cell->IsFailure()) { | |
2674 miss.Unuse(); | |
2675 return cell; | |
2676 } | |
2677 } | 2877 } |
2678 | 2878 |
2679 // Return undefined if maps of the full prototype chain are still the | 2879 // Return undefined if maps of the full prototype chain are still the |
2680 // same and no global property with this name contains a value. | 2880 // same and no global property with this name contains a value. |
2681 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); | 2881 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); |
2682 __ ret(0); | 2882 __ ret(0); |
2683 | 2883 |
2684 __ bind(&miss); | 2884 __ bind(&miss); |
2685 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2885 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2686 | 2886 |
2687 // Return the generated code. | 2887 // Return the generated code. |
2688 return GetCode(NONEXISTENT, heap()->empty_string()); | 2888 return GetCode(NONEXISTENT, factory()->empty_string()); |
2689 } | 2889 } |
2690 | 2890 |
2691 | 2891 |
2692 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object, | 2892 Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object, |
2693 JSObject* holder, | 2893 Handle<JSObject> holder, |
2694 int index, | 2894 int index, |
2695 String* name) { | 2895 Handle<String> name) { |
2696 // ----------- S t a t e ------------- | 2896 // ----------- S t a t e ------------- |
2697 // -- rax : receiver | 2897 // -- rax : receiver |
2698 // -- rcx : name | 2898 // -- rcx : name |
2699 // -- rsp[0] : return address | 2899 // -- rsp[0] : return address |
2700 // ----------------------------------- | 2900 // ----------------------------------- |
2701 Label miss; | 2901 Label miss; |
2702 | 2902 |
2703 GenerateLoadField(object, holder, rax, rbx, rdx, rdi, index, name, &miss); | 2903 GenerateLoadField(object, holder, rax, rbx, rdx, rdi, index, name, &miss); |
2704 __ bind(&miss); | 2904 __ bind(&miss); |
2705 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2905 GenerateLoadMiss(masm(), Code::LOAD_IC); |
(...skipping 18 matching lines...) Expand all Loading... |
2724 rdi, callback, name, &miss); | 2924 rdi, callback, name, &miss); |
2725 if (result->IsFailure()) { | 2925 if (result->IsFailure()) { |
2726 miss.Unuse(); | 2926 miss.Unuse(); |
2727 return result; | 2927 return result; |
2728 } | 2928 } |
2729 | 2929 |
2730 __ bind(&miss); | 2930 __ bind(&miss); |
2731 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2931 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2732 | 2932 |
2733 // Return the generated code. | 2933 // Return the generated code. |
2734 return GetCode(CALLBACKS, name); | 2934 return TryGetCode(CALLBACKS, name); |
2735 } | 2935 } |
2736 | 2936 |
2737 | 2937 |
2738 MaybeObject* LoadStubCompiler::CompileLoadConstant(JSObject* object, | 2938 Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object, |
2739 JSObject* holder, | 2939 Handle<JSObject> holder, |
2740 Object* value, | 2940 Handle<Object> value, |
2741 String* name) { | 2941 Handle<String> name) { |
2742 // ----------- S t a t e ------------- | 2942 // ----------- S t a t e ------------- |
2743 // -- rax : receiver | 2943 // -- rax : receiver |
2744 // -- rcx : name | 2944 // -- rcx : name |
2745 // -- rsp[0] : return address | 2945 // -- rsp[0] : return address |
2746 // ----------------------------------- | 2946 // ----------------------------------- |
2747 Label miss; | 2947 Label miss; |
2748 | 2948 |
2749 GenerateLoadConstant(object, holder, rax, rbx, rdx, rdi, value, name, &miss); | 2949 GenerateLoadConstant(object, holder, rax, rbx, rdx, rdi, value, name, &miss); |
2750 __ bind(&miss); | 2950 __ bind(&miss); |
2751 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2951 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2752 | 2952 |
2753 // Return the generated code. | 2953 // Return the generated code. |
2754 return GetCode(CONSTANT_FUNCTION, name); | 2954 return GetCode(CONSTANT_FUNCTION, name); |
2755 } | 2955 } |
2756 | 2956 |
2757 | 2957 |
2758 MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 2958 MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, |
2759 JSObject* holder, | 2959 JSObject* holder, |
2760 String* name) { | 2960 String* name) { |
2761 // ----------- S t a t e ------------- | 2961 // ----------- S t a t e ------------- |
2762 // -- rax : receiver | 2962 // -- rax : receiver |
2763 // -- rcx : name | 2963 // -- rcx : name |
2764 // -- rsp[0] : return address | 2964 // -- rsp[0] : return address |
2765 // ----------------------------------- | 2965 // ----------------------------------- |
2766 Label miss; | 2966 Label miss; |
2767 | 2967 |
2768 LookupResult lookup; | 2968 LookupResult lookup(isolate()); |
2769 LookupPostInterceptor(holder, name, &lookup); | 2969 LookupPostInterceptor(holder, name, &lookup); |
2770 | 2970 |
2771 // TODO(368): Compile in the whole chain: all the interceptors in | 2971 // TODO(368): Compile in the whole chain: all the interceptors in |
2772 // prototypes and ultimate answer. | 2972 // prototypes and ultimate answer. |
2773 GenerateLoadInterceptor(receiver, | 2973 GenerateLoadInterceptor(receiver, |
2774 holder, | 2974 holder, |
2775 &lookup, | 2975 &lookup, |
2776 rax, | 2976 rax, |
2777 rcx, | 2977 rcx, |
2778 rdx, | 2978 rdx, |
2779 rbx, | 2979 rbx, |
2780 rdi, | 2980 rdi, |
2781 name, | 2981 name, |
2782 &miss); | 2982 &miss); |
2783 | 2983 |
2784 __ bind(&miss); | 2984 __ bind(&miss); |
2785 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2985 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2786 | 2986 |
2787 // Return the generated code. | 2987 // Return the generated code. |
2788 return GetCode(INTERCEPTOR, name); | 2988 return TryGetCode(INTERCEPTOR, name); |
2789 } | 2989 } |
2790 | 2990 |
2791 | 2991 |
2792 MaybeObject* LoadStubCompiler::CompileLoadGlobal(JSObject* object, | 2992 Handle<Code> LoadStubCompiler::CompileLoadGlobal( |
2793 GlobalObject* holder, | 2993 Handle<JSObject> object, |
2794 JSGlobalPropertyCell* cell, | 2994 Handle<GlobalObject> holder, |
2795 String* name, | 2995 Handle<JSGlobalPropertyCell> cell, |
2796 bool is_dont_delete) { | 2996 Handle<String> name, |
| 2997 bool is_dont_delete) { |
2797 // ----------- S t a t e ------------- | 2998 // ----------- S t a t e ------------- |
2798 // -- rax : receiver | 2999 // -- rax : receiver |
2799 // -- rcx : name | 3000 // -- rcx : name |
2800 // -- rsp[0] : return address | 3001 // -- rsp[0] : return address |
2801 // ----------------------------------- | 3002 // ----------------------------------- |
2802 Label miss; | 3003 Label miss; |
2803 | 3004 |
2804 // If the object is the holder then we know that it's a global | 3005 // If the object is the holder then we know that it's a global |
2805 // object which can only happen for contextual loads. In this case, | 3006 // object which can only happen for contextual loads. In this case, |
2806 // the receiver cannot be a smi. | 3007 // the receiver cannot be a smi. |
2807 if (object != holder) { | 3008 if (!object.is_identical_to(holder)) { |
2808 __ JumpIfSmi(rax, &miss); | 3009 __ JumpIfSmi(rax, &miss); |
2809 } | 3010 } |
2810 | 3011 |
2811 // Check that the maps haven't changed. | 3012 // Check that the maps haven't changed. |
2812 CheckPrototypes(object, rax, holder, rbx, rdx, rdi, name, &miss); | 3013 CheckPrototypes(object, rax, holder, rbx, rdx, rdi, name, &miss); |
2813 | 3014 |
2814 // Get the value from the cell. | 3015 // Get the value from the cell. |
2815 __ Move(rbx, Handle<JSGlobalPropertyCell>(cell)); | 3016 __ Move(rbx, cell); |
2816 __ movq(rbx, FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset)); | 3017 __ movq(rbx, FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset)); |
2817 | 3018 |
2818 // Check for deleted property if property can actually be deleted. | 3019 // Check for deleted property if property can actually be deleted. |
2819 if (!is_dont_delete) { | 3020 if (!is_dont_delete) { |
2820 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); | 3021 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); |
2821 __ j(equal, &miss); | 3022 __ j(equal, &miss); |
2822 } else if (FLAG_debug_code) { | 3023 } else if (FLAG_debug_code) { |
2823 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); | 3024 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); |
2824 __ Check(not_equal, "DontDelete cells can't contain the hole"); | 3025 __ Check(not_equal, "DontDelete cells can't contain the hole"); |
2825 } | 3026 } |
2826 | 3027 |
2827 Counters* counters = isolate()->counters(); | 3028 Counters* counters = isolate()->counters(); |
2828 __ IncrementCounter(counters->named_load_global_stub(), 1); | 3029 __ IncrementCounter(counters->named_load_global_stub(), 1); |
2829 __ movq(rax, rbx); | 3030 __ movq(rax, rbx); |
2830 __ ret(0); | 3031 __ ret(0); |
2831 | 3032 |
2832 __ bind(&miss); | 3033 __ bind(&miss); |
2833 __ IncrementCounter(counters->named_load_global_stub_miss(), 1); | 3034 __ IncrementCounter(counters->named_load_global_stub_miss(), 1); |
2834 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3035 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2835 | 3036 |
2836 // Return the generated code. | 3037 // Return the generated code. |
2837 return GetCode(NORMAL, name); | 3038 return GetCode(NORMAL, name); |
2838 } | 3039 } |
2839 | 3040 |
2840 | 3041 |
2841 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, | 3042 Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name, |
2842 JSObject* receiver, | 3043 Handle<JSObject> receiver, |
2843 JSObject* holder, | 3044 Handle<JSObject> holder, |
2844 int index) { | 3045 int index) { |
2845 // ----------- S t a t e ------------- | 3046 // ----------- S t a t e ------------- |
2846 // -- rax : key | 3047 // -- rax : key |
2847 // -- rdx : receiver | 3048 // -- rdx : receiver |
2848 // -- rsp[0] : return address | 3049 // -- rsp[0] : return address |
2849 // ----------------------------------- | 3050 // ----------------------------------- |
2850 Label miss; | 3051 Label miss; |
2851 | 3052 |
2852 Counters* counters = isolate()->counters(); | 3053 Counters* counters = isolate()->counters(); |
2853 __ IncrementCounter(counters->keyed_load_field(), 1); | 3054 __ IncrementCounter(counters->keyed_load_field(), 1); |
2854 | 3055 |
2855 // Check that the name has not changed. | 3056 // Check that the name has not changed. |
2856 __ Cmp(rax, Handle<String>(name)); | 3057 __ Cmp(rax, name); |
2857 __ j(not_equal, &miss); | 3058 __ j(not_equal, &miss); |
2858 | 3059 |
2859 GenerateLoadField(receiver, holder, rdx, rbx, rcx, rdi, index, name, &miss); | 3060 GenerateLoadField(receiver, holder, rdx, rbx, rcx, rdi, index, name, &miss); |
2860 | 3061 |
2861 __ bind(&miss); | 3062 __ bind(&miss); |
2862 __ DecrementCounter(counters->keyed_load_field(), 1); | 3063 __ DecrementCounter(counters->keyed_load_field(), 1); |
2863 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3064 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2864 | 3065 |
2865 // Return the generated code. | 3066 // Return the generated code. |
2866 return GetCode(FIELD, name); | 3067 return GetCode(FIELD, name); |
(...skipping 25 matching lines...) Expand all Loading... |
2892 miss.Unuse(); | 3093 miss.Unuse(); |
2893 return result; | 3094 return result; |
2894 } | 3095 } |
2895 | 3096 |
2896 __ bind(&miss); | 3097 __ bind(&miss); |
2897 | 3098 |
2898 __ DecrementCounter(counters->keyed_load_callback(), 1); | 3099 __ DecrementCounter(counters->keyed_load_callback(), 1); |
2899 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3100 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2900 | 3101 |
2901 // Return the generated code. | 3102 // Return the generated code. |
2902 return GetCode(CALLBACKS, name); | 3103 return TryGetCode(CALLBACKS, name); |
2903 } | 3104 } |
2904 | 3105 |
2905 | 3106 |
2906 MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name, | 3107 Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant( |
2907 JSObject* receiver, | 3108 Handle<String> name, |
2908 JSObject* holder, | 3109 Handle<JSObject> receiver, |
2909 Object* value) { | 3110 Handle<JSObject> holder, |
| 3111 Handle<Object> value) { |
2910 // ----------- S t a t e ------------- | 3112 // ----------- S t a t e ------------- |
2911 // -- rax : key | 3113 // -- rax : key |
2912 // -- rdx : receiver | 3114 // -- rdx : receiver |
2913 // -- rsp[0] : return address | 3115 // -- rsp[0] : return address |
2914 // ----------------------------------- | 3116 // ----------------------------------- |
2915 Label miss; | 3117 Label miss; |
2916 | 3118 |
2917 Counters* counters = isolate()->counters(); | 3119 Counters* counters = isolate()->counters(); |
2918 __ IncrementCounter(counters->keyed_load_constant_function(), 1); | 3120 __ IncrementCounter(counters->keyed_load_constant_function(), 1); |
2919 | 3121 |
(...skipping 22 matching lines...) Expand all Loading... |
2942 // ----------------------------------- | 3144 // ----------------------------------- |
2943 Label miss; | 3145 Label miss; |
2944 | 3146 |
2945 Counters* counters = isolate()->counters(); | 3147 Counters* counters = isolate()->counters(); |
2946 __ IncrementCounter(counters->keyed_load_interceptor(), 1); | 3148 __ IncrementCounter(counters->keyed_load_interceptor(), 1); |
2947 | 3149 |
2948 // Check that the name has not changed. | 3150 // Check that the name has not changed. |
2949 __ Cmp(rax, Handle<String>(name)); | 3151 __ Cmp(rax, Handle<String>(name)); |
2950 __ j(not_equal, &miss); | 3152 __ j(not_equal, &miss); |
2951 | 3153 |
2952 LookupResult lookup; | 3154 LookupResult lookup(isolate()); |
2953 LookupPostInterceptor(holder, name, &lookup); | 3155 LookupPostInterceptor(holder, name, &lookup); |
2954 GenerateLoadInterceptor(receiver, | 3156 GenerateLoadInterceptor(receiver, |
2955 holder, | 3157 holder, |
2956 &lookup, | 3158 &lookup, |
2957 rdx, | 3159 rdx, |
2958 rax, | 3160 rax, |
2959 rcx, | 3161 rcx, |
2960 rbx, | 3162 rbx, |
2961 rdi, | 3163 rdi, |
2962 name, | 3164 name, |
2963 &miss); | 3165 &miss); |
2964 __ bind(&miss); | 3166 __ bind(&miss); |
2965 __ DecrementCounter(counters->keyed_load_interceptor(), 1); | 3167 __ DecrementCounter(counters->keyed_load_interceptor(), 1); |
2966 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3168 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2967 | 3169 |
2968 // Return the generated code. | 3170 // Return the generated code. |
2969 return GetCode(INTERCEPTOR, name); | 3171 return TryGetCode(INTERCEPTOR, name); |
2970 } | 3172 } |
2971 | 3173 |
2972 | 3174 |
2973 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { | 3175 Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength( |
| 3176 Handle<String> name) { |
2974 // ----------- S t a t e ------------- | 3177 // ----------- S t a t e ------------- |
2975 // -- rax : key | 3178 // -- rax : key |
2976 // -- rdx : receiver | 3179 // -- rdx : receiver |
2977 // -- rsp[0] : return address | 3180 // -- rsp[0] : return address |
2978 // ----------------------------------- | 3181 // ----------------------------------- |
2979 Label miss; | 3182 Label miss; |
2980 | 3183 |
2981 Counters* counters = isolate()->counters(); | 3184 Counters* counters = isolate()->counters(); |
2982 __ IncrementCounter(counters->keyed_load_array_length(), 1); | 3185 __ IncrementCounter(counters->keyed_load_array_length(), 1); |
2983 | 3186 |
2984 // Check that the name has not changed. | 3187 // Check that the name has not changed. |
2985 __ Cmp(rax, Handle<String>(name)); | 3188 __ Cmp(rax, name); |
2986 __ j(not_equal, &miss); | 3189 __ j(not_equal, &miss); |
2987 | 3190 |
2988 GenerateLoadArrayLength(masm(), rdx, rcx, &miss); | 3191 GenerateLoadArrayLength(masm(), rdx, rcx, &miss); |
2989 __ bind(&miss); | 3192 __ bind(&miss); |
2990 __ DecrementCounter(counters->keyed_load_array_length(), 1); | 3193 __ DecrementCounter(counters->keyed_load_array_length(), 1); |
2991 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3194 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2992 | 3195 |
2993 // Return the generated code. | 3196 // Return the generated code. |
2994 return GetCode(CALLBACKS, name); | 3197 return GetCode(CALLBACKS, name); |
2995 } | 3198 } |
2996 | 3199 |
2997 | 3200 |
2998 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { | 3201 Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength( |
| 3202 Handle<String> name) { |
2999 // ----------- S t a t e ------------- | 3203 // ----------- S t a t e ------------- |
3000 // -- rax : key | 3204 // -- rax : key |
3001 // -- rdx : receiver | 3205 // -- rdx : receiver |
3002 // -- rsp[0] : return address | 3206 // -- rsp[0] : return address |
3003 // ----------------------------------- | 3207 // ----------------------------------- |
3004 Label miss; | 3208 Label miss; |
3005 | 3209 |
3006 Counters* counters = isolate()->counters(); | 3210 Counters* counters = isolate()->counters(); |
3007 __ IncrementCounter(counters->keyed_load_string_length(), 1); | 3211 __ IncrementCounter(counters->keyed_load_string_length(), 1); |
3008 | 3212 |
3009 // Check that the name has not changed. | 3213 // Check that the name has not changed. |
3010 __ Cmp(rax, Handle<String>(name)); | 3214 __ Cmp(rax, name); |
3011 __ j(not_equal, &miss); | 3215 __ j(not_equal, &miss); |
3012 | 3216 |
3013 GenerateLoadStringLength(masm(), rdx, rcx, rbx, &miss, true); | 3217 GenerateLoadStringLength(masm(), rdx, rcx, rbx, &miss, true); |
3014 __ bind(&miss); | 3218 __ bind(&miss); |
3015 __ DecrementCounter(counters->keyed_load_string_length(), 1); | 3219 __ DecrementCounter(counters->keyed_load_string_length(), 1); |
3016 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3220 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3017 | 3221 |
3018 // Return the generated code. | 3222 // Return the generated code. |
3019 return GetCode(CALLBACKS, name); | 3223 return GetCode(CALLBACKS, name); |
3020 } | 3224 } |
3021 | 3225 |
3022 | 3226 |
3023 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { | 3227 Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype( |
| 3228 Handle<String> name) { |
3024 // ----------- S t a t e ------------- | 3229 // ----------- S t a t e ------------- |
3025 // -- rax : key | 3230 // -- rax : key |
3026 // -- rdx : receiver | 3231 // -- rdx : receiver |
3027 // -- rsp[0] : return address | 3232 // -- rsp[0] : return address |
3028 // ----------------------------------- | 3233 // ----------------------------------- |
3029 Label miss; | 3234 Label miss; |
3030 | 3235 |
3031 Counters* counters = isolate()->counters(); | 3236 Counters* counters = isolate()->counters(); |
3032 __ IncrementCounter(counters->keyed_load_function_prototype(), 1); | 3237 __ IncrementCounter(counters->keyed_load_function_prototype(), 1); |
3033 | 3238 |
3034 // Check that the name has not changed. | 3239 // Check that the name has not changed. |
3035 __ Cmp(rax, Handle<String>(name)); | 3240 __ Cmp(rax, name); |
3036 __ j(not_equal, &miss); | 3241 __ j(not_equal, &miss); |
3037 | 3242 |
3038 GenerateLoadFunctionPrototype(masm(), rdx, rcx, rbx, &miss); | 3243 GenerateLoadFunctionPrototype(masm(), rdx, rcx, rbx, &miss); |
3039 __ bind(&miss); | 3244 __ bind(&miss); |
3040 __ DecrementCounter(counters->keyed_load_function_prototype(), 1); | 3245 __ DecrementCounter(counters->keyed_load_function_prototype(), 1); |
3041 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3246 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3042 | 3247 |
3043 // Return the generated code. | 3248 // Return the generated code. |
3044 return GetCode(CALLBACKS, name); | 3249 return GetCode(CALLBACKS, name); |
3045 } | 3250 } |
3046 | 3251 |
3047 | 3252 |
3048 MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) { | 3253 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( |
| 3254 Handle<Map> receiver_map) { |
3049 // ----------- S t a t e ------------- | 3255 // ----------- S t a t e ------------- |
3050 // -- rax : key | 3256 // -- rax : key |
3051 // -- rdx : receiver | 3257 // -- rdx : receiver |
3052 // -- rsp[0] : return address | 3258 // -- rsp[0] : return address |
3053 // ----------------------------------- | 3259 // ----------------------------------- |
3054 Code* stub; | |
3055 ElementsKind elements_kind = receiver_map->elements_kind(); | 3260 ElementsKind elements_kind = receiver_map->elements_kind(); |
3056 MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode(); | 3261 Handle<Code> stub = KeyedLoadElementStub(elements_kind).GetCode(); |
3057 if (!maybe_stub->To(&stub)) return maybe_stub; | 3262 |
3058 __ DispatchMap(rdx, | 3263 __ DispatchMap(rdx, receiver_map, stub, DO_SMI_CHECK); |
3059 Handle<Map>(receiver_map), | |
3060 Handle<Code>(stub), | |
3061 DO_SMI_CHECK); | |
3062 | 3264 |
3063 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); | 3265 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); |
3064 __ jmp(ic, RelocInfo::CODE_TARGET); | 3266 __ jmp(ic, RelocInfo::CODE_TARGET); |
3065 | 3267 |
3066 // Return the generated code. | 3268 // Return the generated code. |
3067 return GetCode(NORMAL, NULL); | 3269 return GetCode(NORMAL, factory()->empty_string()); |
3068 } | 3270 } |
3069 | 3271 |
3070 | 3272 |
3071 MaybeObject* KeyedLoadStubCompiler::CompileLoadPolymorphic( | 3273 Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic( |
3072 MapList* receiver_maps, | 3274 MapHandleList* receiver_maps, |
3073 CodeList* handler_ics) { | 3275 CodeHandleList* handler_ics) { |
3074 // ----------- S t a t e ------------- | 3276 // ----------- S t a t e ------------- |
3075 // -- rax : key | 3277 // -- rax : key |
3076 // -- rdx : receiver | 3278 // -- rdx : receiver |
3077 // -- rsp[0] : return address | 3279 // -- rsp[0] : return address |
3078 // ----------------------------------- | 3280 // ----------------------------------- |
3079 Label miss; | 3281 Label miss; |
3080 __ JumpIfSmi(rdx, &miss); | 3282 __ JumpIfSmi(rdx, &miss); |
3081 | 3283 |
3082 Register map_reg = rbx; | 3284 Register map_reg = rbx; |
3083 __ movq(map_reg, FieldOperand(rdx, HeapObject::kMapOffset)); | 3285 __ movq(map_reg, FieldOperand(rdx, HeapObject::kMapOffset)); |
3084 int receiver_count = receiver_maps->length(); | 3286 int receiver_count = receiver_maps->length(); |
3085 for (int current = 0; current < receiver_count; ++current) { | 3287 for (int current = 0; current < receiver_count; ++current) { |
3086 // Check map and tail call if there's a match | 3288 // Check map and tail call if there's a match |
3087 Handle<Map> map(receiver_maps->at(current)); | 3289 __ Cmp(map_reg, receiver_maps->at(current)); |
3088 __ Cmp(map_reg, map); | 3290 __ j(equal, handler_ics->at(current), RelocInfo::CODE_TARGET); |
3089 __ j(equal, | |
3090 Handle<Code>(handler_ics->at(current)), | |
3091 RelocInfo::CODE_TARGET); | |
3092 } | 3291 } |
3093 | 3292 |
3094 __ bind(&miss); | 3293 __ bind(&miss); |
3095 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3294 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3096 | 3295 |
3097 // Return the generated code. | 3296 // Return the generated code. |
3098 return GetCode(NORMAL, NULL, MEGAMORPHIC); | 3297 return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC); |
3099 } | 3298 } |
3100 | 3299 |
3101 | 3300 |
3102 // Specialized stub for constructing objects from functions which only have only | 3301 // Specialized stub for constructing objects from functions which only have only |
3103 // simple assignments of the form this.x = ...; in their body. | 3302 // simple assignments of the form this.x = ...; in their body. |
3104 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { | 3303 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { |
3105 // ----------- S t a t e ------------- | 3304 // ----------- S t a t e ------------- |
3106 // -- rax : argc | 3305 // -- rax : argc |
3107 // -- rdi : constructor | 3306 // -- rdi : constructor |
3108 // -- rsp[0] : return address | 3307 // -- rsp[0] : return address |
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3804 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 4003 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
3805 __ jmp(ic_miss, RelocInfo::CODE_TARGET); | 4004 __ jmp(ic_miss, RelocInfo::CODE_TARGET); |
3806 } | 4005 } |
3807 | 4006 |
3808 | 4007 |
3809 #undef __ | 4008 #undef __ |
3810 | 4009 |
3811 } } // namespace v8::internal | 4010 } } // namespace v8::internal |
3812 | 4011 |
3813 #endif // V8_TARGET_ARCH_X64 | 4012 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |