Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1828)

Side by Side Diff: src/x64/stub-cache-x64.cc

Issue 8332003: Handlify CallStubCompiler::CompileCallField. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rename some functions on ARM. Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« src/arm/stub-cache-arm.cc ('K') | « src/x64/code-stubs-x64.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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,
ulan 2011/10/24 16:28:25 Indentation is broken.
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
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
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 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 } 851 }
802 852
803 // Return the value (register rax). 853 // Return the value (register rax).
804 __ ret(0); 854 __ ret(0);
805 } 855 }
806 856
807 857
808 // Generate code to check that a global property cell is empty. Create 858 // 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 859 // the property cell at compilation time if no cell exists for the
810 // property. 860 // property.
811 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCell( 861 static void GenerateCheckPropertyCell(MacroAssembler* masm,
862 Handle<GlobalObject> global,
863 Handle<String> name,
864 Register scratch,
865 Label* miss) {
866 Handle<JSGlobalPropertyCell> cell =
867 GlobalObject::EnsurePropertyCell(global, name);
868 ASSERT(cell->value()->IsTheHole());
869 __ Move(scratch, cell);
870 __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset),
871 masm->isolate()->factory()->the_hole_value());
872 __ j(not_equal, miss);
873 }
874
875
876 // TODO(kmillikin): Eliminate this function when the stub cache is fully
877 // handlified.
878 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCell(
812 MacroAssembler* masm, 879 MacroAssembler* masm,
813 GlobalObject* global, 880 GlobalObject* global,
814 String* name, 881 String* name,
815 Register scratch, 882 Register scratch,
816 Label* miss) { 883 Label* miss) {
817 Object* probe; 884 Object* probe;
818 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); 885 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name);
819 if (!maybe_probe->ToObject(&probe)) return maybe_probe; 886 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
820 } 887 }
821 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); 888 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe);
822 ASSERT(cell->value()->IsTheHole()); 889 ASSERT(cell->value()->IsTheHole());
823 __ Move(scratch, Handle<Object>(cell)); 890 __ Move(scratch, Handle<Object>(cell));
824 __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), 891 __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset),
825 masm->isolate()->factory()->the_hole_value()); 892 masm->isolate()->factory()->the_hole_value());
826 __ j(not_equal, miss); 893 __ j(not_equal, miss);
827 return cell; 894 return cell;
828 } 895 }
829 896
830 897
898 // Calls GenerateCheckPropertyCell for each global object in the prototype chain
899 // from object to (but not including) holder.
900 static void GenerateCheckPropertyCells(MacroAssembler* masm,
901 Handle<JSObject> object,
902 Handle<JSObject> holder,
903 Handle<String> name,
904 Register scratch,
905 Label* miss) {
906 Handle<JSObject> current = object;
907 while (!current.is_identical_to(holder)) {
908 if (current->IsGlobalObject()) {
909 GenerateCheckPropertyCell(masm,
910 Handle<GlobalObject>::cast(current),
911 name,
912 scratch,
913 miss);
914 }
915 current = Handle<JSObject>(JSObject::cast(current->GetPrototype()));
916 }
917 }
918
919
920 // TODO(kmillikin): Eliminate this function when the stub cache is fully
921 // handlified.
922 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCells(
923 MacroAssembler* masm,
924 JSObject* object,
925 JSObject* holder,
926 String* name,
927 Register scratch,
928 Label* miss) {
929 JSObject* current = object;
930 while (current != holder) {
931 if (current->IsGlobalObject()) {
932 // Returns a cell or a failure.
933 MaybeObject* result = TryGenerateCheckPropertyCell(
934 masm,
935 GlobalObject::cast(current),
936 name,
937 scratch,
938 miss);
939 if (result->IsFailure()) return result;
940 }
941 ASSERT(current->IsJSObject());
942 current = JSObject::cast(current->GetPrototype());
943 }
944 return NULL;
945 }
946
947
831 #undef __ 948 #undef __
832 #define __ ACCESS_MASM((masm())) 949 #define __ ACCESS_MASM((masm()))
833 950
834 951
952 Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
953 Register object_reg,
954 Handle<JSObject> holder,
955 Register holder_reg,
956 Register scratch1,
957 Register scratch2,
958 Handle<String> name,
959 int save_at_depth,
960 Label* miss) {
961 // Make sure there's no overlap between holder and object registers.
962 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
963 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
964 && !scratch2.is(scratch1));
965
966 // Keep track of the current object in register reg. On the first
967 // iteration, reg is an alias for object_reg, on later iterations,
968 // it is an alias for holder_reg.
969 Register reg = object_reg;
970 int depth = 0;
971
972 if (save_at_depth == depth) {
973 __ movq(Operand(rsp, kPointerSize), object_reg);
974 }
975
976 // Check the maps in the prototype chain.
977 // Traverse the prototype chain from the object and do map checks.
978 Handle<JSObject> current = object;
979 while (!current.is_identical_to(holder)) {
980 ++depth;
981
982 // Only global objects and objects that do not require access
983 // checks are allowed in stubs.
984 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded());
985
986 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype()));
987 if (!current->HasFastProperties() &&
988 !current->IsJSGlobalObject() &&
989 !current->IsJSGlobalProxy()) {
990 if (!name->IsSymbol()) {
991 name = factory()->LookupSymbol(name);
992 }
993 ASSERT(current->property_dictionary()->FindEntry(*name) ==
994 StringDictionary::kNotFound);
995
996 GenerateDictionaryNegativeLookup(masm(), miss, reg, name,
997 scratch1, scratch2);
998
999 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
1000 reg = holder_reg; // From now on the object will be in holder_reg.
1001 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
1002 } else {
1003 bool in_new_space = heap()->InNewSpace(*prototype);
1004 Handle<Map> current_map(current->map());
1005 if (in_new_space) {
1006 // Save the map in scratch1 for later.
1007 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
1008 __ Cmp(scratch1, current_map);
1009 } else {
1010 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), current_map);
1011 }
1012 // Branch on the result of the map check.
1013 __ j(not_equal, miss);
1014 // Check access rights to the global object. This has to happen after
1015 // the map check so that we know that the object is actually a global
1016 // object.
1017 if (current->IsJSGlobalProxy()) {
1018 __ CheckAccessGlobalProxy(reg, scratch2, miss);
1019 }
1020 reg = holder_reg; // From now on the object will be in holder_reg.
1021
1022 if (in_new_space) {
1023 // The prototype is in new space; we cannot store a reference to it
1024 // in the code. Load it from the map.
1025 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
1026 } else {
1027 // The prototype is in old space; load it directly.
1028 __ Move(reg, prototype);
1029 }
1030 }
1031
1032 if (save_at_depth == depth) {
1033 __ movq(Operand(rsp, kPointerSize), reg);
1034 }
1035
1036 // Go to the next object in the prototype chain.
1037 current = prototype;
1038 }
1039 ASSERT(current.is_identical_to(holder));
1040
1041 // Log the check depth.
1042 LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
1043
1044 // Check the holder map.
1045 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), Handle<Map>(holder->map()));
1046 __ j(not_equal, miss);
1047
1048 // Perform security check for access to the global object.
1049 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded());
1050 if (current->IsJSGlobalProxy()) {
1051 __ CheckAccessGlobalProxy(reg, scratch1, miss);
1052 }
1053
1054 // If we've skipped any global objects, it's not enough to verify that
1055 // their maps haven't changed. We also need to check that the property
1056 // cell for the property is still empty.
1057 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss);
1058
1059 // Return the register containing the holder.
1060 return reg;
1061 }
1062
1063
835 Register StubCompiler::CheckPrototypes(JSObject* object, 1064 Register StubCompiler::CheckPrototypes(JSObject* object,
836 Register object_reg, 1065 Register object_reg,
837 JSObject* holder, 1066 JSObject* holder,
838 Register holder_reg, 1067 Register holder_reg,
839 Register scratch1, 1068 Register scratch1,
840 Register scratch2, 1069 Register scratch2,
841 String* name, 1070 String* name,
842 int save_at_depth, 1071 int save_at_depth,
843 Label* miss) { 1072 Label* miss) {
844 // Make sure there's no overlap between holder and object registers. 1073 // Make sure there's no overlap between holder and object registers.
(...skipping 30 matching lines...) Expand all
875 if (lookup_result->IsFailure()) { 1104 if (lookup_result->IsFailure()) {
876 set_failure(Failure::cast(lookup_result)); 1105 set_failure(Failure::cast(lookup_result));
877 return reg; 1106 return reg;
878 } else { 1107 } else {
879 name = String::cast(lookup_result->ToObjectUnchecked()); 1108 name = String::cast(lookup_result->ToObjectUnchecked());
880 } 1109 }
881 } 1110 }
882 ASSERT(current->property_dictionary()->FindEntry(name) == 1111 ASSERT(current->property_dictionary()->FindEntry(name) ==
883 StringDictionary::kNotFound); 1112 StringDictionary::kNotFound);
884 1113
885 MaybeObject* negative_lookup = GenerateDictionaryNegativeLookup(masm(), 1114 MaybeObject* negative_lookup =
886 miss, 1115 TryGenerateDictionaryNegativeLookup(masm(),
887 reg, 1116 miss,
888 name, 1117 reg,
889 scratch1, 1118 name,
890 scratch2); 1119 scratch1,
1120 scratch2);
891 if (negative_lookup->IsFailure()) { 1121 if (negative_lookup->IsFailure()) {
892 set_failure(Failure::cast(negative_lookup)); 1122 set_failure(Failure::cast(negative_lookup));
893 return reg; 1123 return reg;
894 } 1124 }
895 1125
896 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 1126 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
897 reg = holder_reg; // from now the object is in holder_reg 1127 reg = holder_reg; // from now the object is in holder_reg
898 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 1128 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
899 } else if (heap()->InNewSpace(prototype)) { 1129 } else if (heap()->InNewSpace(prototype)) {
900 // Get the map of the current object. 1130 // Get the map of the current object.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
953 // the holder register. 1183 // the holder register.
954 ASSERT(current == holder); 1184 ASSERT(current == holder);
955 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); 1185 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded());
956 if (current->IsJSGlobalProxy()) { 1186 if (current->IsJSGlobalProxy()) {
957 __ CheckAccessGlobalProxy(reg, scratch1, miss); 1187 __ CheckAccessGlobalProxy(reg, scratch1, miss);
958 } 1188 }
959 1189
960 // If we've skipped any global objects, it's not enough to verify 1190 // 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 1191 // that their maps haven't changed. We also need to check that the
962 // property cell for the property is still empty. 1192 // property cell for the property is still empty.
963 current = object; 1193 MaybeObject* result = TryGenerateCheckPropertyCells(masm(),
964 while (current != holder) { 1194 object,
965 if (current->IsGlobalObject()) { 1195 holder,
966 MaybeObject* cell = GenerateCheckPropertyCell(masm(), 1196 name,
967 GlobalObject::cast(current), 1197 scratch1,
968 name, 1198 miss);
969 scratch1, 1199 if (result->IsFailure()) set_failure(Failure::cast(result));
ulan 2011/10/24 16:28:25 The result can be NULL. It works but looks suspici
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 1200
979 // Return the register containing the holder. 1201 // Return the register containing the holder.
980 return reg; 1202 return reg;
981 } 1203 }
982 1204
983 1205
984 void StubCompiler::GenerateLoadField(JSObject* object, 1206 void StubCompiler::GenerateLoadField(JSObject* object,
985 JSObject* holder, 1207 JSObject* holder,
986 Register receiver, 1208 Register receiver,
987 Register scratch1, 1209 Register scratch1,
988 Register scratch2, 1210 Register scratch2,
989 Register scratch3, 1211 Register scratch3,
990 int index, 1212 int index,
991 String* name, 1213 String* name,
992 Label* miss) { 1214 Label* miss) {
993 // Check that the receiver isn't a smi. 1215 // Check that the receiver isn't a smi.
994 __ JumpIfSmi(receiver, miss); 1216 __ JumpIfSmi(receiver, miss);
995 1217
996 // Check the prototype chain. 1218 // Check the prototype chain.
997 Register reg = 1219 Register reg =
998 CheckPrototypes(object, receiver, holder, 1220 CheckPrototypes(object, receiver, holder,
999 scratch1, scratch2, scratch3, name, miss); 1221 scratch1, scratch2, scratch3, name, miss);
1000 1222
1001 // Get the value from the properties. 1223 // Get the value from the properties.
1002 GenerateFastPropertyLoad(masm(), rax, reg, holder, index); 1224 GenerateFastPropertyLoad(masm(), rax, reg, Handle<JSObject>(holder), index);
1003 __ ret(0); 1225 __ ret(0);
1004 } 1226 }
1005 1227
1006 1228
1007 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, 1229 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object,
1008 JSObject* holder, 1230 JSObject* holder,
1009 Register receiver, 1231 Register receiver,
1010 Register name_reg, 1232 Register name_reg,
1011 Register scratch1, 1233 Register scratch1,
1012 Register scratch2, 1234 Register scratch2,
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 scratch2, 1413 scratch2,
1192 scratch3, 1414 scratch3,
1193 name, 1415 name,
1194 miss); 1416 miss);
1195 } 1417 }
1196 1418
1197 if (lookup->type() == FIELD) { 1419 if (lookup->type() == FIELD) {
1198 // We found FIELD property in prototype chain of interceptor's holder. 1420 // We found FIELD property in prototype chain of interceptor's holder.
1199 // Retrieve a field from field's holder. 1421 // Retrieve a field from field's holder.
1200 GenerateFastPropertyLoad(masm(), rax, holder_reg, 1422 GenerateFastPropertyLoad(masm(), rax, holder_reg,
1201 lookup->holder(), lookup->GetFieldIndex()); 1423 Handle<JSObject>(lookup->holder()),
1424 lookup->GetFieldIndex());
1202 __ ret(0); 1425 __ ret(0);
1203 } else { 1426 } else {
1204 // We found CALLBACKS property in prototype chain of interceptor's 1427 // We found CALLBACKS property in prototype chain of interceptor's
1205 // holder. 1428 // holder.
1206 ASSERT(lookup->type() == CALLBACKS); 1429 ASSERT(lookup->type() == CALLBACKS);
1207 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); 1430 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo());
1208 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); 1431 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject());
1209 ASSERT(callback != NULL); 1432 ASSERT(callback != NULL);
1210 ASSERT(callback->getter() != NULL); 1433 ASSERT(callback->getter() != NULL);
1211 1434
(...skipping 25 matching lines...) Expand all
1237 name_reg, interceptor_holder); 1460 name_reg, interceptor_holder);
1238 __ push(scratch2); // restore old return address 1461 __ push(scratch2); // restore old return address
1239 1462
1240 ExternalReference ref = ExternalReference( 1463 ExternalReference ref = ExternalReference(
1241 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate()); 1464 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate());
1242 __ TailCallExternalReference(ref, 5, 1); 1465 __ TailCallExternalReference(ref, 5, 1);
1243 } 1466 }
1244 } 1467 }
1245 1468
1246 1469
1247 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { 1470 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) {
1248 if (kind_ == Code::KEYED_CALL_IC) { 1471 if (kind_ == Code::KEYED_CALL_IC) {
1249 __ Cmp(rcx, Handle<String>(name)); 1472 __ Cmp(rcx, name);
1250 __ j(not_equal, miss); 1473 __ j(not_equal, miss);
1251 } 1474 }
1252 } 1475 }
1253 1476
1254 1477
1255 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, 1478 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object,
1256 JSObject* holder, 1479 JSObject* holder,
1257 String* name, 1480 String* name,
1258 Label* miss) { 1481 Label* miss) {
1259 ASSERT(holder->IsGlobalObject()); 1482 ASSERT(holder->IsGlobalObject());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1298 __ Move(rax, Handle<SharedFunctionInfo>(function->shared())); 1521 __ Move(rax, Handle<SharedFunctionInfo>(function->shared()));
1299 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax); 1522 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax);
1300 __ j(not_equal, miss); 1523 __ j(not_equal, miss);
1301 } else { 1524 } else {
1302 __ Cmp(rdi, Handle<JSFunction>(function)); 1525 __ Cmp(rdi, Handle<JSFunction>(function));
1303 __ j(not_equal, miss); 1526 __ j(not_equal, miss);
1304 } 1527 }
1305 } 1528 }
1306 1529
1307 1530
1308 MaybeObject* CallStubCompiler::GenerateMissBranch() { 1531 void CallStubCompiler::GenerateMissBranch() {
1532 Handle<Code> code =
1533 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(),
1534 kind_,
1535 extra_state_);
1536 __ Jump(code, RelocInfo::CODE_TARGET);
1537 }
1538
1539
1540 // TODO(kmillikin): Eliminate this function when the stub cache is fully
1541 // handlified.
1542 MaybeObject* CallStubCompiler::TryGenerateMissBranch() {
1309 MaybeObject* maybe_obj = 1543 MaybeObject* maybe_obj =
1310 isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(), 1544 isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(),
1311 kind_, 1545 kind_,
1312 extra_state_); 1546 extra_state_);
1313 Object* obj; 1547 Object* obj;
1314 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1548 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1315 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); 1549 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET);
1316 return obj; 1550 return obj;
1317 } 1551 }
1318 1552
1319 1553
1320 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object, 1554 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
1321 JSObject* holder, 1555 Handle<JSObject> holder,
1322 int index, 1556 int index,
1323 String* name) { 1557 Handle<String> name) {
1324 // ----------- S t a t e ------------- 1558 // ----------- S t a t e -------------
1325 // rcx : function name 1559 // rcx : function name
1326 // rsp[0] : return address 1560 // rsp[0] : return address
1327 // rsp[8] : argument argc 1561 // rsp[8] : argument argc
1328 // rsp[16] : argument argc - 1 1562 // rsp[16] : argument argc - 1
1329 // ... 1563 // ...
1330 // rsp[argc * 8] : argument 1 1564 // rsp[argc * 8] : argument 1
1331 // rsp[(argc + 1) * 8] : argument 0 = receiver 1565 // rsp[(argc + 1) * 8] : argument 0 = receiver
1332 // ----------------------------------- 1566 // -----------------------------------
1333 Label miss; 1567 Label miss;
(...skipping 26 matching lines...) Expand all
1360 } 1594 }
1361 1595
1362 // Invoke the function. 1596 // Invoke the function.
1363 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 1597 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
1364 ? CALL_AS_FUNCTION 1598 ? CALL_AS_FUNCTION
1365 : CALL_AS_METHOD; 1599 : CALL_AS_METHOD;
1366 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, 1600 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
1367 NullCallWrapper(), call_kind); 1601 NullCallWrapper(), call_kind);
1368 1602
1369 // Handle call cache miss. 1603 // Handle call cache miss.
1370 __ bind(&miss); 1604 __ bind(&miss);GenerateMissBranch();
ulan 2011/10/24 16:28:25 New line between statements.
1371 MaybeObject* maybe_result = GenerateMissBranch();
1372 if (maybe_result->IsFailure()) return maybe_result;
1373 1605
1374 // Return the generated code. 1606 // Return the generated code.
1375 return GetCode(FIELD, name); 1607 return GetCode(FIELD, name);
1376 } 1608 }
1377 1609
1378 1610
1379 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, 1611 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object,
1380 JSObject* holder, 1612 JSObject* holder,
1381 JSGlobalPropertyCell* cell, 1613 JSGlobalPropertyCell* cell,
1382 JSFunction* function, 1614 JSFunction* function,
1383 String* name) { 1615 String* name) {
1384 // ----------- S t a t e ------------- 1616 // ----------- S t a t e -------------
1385 // -- rcx : name 1617 // -- rcx : name
1386 // -- rsp[0] : return address 1618 // -- rsp[0] : return address
1387 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 1619 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
1388 // -- ... 1620 // -- ...
1389 // -- rsp[(argc + 1) * 8] : receiver 1621 // -- rsp[(argc + 1) * 8] : receiver
1390 // ----------------------------------- 1622 // -----------------------------------
1391 1623
1392 // If object is not an array, bail out to regular call. 1624 // If object is not an array, bail out to regular call.
1393 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); 1625 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value();
1394 1626
1395 Label miss; 1627 Label miss;
1396 1628
1397 GenerateNameCheck(name, &miss); 1629 GenerateNameCheck(Handle<String>(name), &miss);
1398 1630
1399 // Get the receiver from the stack. 1631 // Get the receiver from the stack.
1400 const int argc = arguments().immediate(); 1632 const int argc = arguments().immediate();
1401 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 1633 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
1402 1634
1403 // Check that the receiver isn't a smi. 1635 // Check that the receiver isn't a smi.
1404 __ JumpIfSmi(rdx, &miss); 1636 __ JumpIfSmi(rdx, &miss);
1405 1637
1406 CheckPrototypes(JSObject::cast(object), 1638 CheckPrototypes(JSObject::cast(object),
1407 rdx, 1639 rdx,
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1546 } 1778 }
1547 1779
1548 __ bind(&call_builtin); 1780 __ bind(&call_builtin);
1549 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, 1781 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush,
1550 isolate()), 1782 isolate()),
1551 argc + 1, 1783 argc + 1,
1552 1); 1784 1);
1553 } 1785 }
1554 1786
1555 __ bind(&miss); 1787 __ bind(&miss);
1556 MaybeObject* maybe_result = GenerateMissBranch(); 1788 MaybeObject* maybe_result = TryGenerateMissBranch();
1557 if (maybe_result->IsFailure()) return maybe_result; 1789 if (maybe_result->IsFailure()) return maybe_result;
1558 1790
1559 // Return the generated code. 1791 // Return the generated code.
1560 return GetCode(function); 1792 return TryGetCode(function);
1561 } 1793 }
1562 1794
1563 1795
1564 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, 1796 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object,
1565 JSObject* holder, 1797 JSObject* holder,
1566 JSGlobalPropertyCell* cell, 1798 JSGlobalPropertyCell* cell,
1567 JSFunction* function, 1799 JSFunction* function,
1568 String* name) { 1800 String* name) {
1569 // ----------- S t a t e ------------- 1801 // ----------- S t a t e -------------
1570 // -- rcx : name 1802 // -- rcx : name
1571 // -- rsp[0] : return address 1803 // -- rsp[0] : return address
1572 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 1804 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
1573 // -- ... 1805 // -- ...
1574 // -- rsp[(argc + 1) * 8] : receiver 1806 // -- rsp[(argc + 1) * 8] : receiver
1575 // ----------------------------------- 1807 // -----------------------------------
1576 1808
1577 // If object is not an array, bail out to regular call. 1809 // If object is not an array, bail out to regular call.
1578 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); 1810 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value();
1579 1811
1580 Label miss, return_undefined, call_builtin; 1812 Label miss, return_undefined, call_builtin;
1581 1813
1582 GenerateNameCheck(name, &miss); 1814 GenerateNameCheck(Handle<String>(name), &miss);
1583 1815
1584 // Get the receiver from the stack. 1816 // Get the receiver from the stack.
1585 const int argc = arguments().immediate(); 1817 const int argc = arguments().immediate();
1586 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 1818 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
1587 1819
1588 // Check that the receiver isn't a smi. 1820 // Check that the receiver isn't a smi.
1589 __ JumpIfSmi(rdx, &miss); 1821 __ JumpIfSmi(rdx, &miss);
1590 1822
1591 CheckPrototypes(JSObject::cast(object), rdx, 1823 CheckPrototypes(JSObject::cast(object), rdx,
1592 holder, rbx, 1824 holder, rbx,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1629 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 1861 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
1630 __ ret((argc + 1) * kPointerSize); 1862 __ ret((argc + 1) * kPointerSize);
1631 1863
1632 __ bind(&call_builtin); 1864 __ bind(&call_builtin);
1633 __ TailCallExternalReference( 1865 __ TailCallExternalReference(
1634 ExternalReference(Builtins::c_ArrayPop, isolate()), 1866 ExternalReference(Builtins::c_ArrayPop, isolate()),
1635 argc + 1, 1867 argc + 1,
1636 1); 1868 1);
1637 1869
1638 __ bind(&miss); 1870 __ bind(&miss);
1639 MaybeObject* maybe_result = GenerateMissBranch(); 1871 MaybeObject* maybe_result = TryGenerateMissBranch();
1640 if (maybe_result->IsFailure()) return maybe_result; 1872 if (maybe_result->IsFailure()) return maybe_result;
1641 1873
1642 // Return the generated code. 1874 // Return the generated code.
1643 return GetCode(function); 1875 return TryGetCode(function);
1644 } 1876 }
1645 1877
1646 1878
1647 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( 1879 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall(
1648 Object* object, 1880 Object* object,
1649 JSObject* holder, 1881 JSObject* holder,
1650 JSGlobalPropertyCell* cell, 1882 JSGlobalPropertyCell* cell,
1651 JSFunction* function, 1883 JSFunction* function,
1652 String* name) { 1884 String* name) {
1653 // ----------- S t a t e ------------- 1885 // ----------- S t a t e -------------
(...skipping 13 matching lines...) Expand all
1667 Label name_miss; 1899 Label name_miss;
1668 Label index_out_of_range; 1900 Label index_out_of_range;
1669 Label* index_out_of_range_label = &index_out_of_range; 1901 Label* index_out_of_range_label = &index_out_of_range;
1670 1902
1671 if (kind_ == Code::CALL_IC && 1903 if (kind_ == Code::CALL_IC &&
1672 (CallICBase::StringStubState::decode(extra_state_) == 1904 (CallICBase::StringStubState::decode(extra_state_) ==
1673 DEFAULT_STRING_STUB)) { 1905 DEFAULT_STRING_STUB)) {
1674 index_out_of_range_label = &miss; 1906 index_out_of_range_label = &miss;
1675 } 1907 }
1676 1908
1677 GenerateNameCheck(name, &name_miss); 1909 GenerateNameCheck(Handle<String>(name), &name_miss);
1678 1910
1679 // Check that the maps starting from the prototype haven't changed. 1911 // Check that the maps starting from the prototype haven't changed.
1680 GenerateDirectLoadGlobalFunctionPrototype(masm(), 1912 GenerateDirectLoadGlobalFunctionPrototype(masm(),
1681 Context::STRING_FUNCTION_INDEX, 1913 Context::STRING_FUNCTION_INDEX,
1682 rax, 1914 rax,
1683 &miss); 1915 &miss);
1684 ASSERT(object != holder); 1916 ASSERT(object != holder);
1685 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, 1917 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
1686 rbx, rdx, rdi, name, &miss); 1918 rbx, rdx, rdi, name, &miss);
1687 1919
(...skipping 25 matching lines...) Expand all
1713 if (index_out_of_range.is_linked()) { 1945 if (index_out_of_range.is_linked()) {
1714 __ bind(&index_out_of_range); 1946 __ bind(&index_out_of_range);
1715 __ LoadRoot(rax, Heap::kNanValueRootIndex); 1947 __ LoadRoot(rax, Heap::kNanValueRootIndex);
1716 __ ret((argc + 1) * kPointerSize); 1948 __ ret((argc + 1) * kPointerSize);
1717 } 1949 }
1718 1950
1719 __ bind(&miss); 1951 __ bind(&miss);
1720 // Restore function name in rcx. 1952 // Restore function name in rcx.
1721 __ Move(rcx, Handle<String>(name)); 1953 __ Move(rcx, Handle<String>(name));
1722 __ bind(&name_miss); 1954 __ bind(&name_miss);
1723 MaybeObject* maybe_result = GenerateMissBranch(); 1955 MaybeObject* maybe_result = TryGenerateMissBranch();
1724 if (maybe_result->IsFailure()) return maybe_result; 1956 if (maybe_result->IsFailure()) return maybe_result;
1725 1957
1726 // Return the generated code. 1958 // Return the generated code.
1727 return GetCode(function); 1959 return TryGetCode(function);
1728 } 1960 }
1729 1961
1730 1962
1731 MaybeObject* CallStubCompiler::CompileStringCharAtCall( 1963 MaybeObject* CallStubCompiler::CompileStringCharAtCall(
1732 Object* object, 1964 Object* object,
1733 JSObject* holder, 1965 JSObject* holder,
1734 JSGlobalPropertyCell* cell, 1966 JSGlobalPropertyCell* cell,
1735 JSFunction* function, 1967 JSFunction* function,
1736 String* name) { 1968 String* name) {
1737 // ----------- S t a t e ------------- 1969 // ----------- S t a t e -------------
(...skipping 13 matching lines...) Expand all
1751 Label name_miss; 1983 Label name_miss;
1752 Label index_out_of_range; 1984 Label index_out_of_range;
1753 Label* index_out_of_range_label = &index_out_of_range; 1985 Label* index_out_of_range_label = &index_out_of_range;
1754 1986
1755 if (kind_ == Code::CALL_IC && 1987 if (kind_ == Code::CALL_IC &&
1756 (CallICBase::StringStubState::decode(extra_state_) == 1988 (CallICBase::StringStubState::decode(extra_state_) ==
1757 DEFAULT_STRING_STUB)) { 1989 DEFAULT_STRING_STUB)) {
1758 index_out_of_range_label = &miss; 1990 index_out_of_range_label = &miss;
1759 } 1991 }
1760 1992
1761 GenerateNameCheck(name, &name_miss); 1993 GenerateNameCheck(Handle<String>(name), &name_miss);
1762 1994
1763 // Check that the maps starting from the prototype haven't changed. 1995 // Check that the maps starting from the prototype haven't changed.
1764 GenerateDirectLoadGlobalFunctionPrototype(masm(), 1996 GenerateDirectLoadGlobalFunctionPrototype(masm(),
1765 Context::STRING_FUNCTION_INDEX, 1997 Context::STRING_FUNCTION_INDEX,
1766 rax, 1998 rax,
1767 &miss); 1999 &miss);
1768 ASSERT(object != holder); 2000 ASSERT(object != holder);
1769 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, 2001 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
1770 rbx, rdx, rdi, name, &miss); 2002 rbx, rdx, rdi, name, &miss);
1771 2003
(...skipping 27 matching lines...) Expand all
1799 if (index_out_of_range.is_linked()) { 2031 if (index_out_of_range.is_linked()) {
1800 __ bind(&index_out_of_range); 2032 __ bind(&index_out_of_range);
1801 __ LoadRoot(rax, Heap::kEmptyStringRootIndex); 2033 __ LoadRoot(rax, Heap::kEmptyStringRootIndex);
1802 __ ret((argc + 1) * kPointerSize); 2034 __ ret((argc + 1) * kPointerSize);
1803 } 2035 }
1804 2036
1805 __ bind(&miss); 2037 __ bind(&miss);
1806 // Restore function name in rcx. 2038 // Restore function name in rcx.
1807 __ Move(rcx, Handle<String>(name)); 2039 __ Move(rcx, Handle<String>(name));
1808 __ bind(&name_miss); 2040 __ bind(&name_miss);
1809 MaybeObject* maybe_result = GenerateMissBranch(); 2041 MaybeObject* maybe_result = TryGenerateMissBranch();
1810 if (maybe_result->IsFailure()) return maybe_result; 2042 if (maybe_result->IsFailure()) return maybe_result;
1811 2043
1812 // Return the generated code. 2044 // Return the generated code.
1813 return GetCode(function); 2045 return TryGetCode(function);
1814 } 2046 }
1815 2047
1816 2048
1817 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( 2049 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall(
1818 Object* object, 2050 Object* object,
1819 JSObject* holder, 2051 JSObject* holder,
1820 JSGlobalPropertyCell* cell, 2052 JSGlobalPropertyCell* cell,
1821 JSFunction* function, 2053 JSFunction* function,
1822 String* name) { 2054 String* name) {
1823 // ----------- S t a t e ------------- 2055 // ----------- S t a t e -------------
1824 // -- rcx : function name 2056 // -- rcx : function name
1825 // -- rsp[0] : return address 2057 // -- rsp[0] : return address
1826 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 2058 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
1827 // -- ... 2059 // -- ...
1828 // -- rsp[(argc + 1) * 8] : receiver 2060 // -- rsp[(argc + 1) * 8] : receiver
1829 // ----------------------------------- 2061 // -----------------------------------
1830 2062
1831 const int argc = arguments().immediate(); 2063 const int argc = arguments().immediate();
1832 2064
1833 // If the object is not a JSObject or we got an unexpected number of 2065 // If the object is not a JSObject or we got an unexpected number of
1834 // arguments, bail out to the regular call. 2066 // arguments, bail out to the regular call.
1835 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); 2067 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value();
1836 2068
1837 Label miss; 2069 Label miss;
1838 GenerateNameCheck(name, &miss); 2070 GenerateNameCheck(Handle<String>(name), &miss);
1839 2071
1840 if (cell == NULL) { 2072 if (cell == NULL) {
1841 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); 2073 __ movq(rdx, Operand(rsp, 2 * kPointerSize));
1842 2074
1843 __ JumpIfSmi(rdx, &miss); 2075 __ JumpIfSmi(rdx, &miss);
1844 2076
1845 CheckPrototypes(JSObject::cast(object), rdx, holder, rbx, rax, rdi, name, 2077 CheckPrototypes(JSObject::cast(object), rdx, holder, rbx, rax, rdi, name,
1846 &miss); 2078 &miss);
1847 } else { 2079 } else {
1848 ASSERT(cell->value() == function); 2080 ASSERT(cell->value() == function);
(...skipping 23 matching lines...) Expand all
1872 // because the function makes no use of it. 2104 // because the function makes no use of it.
1873 __ bind(&slow); 2105 __ bind(&slow);
1874 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2106 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
1875 ? CALL_AS_FUNCTION 2107 ? CALL_AS_FUNCTION
1876 : CALL_AS_METHOD; 2108 : CALL_AS_METHOD;
1877 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, 2109 __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
1878 NullCallWrapper(), call_kind); 2110 NullCallWrapper(), call_kind);
1879 2111
1880 __ bind(&miss); 2112 __ bind(&miss);
1881 // rcx: function name. 2113 // rcx: function name.
1882 MaybeObject* maybe_result = GenerateMissBranch(); 2114 MaybeObject* maybe_result = TryGenerateMissBranch();
1883 if (maybe_result->IsFailure()) return maybe_result; 2115 if (maybe_result->IsFailure()) return maybe_result;
1884 2116
1885 // Return the generated code. 2117 // Return the generated code.
1886 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); 2118 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name);
1887 } 2119 }
1888 2120
1889 2121
1890 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, 2122 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object,
1891 JSObject* holder, 2123 JSObject* holder,
1892 JSGlobalPropertyCell* cell, 2124 JSGlobalPropertyCell* cell,
1893 JSFunction* function, 2125 JSFunction* function,
1894 String* name) { 2126 String* name) {
1895 // TODO(872): implement this. 2127 // TODO(872): implement this.
1896 return heap()->undefined_value(); 2128 return heap()->undefined_value();
(...skipping 13 matching lines...) Expand all
1910 // -- rsp[(argc + 1) * 8] : receiver 2142 // -- rsp[(argc + 1) * 8] : receiver
1911 // ----------------------------------- 2143 // -----------------------------------
1912 2144
1913 const int argc = arguments().immediate(); 2145 const int argc = arguments().immediate();
1914 2146
1915 // If the object is not a JSObject or we got an unexpected number of 2147 // If the object is not a JSObject or we got an unexpected number of
1916 // arguments, bail out to the regular call. 2148 // arguments, bail out to the regular call.
1917 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); 2149 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value();
1918 2150
1919 Label miss; 2151 Label miss;
1920 GenerateNameCheck(name, &miss); 2152 GenerateNameCheck(Handle<String>(name), &miss);
1921 2153
1922 if (cell == NULL) { 2154 if (cell == NULL) {
1923 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); 2155 __ movq(rdx, Operand(rsp, 2 * kPointerSize));
1924 2156
1925 __ JumpIfSmi(rdx, &miss); 2157 __ JumpIfSmi(rdx, &miss);
1926 2158
1927 CheckPrototypes(JSObject::cast(object), rdx, holder, rbx, rax, rdi, name, 2159 CheckPrototypes(JSObject::cast(object), rdx, holder, rbx, rax, rdi, name,
1928 &miss); 2160 &miss);
1929 } else { 2161 } else {
1930 ASSERT(cell->value() == function); 2162 ASSERT(cell->value() == function);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1989 // because the function makes no use of it. 2221 // because the function makes no use of it.
1990 __ bind(&slow); 2222 __ bind(&slow);
1991 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2223 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
1992 ? CALL_AS_FUNCTION 2224 ? CALL_AS_FUNCTION
1993 : CALL_AS_METHOD; 2225 : CALL_AS_METHOD;
1994 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, 2226 __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
1995 NullCallWrapper(), call_kind); 2227 NullCallWrapper(), call_kind);
1996 2228
1997 __ bind(&miss); 2229 __ bind(&miss);
1998 // rcx: function name. 2230 // rcx: function name.
1999 MaybeObject* maybe_result = GenerateMissBranch(); 2231 MaybeObject* maybe_result = TryGenerateMissBranch();
2000 if (maybe_result->IsFailure()) return maybe_result; 2232 if (maybe_result->IsFailure()) return maybe_result;
2001 2233
2002 // Return the generated code. 2234 // Return the generated code.
2003 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); 2235 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name);
2004 } 2236 }
2005 2237
2006 2238
2007 MaybeObject* CallStubCompiler::CompileFastApiCall( 2239 MaybeObject* CallStubCompiler::CompileFastApiCall(
2008 const CallOptimization& optimization, 2240 const CallOptimization& optimization,
2009 Object* object, 2241 Object* object,
2010 JSObject* holder, 2242 JSObject* holder,
2011 JSGlobalPropertyCell* cell, 2243 JSGlobalPropertyCell* cell,
2012 JSFunction* function, 2244 JSFunction* function,
2013 String* name) { 2245 String* name) {
2014 ASSERT(optimization.is_simple_api_call()); 2246 ASSERT(optimization.is_simple_api_call());
2015 // Bail out if object is a global object as we don't want to 2247 // Bail out if object is a global object as we don't want to
2016 // repatch it to global receiver. 2248 // repatch it to global receiver.
2017 if (object->IsGlobalObject()) return heap()->undefined_value(); 2249 if (object->IsGlobalObject()) return heap()->undefined_value();
2018 if (cell != NULL) return heap()->undefined_value(); 2250 if (cell != NULL) return heap()->undefined_value();
2019 if (!object->IsJSObject()) return heap()->undefined_value(); 2251 if (!object->IsJSObject()) return heap()->undefined_value();
2020 int depth = optimization.GetPrototypeDepthOfExpectedType( 2252 int depth = optimization.GetPrototypeDepthOfExpectedType(
2021 JSObject::cast(object), holder); 2253 JSObject::cast(object), holder);
2022 if (depth == kInvalidProtoDepth) return heap()->undefined_value(); 2254 if (depth == kInvalidProtoDepth) return heap()->undefined_value();
2023 2255
2024 Label miss, miss_before_stack_reserved; 2256 Label miss, miss_before_stack_reserved;
2025 2257
2026 GenerateNameCheck(name, &miss_before_stack_reserved); 2258 GenerateNameCheck(Handle<String>(name), &miss_before_stack_reserved);
2027 2259
2028 // Get the receiver from the stack. 2260 // Get the receiver from the stack.
2029 const int argc = arguments().immediate(); 2261 const int argc = arguments().immediate();
2030 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 2262 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
2031 2263
2032 // Check that the receiver isn't a smi. 2264 // Check that the receiver isn't a smi.
2033 __ JumpIfSmi(rdx, &miss_before_stack_reserved); 2265 __ JumpIfSmi(rdx, &miss_before_stack_reserved);
2034 2266
2035 Counters* counters = isolate()->counters(); 2267 Counters* counters = isolate()->counters();
2036 __ IncrementCounter(counters->call_const(), 1); 2268 __ IncrementCounter(counters->call_const(), 1);
(...skipping 11 matching lines...) Expand all
2048 __ movq(rax, Operand(rsp, 3 * kPointerSize)); 2280 __ movq(rax, Operand(rsp, 3 * kPointerSize));
2049 __ movq(Operand(rsp, 0 * kPointerSize), rax); 2281 __ movq(Operand(rsp, 0 * kPointerSize), rax);
2050 2282
2051 MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc); 2283 MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc);
2052 if (result->IsFailure()) return result; 2284 if (result->IsFailure()) return result;
2053 2285
2054 __ bind(&miss); 2286 __ bind(&miss);
2055 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); 2287 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
2056 2288
2057 __ bind(&miss_before_stack_reserved); 2289 __ bind(&miss_before_stack_reserved);
2058 MaybeObject* maybe_result = GenerateMissBranch(); 2290 MaybeObject* maybe_result = TryGenerateMissBranch();
2059 if (maybe_result->IsFailure()) return maybe_result; 2291 if (maybe_result->IsFailure()) return maybe_result;
2060 2292
2061 // Return the generated code. 2293 // Return the generated code.
2062 return GetCode(function); 2294 return TryGetCode(function);
2063 } 2295 }
2064 2296
2065 2297
2066 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, 2298 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object,
2067 JSObject* holder, 2299 JSObject* holder,
2068 JSFunction* function, 2300 JSFunction* function,
2069 String* name, 2301 String* name,
2070 CheckType check) { 2302 CheckType check) {
2071 // ----------- S t a t e ------------- 2303 // ----------- S t a t e -------------
2072 // rcx : function name 2304 // rcx : function name
2073 // rsp[0] : return address 2305 // rsp[0] : return address
2074 // rsp[8] : argument argc 2306 // rsp[8] : argument argc
2075 // rsp[16] : argument argc - 1 2307 // rsp[16] : argument argc - 1
2076 // ... 2308 // ...
2077 // rsp[argc * 8] : argument 1 2309 // rsp[argc * 8] : argument 1
2078 // rsp[(argc + 1) * 8] : argument 0 = receiver 2310 // rsp[(argc + 1) * 8] : argument 0 = receiver
2079 // ----------------------------------- 2311 // -----------------------------------
2080 2312
2081 if (HasCustomCallGenerator(function)) { 2313 if (HasCustomCallGenerator(function)) {
2082 MaybeObject* maybe_result = CompileCustomCall( 2314 MaybeObject* maybe_result = CompileCustomCall(
2083 object, holder, NULL, function, name); 2315 object, holder, NULL, function, name);
2084 Object* result; 2316 Object* result;
2085 if (!maybe_result->ToObject(&result)) return maybe_result; 2317 if (!maybe_result->ToObject(&result)) return maybe_result;
2086 // undefined means bail out to regular compiler. 2318 // undefined means bail out to regular compiler.
2087 if (!result->IsUndefined()) return result; 2319 if (!result->IsUndefined()) return result;
2088 } 2320 }
2089 2321
2090 Label miss; 2322 Label miss;
2091 2323
2092 GenerateNameCheck(name, &miss); 2324 GenerateNameCheck(Handle<String>(name), &miss);
2093 2325
2094 // Get the receiver from the stack. 2326 // Get the receiver from the stack.
2095 const int argc = arguments().immediate(); 2327 const int argc = arguments().immediate();
2096 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 2328 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
2097 2329
2098 // Check that the receiver isn't a smi. 2330 // Check that the receiver isn't a smi.
2099 if (check != NUMBER_CHECK) { 2331 if (check != NUMBER_CHECK) {
2100 __ JumpIfSmi(rdx, &miss); 2332 __ JumpIfSmi(rdx, &miss);
2101 } 2333 }
2102 2334
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
2187 } 2419 }
2188 2420
2189 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2421 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2190 ? CALL_AS_FUNCTION 2422 ? CALL_AS_FUNCTION
2191 : CALL_AS_METHOD; 2423 : CALL_AS_METHOD;
2192 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, 2424 __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
2193 NullCallWrapper(), call_kind); 2425 NullCallWrapper(), call_kind);
2194 2426
2195 // Handle call cache miss. 2427 // Handle call cache miss.
2196 __ bind(&miss); 2428 __ bind(&miss);
2197 MaybeObject* maybe_result = GenerateMissBranch(); 2429 MaybeObject* maybe_result = TryGenerateMissBranch();
2198 if (maybe_result->IsFailure()) return maybe_result; 2430 if (maybe_result->IsFailure()) return maybe_result;
2199 2431
2200 // Return the generated code. 2432 // Return the generated code.
2201 return GetCode(function); 2433 return TryGetCode(function);
2202 } 2434 }
2203 2435
2204 2436
2205 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, 2437 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object,
2206 JSObject* holder, 2438 JSObject* holder,
2207 String* name) { 2439 String* name) {
2208 // ----------- S t a t e ------------- 2440 // ----------- S t a t e -------------
2209 // rcx : function name 2441 // rcx : function name
2210 // rsp[0] : return address 2442 // rsp[0] : return address
2211 // rsp[8] : argument argc 2443 // rsp[8] : argument argc
2212 // rsp[16] : argument argc - 1 2444 // rsp[16] : argument argc - 1
2213 // ... 2445 // ...
2214 // rsp[argc * 8] : argument 1 2446 // rsp[argc * 8] : argument 1
2215 // rsp[(argc + 1) * 8] : argument 0 = receiver 2447 // rsp[(argc + 1) * 8] : argument 0 = receiver
2216 // ----------------------------------- 2448 // -----------------------------------
2217 Label miss; 2449 Label miss;
2218 2450
2219 GenerateNameCheck(name, &miss); 2451 GenerateNameCheck(Handle<String>(name), &miss);
2220 2452
2221 // Get the number of arguments. 2453 // Get the number of arguments.
2222 const int argc = arguments().immediate(); 2454 const int argc = arguments().immediate();
2223 2455
2224 LookupResult lookup(isolate()); 2456 LookupResult lookup(isolate());
2225 LookupPostInterceptor(holder, name, &lookup); 2457 LookupPostInterceptor(holder, name, &lookup);
2226 2458
2227 // Get the receiver from the stack. 2459 // Get the receiver from the stack.
2228 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 2460 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
2229 2461
(...skipping 28 matching lines...) Expand all
2258 // Invoke the function. 2490 // Invoke the function.
2259 __ movq(rdi, rax); 2491 __ movq(rdi, rax);
2260 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2492 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2261 ? CALL_AS_FUNCTION 2493 ? CALL_AS_FUNCTION
2262 : CALL_AS_METHOD; 2494 : CALL_AS_METHOD;
2263 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, 2495 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
2264 NullCallWrapper(), call_kind); 2496 NullCallWrapper(), call_kind);
2265 2497
2266 // Handle load cache miss. 2498 // Handle load cache miss.
2267 __ bind(&miss); 2499 __ bind(&miss);
2268 MaybeObject* maybe_result = GenerateMissBranch(); 2500 MaybeObject* maybe_result = TryGenerateMissBranch();
2269 if (maybe_result->IsFailure()) return maybe_result; 2501 if (maybe_result->IsFailure()) return maybe_result;
2270 2502
2271 // Return the generated code. 2503 // Return the generated code.
2272 return GetCode(INTERCEPTOR, name); 2504 return TryGetCode(INTERCEPTOR, name);
2273 } 2505 }
2274 2506
2275 2507
2276 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, 2508 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object,
2277 GlobalObject* holder, 2509 GlobalObject* holder,
2278 JSGlobalPropertyCell* cell, 2510 JSGlobalPropertyCell* cell,
2279 JSFunction* function, 2511 JSFunction* function,
2280 String* name) { 2512 String* name) {
2281 // ----------- S t a t e ------------- 2513 // ----------- S t a t e -------------
2282 // rcx : function name 2514 // rcx : function name
2283 // rsp[0] : return address 2515 // rsp[0] : return address
2284 // rsp[8] : argument argc 2516 // rsp[8] : argument argc
2285 // rsp[16] : argument argc - 1 2517 // rsp[16] : argument argc - 1
2286 // ... 2518 // ...
2287 // rsp[argc * 8] : argument 1 2519 // rsp[argc * 8] : argument 1
2288 // rsp[(argc + 1) * 8] : argument 0 = receiver 2520 // rsp[(argc + 1) * 8] : argument 0 = receiver
2289 // ----------------------------------- 2521 // -----------------------------------
2290 2522
2291 if (HasCustomCallGenerator(function)) { 2523 if (HasCustomCallGenerator(function)) {
2292 MaybeObject* maybe_result = CompileCustomCall( 2524 MaybeObject* maybe_result = CompileCustomCall(
2293 object, holder, cell, function, name); 2525 object, holder, cell, function, name);
2294 Object* result; 2526 Object* result;
2295 if (!maybe_result->ToObject(&result)) return maybe_result; 2527 if (!maybe_result->ToObject(&result)) return maybe_result;
2296 // undefined means bail out to regular compiler. 2528 // undefined means bail out to regular compiler.
2297 if (!result->IsUndefined()) return result; 2529 if (!result->IsUndefined()) return result;
2298 } 2530 }
2299 2531
2300 Label miss; 2532 Label miss;
2301 2533
2302 GenerateNameCheck(name, &miss); 2534 GenerateNameCheck(Handle<String>(name), &miss);
2303 2535
2304 // Get the number of arguments. 2536 // Get the number of arguments.
2305 const int argc = arguments().immediate(); 2537 const int argc = arguments().immediate();
2306 2538
2307 GenerateGlobalReceiverCheck(object, holder, name, &miss); 2539 GenerateGlobalReceiverCheck(object, holder, name, &miss);
2308 2540
2309 GenerateLoadFunctionFromCell(cell, function, &miss); 2541 GenerateLoadFunctionFromCell(cell, function, &miss);
2310 2542
2311 // Patch the receiver on the stack with the global proxy. 2543 // Patch the receiver on the stack with the global proxy.
2312 if (object->IsGlobalObject()) { 2544 if (object->IsGlobalObject()) {
(...skipping 14 matching lines...) Expand all
2327 // We call indirectly through the code field in the function to 2559 // We call indirectly through the code field in the function to
2328 // allow recompilation to take effect without changing any of the 2560 // allow recompilation to take effect without changing any of the
2329 // call sites. 2561 // call sites.
2330 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 2562 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
2331 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION, 2563 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION,
2332 NullCallWrapper(), call_kind); 2564 NullCallWrapper(), call_kind);
2333 2565
2334 // Handle call cache miss. 2566 // Handle call cache miss.
2335 __ bind(&miss); 2567 __ bind(&miss);
2336 __ IncrementCounter(counters->call_global_inline_miss(), 1); 2568 __ IncrementCounter(counters->call_global_inline_miss(), 1);
2337 MaybeObject* maybe_result = GenerateMissBranch(); 2569 MaybeObject* maybe_result = TryGenerateMissBranch();
2338 if (maybe_result->IsFailure()) return maybe_result; 2570 if (maybe_result->IsFailure()) return maybe_result;
2339 2571
2340 // Return the generated code. 2572 // Return the generated code.
2341 return GetCode(NORMAL, name); 2573 return TryGetCode(NORMAL, name);
2342 } 2574 }
2343 2575
2344 2576
2345 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, 2577 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object,
2346 int index, 2578 int index,
2347 Map* transition, 2579 Map* transition,
2348 String* name) { 2580 String* name) {
2349 // ----------- S t a t e ------------- 2581 // ----------- S t a t e -------------
2350 // -- rax : value 2582 // -- rax : value
2351 // -- rcx : name 2583 // -- rcx : name
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
2651 __ JumpIfSmi(rax, &miss); 2883 __ JumpIfSmi(rax, &miss);
2652 2884
2653 // Check the maps of the full prototype chain. Also check that 2885 // Check the maps of the full prototype chain. Also check that
2654 // global property cells up to (but not including) the last object 2886 // global property cells up to (but not including) the last object
2655 // in the prototype chain are empty. 2887 // in the prototype chain are empty.
2656 CheckPrototypes(object, rax, last, rbx, rdx, rdi, name, &miss); 2888 CheckPrototypes(object, rax, last, rbx, rdx, rdi, name, &miss);
2657 2889
2658 // If the last object in the prototype chain is a global object, 2890 // If the last object in the prototype chain is a global object,
2659 // check that the global property cell is empty. 2891 // check that the global property cell is empty.
2660 if (last->IsGlobalObject()) { 2892 if (last->IsGlobalObject()) {
2661 MaybeObject* cell = GenerateCheckPropertyCell(masm(), 2893 MaybeObject* cell = TryGenerateCheckPropertyCell(masm(),
2662 GlobalObject::cast(last), 2894 GlobalObject::cast(last),
2663 name, 2895 name,
2664 rdx, 2896 rdx,
2665 &miss); 2897 &miss);
2666 if (cell->IsFailure()) { 2898 if (cell->IsFailure()) {
2667 miss.Unuse(); 2899 miss.Unuse();
2668 return cell; 2900 return cell;
2669 } 2901 }
2670 } 2902 }
2671 2903
2672 // Return undefined if maps of the full prototype chain are still the 2904 // Return undefined if maps of the full prototype chain are still the
2673 // same and no global property with this name contains a value. 2905 // same and no global property with this name contains a value.
2674 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 2906 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
2675 __ ret(0); 2907 __ ret(0);
(...skipping 1121 matching lines...) Expand 10 before | Expand all | Expand 10 after
3797 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); 4029 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
3798 __ jmp(ic_miss, RelocInfo::CODE_TARGET); 4030 __ jmp(ic_miss, RelocInfo::CODE_TARGET);
3799 } 4031 }
3800 4032
3801 4033
3802 #undef __ 4034 #undef __
3803 4035
3804 } } // namespace v8::internal 4036 } } // namespace v8::internal
3805 4037
3806 #endif // V8_TARGET_ARCH_X64 4038 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/arm/stub-cache-arm.cc ('K') | « src/x64/code-stubs-x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698