Chromium Code Reviews| 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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 88 // Miss: fall through. | 88 // Miss: fall through. |
| 89 __ bind(&miss); | 89 __ bind(&miss); |
| 90 } | 90 } |
| 91 | 91 |
| 92 | 92 |
| 93 // Helper function used to check that the dictionary doesn't contain | 93 // Helper function used to check that the dictionary doesn't contain |
| 94 // the property. This function may return false negatives, so miss_label | 94 // the property. This function may return false negatives, so miss_label |
| 95 // must always call a backup property check that is complete. | 95 // must always call a backup property check that is complete. |
| 96 // This function is safe to call if the receiver has fast properties. | 96 // This function is safe to call if the receiver has fast properties. |
| 97 // Name must be a symbol and receiver must be a heap object. | 97 // Name must be a symbol and receiver must be a heap object. |
| 98 MUST_USE_RESULT static MaybeObject* GenerateDictionaryNegativeLookup( | 98 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, |
| 99 Label* miss_label, | |
| 100 Register receiver, | |
| 101 Handle<String> name, | |
| 102 Register scratch0, | |
| 103 Register scratch1) { | |
| 104 ASSERT(name->IsSymbol()); | |
| 105 Counters* counters = masm->isolate()->counters(); | |
| 106 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); | |
| 107 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | |
| 108 | |
| 109 Label done; | |
| 110 | |
| 111 const int kInterceptorOrAccessCheckNeededMask = | |
| 112 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | |
| 113 | |
| 114 // Bail out if the receiver has a named interceptor or requires access checks. | |
| 115 Register map = scratch1; | |
| 116 __ ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); | |
| 117 __ ldrb(scratch0, FieldMemOperand(map, Map::kBitFieldOffset)); | |
| 118 __ tst(scratch0, Operand(kInterceptorOrAccessCheckNeededMask)); | |
| 119 __ b(ne, miss_label); | |
| 120 | |
| 121 // Check that receiver is a JSObject. | |
| 122 __ ldrb(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset)); | |
| 123 __ cmp(scratch0, Operand(FIRST_SPEC_OBJECT_TYPE)); | |
| 124 __ b(lt, miss_label); | |
| 125 | |
| 126 // Load properties array. | |
| 127 Register properties = scratch0; | |
| 128 __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | |
| 129 // Check that the properties array is a dictionary. | |
| 130 __ ldr(map, FieldMemOperand(properties, HeapObject::kMapOffset)); | |
| 131 Register tmp = properties; | |
| 132 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); | |
| 133 __ cmp(map, tmp); | |
| 134 __ b(ne, miss_label); | |
| 135 | |
| 136 // Restore the temporarily used register. | |
| 137 __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | |
| 138 | |
| 139 | |
| 140 StringDictionaryLookupStub::GenerateNegativeLookup(masm, | |
|
Kevin Millikin (Chromium)
2011/10/24 15:55:12
This is the only change from the original.
| |
| 141 miss_label, | |
| 142 &done, | |
| 143 receiver, | |
| 144 properties, | |
| 145 name, | |
| 146 scratch1); | |
| 147 __ bind(&done); | |
| 148 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | |
| 149 } | |
| 150 | |
| 151 | |
| 152 // TODO(kmillikin): Eliminate this function when the stub cache is fully | |
| 153 // handlified. | |
| 154 MUST_USE_RESULT static MaybeObject* TryGenerateDictionaryNegativeLookup( | |
| 99 MacroAssembler* masm, | 155 MacroAssembler* masm, |
| 100 Label* miss_label, | 156 Label* miss_label, |
| 101 Register receiver, | 157 Register receiver, |
| 102 String* name, | 158 String* name, |
| 103 Register scratch0, | 159 Register scratch0, |
| 104 Register scratch1) { | 160 Register scratch1) { |
| 105 ASSERT(name->IsSymbol()); | 161 ASSERT(name->IsSymbol()); |
| 106 Counters* counters = masm->isolate()->counters(); | 162 Counters* counters = masm->isolate()->counters(); |
| 107 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); | 163 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); |
| 108 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | 164 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 131 __ ldr(map, FieldMemOperand(properties, HeapObject::kMapOffset)); | 187 __ ldr(map, FieldMemOperand(properties, HeapObject::kMapOffset)); |
| 132 Register tmp = properties; | 188 Register tmp = properties; |
| 133 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); | 189 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); |
| 134 __ cmp(map, tmp); | 190 __ cmp(map, tmp); |
| 135 __ b(ne, miss_label); | 191 __ b(ne, miss_label); |
| 136 | 192 |
| 137 // Restore the temporarily used register. | 193 // Restore the temporarily used register. |
| 138 __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 194 __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
| 139 | 195 |
| 140 | 196 |
| 141 MaybeObject* result = StringDictionaryLookupStub::GenerateNegativeLookup( | 197 MaybeObject* result = StringDictionaryLookupStub::TryGenerateNegativeLookup( |
| 142 masm, | 198 masm, |
| 143 miss_label, | 199 miss_label, |
| 144 &done, | 200 &done, |
| 145 receiver, | 201 receiver, |
| 146 properties, | 202 properties, |
| 147 name, | 203 name, |
| 148 scratch1); | 204 scratch1); |
| 149 if (result->IsFailure()) return result; | 205 if (result->IsFailure()) return result; |
| 150 | 206 |
| 151 __ bind(&done); | 207 __ bind(&done); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 252 __ Move(prototype, Handle<Map>(function->initial_map())); | 308 __ Move(prototype, Handle<Map>(function->initial_map())); |
| 253 // Load the prototype from the initial map. | 309 // Load the prototype from the initial map. |
| 254 __ ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); | 310 __ ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); |
| 255 } | 311 } |
| 256 | 312 |
| 257 | 313 |
| 258 // Load a fast property out of a holder object (src). In-object properties | 314 // Load a fast property out of a holder object (src). In-object properties |
| 259 // are loaded directly otherwise the property is loaded from the properties | 315 // are loaded directly otherwise the property is loaded from the properties |
| 260 // fixed array. | 316 // fixed array. |
| 261 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, | 317 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, |
| 262 Register dst, Register src, | 318 Register dst, |
| 263 JSObject* holder, int index) { | 319 Register src, |
| 320 Handle<JSObject> holder, | |
| 321 int index) { | |
| 264 // Adjust for the number of properties stored in the holder. | 322 // Adjust for the number of properties stored in the holder. |
| 265 index -= holder->map()->inobject_properties(); | 323 index -= holder->map()->inobject_properties(); |
| 266 if (index < 0) { | 324 if (index < 0) { |
| 267 // Get the property straight out of the holder. | 325 // Get the property straight out of the holder. |
| 268 int offset = holder->map()->instance_size() + (index * kPointerSize); | 326 int offset = holder->map()->instance_size() + (index * kPointerSize); |
| 269 __ ldr(dst, FieldMemOperand(src, offset)); | 327 __ ldr(dst, FieldMemOperand(src, offset)); |
| 270 } else { | 328 } else { |
| 271 // Calculate the offset into the properties array. | 329 // Calculate the offset into the properties array. |
| 272 int offset = index * kPointerSize + FixedArray::kHeaderSize; | 330 int offset = index * kPointerSize + FixedArray::kHeaderSize; |
| 273 __ ldr(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); | 331 __ ldr(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 473 } else { | 531 } else { |
| 474 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss); | 532 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss); |
| 475 } | 533 } |
| 476 | 534 |
| 477 Handle<Code> ic(code); | 535 Handle<Code> ic(code); |
| 478 __ Jump(ic, RelocInfo::CODE_TARGET); | 536 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 479 } | 537 } |
| 480 | 538 |
| 481 | 539 |
| 482 static void GenerateCallFunction(MacroAssembler* masm, | 540 static void GenerateCallFunction(MacroAssembler* masm, |
| 483 Object* object, | 541 Handle<Object> object, |
| 484 const ParameterCount& arguments, | 542 const ParameterCount& arguments, |
| 485 Label* miss, | 543 Label* miss, |
| 486 Code::ExtraICState extra_ic_state) { | 544 Code::ExtraICState extra_ic_state) { |
| 487 // ----------- S t a t e ------------- | 545 // ----------- S t a t e ------------- |
| 488 // -- r0: receiver | 546 // -- r0: receiver |
| 489 // -- r1: function to call | 547 // -- r1: function to call |
| 490 // ----------------------------------- | 548 // ----------------------------------- |
| 491 | 549 |
| 492 // Check that the function really is a function. | 550 // Check that the function really is a function. |
| 493 __ JumpIfSmi(r1, miss); | 551 __ JumpIfSmi(r1, miss); |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 861 StubCompiler* stub_compiler_; | 919 StubCompiler* stub_compiler_; |
| 862 const ParameterCount& arguments_; | 920 const ParameterCount& arguments_; |
| 863 Register name_; | 921 Register name_; |
| 864 Code::ExtraICState extra_ic_state_; | 922 Code::ExtraICState extra_ic_state_; |
| 865 }; | 923 }; |
| 866 | 924 |
| 867 | 925 |
| 868 // Generate code to check that a global property cell is empty. Create | 926 // Generate code to check that a global property cell is empty. Create |
| 869 // the property cell at compilation time if no cell exists for the | 927 // the property cell at compilation time if no cell exists for the |
| 870 // property. | 928 // property. |
| 871 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCell( | 929 static void GenerateCheckPropertyCell(MacroAssembler* masm, |
| 930 Handle<GlobalObject> global, | |
| 931 Handle<String> name, | |
| 932 Register scratch, | |
| 933 Label* miss) { | |
| 934 Handle<JSGlobalPropertyCell> cell = | |
| 935 GlobalObject::EnsurePropertyCell(global, name); | |
| 936 ASSERT(cell->value()->IsTheHole()); | |
| 937 __ mov(scratch, Operand(cell)); | |
| 938 __ ldr(scratch, | |
| 939 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); | |
| 940 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | |
| 941 __ cmp(scratch, ip); | |
| 942 __ b(ne, miss); | |
| 943 } | |
| 944 | |
| 945 | |
| 946 // TODO(kmillikin): Eliminate this function when the stub cache is fully | |
| 947 // handlified. | |
| 948 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCell( | |
| 872 MacroAssembler* masm, | 949 MacroAssembler* masm, |
| 873 GlobalObject* global, | 950 GlobalObject* global, |
| 874 String* name, | 951 String* name, |
| 875 Register scratch, | 952 Register scratch, |
| 876 Label* miss) { | 953 Label* miss) { |
| 877 Object* probe; | 954 Object* probe; |
| 878 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); | 955 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); |
| 879 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 956 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
| 880 } | 957 } |
| 881 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); | 958 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); |
| 882 ASSERT(cell->value()->IsTheHole()); | 959 ASSERT(cell->value()->IsTheHole()); |
| 883 __ mov(scratch, Operand(Handle<Object>(cell))); | 960 __ mov(scratch, Operand(Handle<Object>(cell))); |
| 884 __ ldr(scratch, | 961 __ ldr(scratch, |
| 885 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); | 962 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); |
| 886 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 963 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
| 887 __ cmp(scratch, ip); | 964 __ cmp(scratch, ip); |
| 888 __ b(ne, miss); | 965 __ b(ne, miss); |
| 889 return cell; | 966 return cell; |
| 890 } | 967 } |
| 891 | 968 |
| 969 | |
| 892 // Calls GenerateCheckPropertyCell for each global object in the prototype chain | 970 // Calls GenerateCheckPropertyCell for each global object in the prototype chain |
| 893 // from object to (but not including) holder. | 971 // from object to (but not including) holder. |
| 894 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCells( | 972 static void GenerateCheckPropertyCells(MacroAssembler* masm, |
| 973 Handle<JSObject> object, | |
| 974 Handle<JSObject> holder, | |
| 975 Handle<String> name, | |
| 976 Register scratch, | |
| 977 Label* miss) { | |
| 978 Handle<JSObject> current = object; | |
| 979 while (!current.is_identical_to(holder)) { | |
| 980 if (current->IsGlobalObject()) { | |
| 981 GenerateCheckPropertyCell(masm, | |
| 982 Handle<GlobalObject>::cast(current), | |
| 983 name, | |
| 984 scratch, | |
| 985 miss); | |
| 986 } | |
| 987 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); | |
| 988 } | |
| 989 } | |
| 990 | |
| 991 | |
| 992 // TODO(kmillikin): Eliminate this function when the stub cache is fully | |
| 993 // handlified. | |
| 994 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCells( | |
| 895 MacroAssembler* masm, | 995 MacroAssembler* masm, |
| 896 JSObject* object, | 996 JSObject* object, |
| 897 JSObject* holder, | 997 JSObject* holder, |
| 898 String* name, | 998 String* name, |
| 899 Register scratch, | 999 Register scratch, |
| 900 Label* miss) { | 1000 Label* miss) { |
| 901 JSObject* current = object; | 1001 JSObject* current = object; |
| 902 while (current != holder) { | 1002 while (current != holder) { |
| 903 if (current->IsGlobalObject()) { | 1003 if (current->IsGlobalObject()) { |
| 904 // Returns a cell or a failure. | 1004 // Returns a cell or a failure. |
| 905 MaybeObject* result = GenerateCheckPropertyCell( | 1005 MaybeObject* result = TryGenerateCheckPropertyCell( |
| 906 masm, | 1006 masm, |
| 907 GlobalObject::cast(current), | 1007 GlobalObject::cast(current), |
| 908 name, | 1008 name, |
| 909 scratch, | 1009 scratch, |
| 910 miss); | 1010 miss); |
| 911 if (result->IsFailure()) return result; | 1011 if (result->IsFailure()) return result; |
| 912 } | 1012 } |
| 913 ASSERT(current->IsJSObject()); | 1013 ASSERT(current->IsJSObject()); |
| 914 current = JSObject::cast(current->GetPrototype()); | 1014 current = JSObject::cast(current->GetPrototype()); |
| 915 } | 1015 } |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1020 if (!(biased_exponent & 1)) { | 1120 if (!(biased_exponent & 1)) { |
| 1021 __ bic(hiword, hiword, Operand(1 << HeapNumber::kExponentShift)); | 1121 __ bic(hiword, hiword, Operand(1 << HeapNumber::kExponentShift)); |
| 1022 } | 1122 } |
| 1023 } | 1123 } |
| 1024 | 1124 |
| 1025 | 1125 |
| 1026 #undef __ | 1126 #undef __ |
| 1027 #define __ ACCESS_MASM(masm()) | 1127 #define __ ACCESS_MASM(masm()) |
| 1028 | 1128 |
| 1029 | 1129 |
| 1130 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, | |
| 1131 Register object_reg, | |
| 1132 Handle<JSObject> holder, | |
| 1133 Register holder_reg, | |
| 1134 Register scratch1, | |
| 1135 Register scratch2, | |
| 1136 Handle<String> name, | |
| 1137 int save_at_depth, | |
| 1138 Label* miss) { | |
| 1139 // Make sure there's no overlap between holder and object registers. | |
| 1140 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | |
| 1141 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | |
| 1142 && !scratch2.is(scratch1)); | |
| 1143 | |
| 1144 // Keep track of the current object in register reg. | |
| 1145 Register reg = object_reg; | |
| 1146 int depth = 0; | |
| 1147 | |
| 1148 if (save_at_depth == depth) { | |
| 1149 __ str(reg, MemOperand(sp)); | |
| 1150 } | |
| 1151 | |
| 1152 // Check the maps in the prototype chain. | |
| 1153 // Traverse the prototype chain from the object and do map checks. | |
| 1154 Handle<JSObject> current = object; | |
| 1155 while (!current.is_identical_to(holder)) { | |
| 1156 ++depth; | |
| 1157 | |
| 1158 // Only global objects and objects that do not require access | |
| 1159 // checks are allowed in stubs. | |
| 1160 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | |
| 1161 | |
| 1162 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); | |
| 1163 if (!current->HasFastProperties() && | |
| 1164 !current->IsJSGlobalObject() && | |
| 1165 !current->IsJSGlobalProxy()) { | |
| 1166 if (!name->IsSymbol()) { | |
| 1167 name = factory()->LookupSymbol(name); | |
| 1168 } | |
| 1169 ASSERT(current->property_dictionary()->FindEntry(*name) == | |
| 1170 StringDictionary::kNotFound); | |
| 1171 | |
| 1172 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, | |
| 1173 scratch1, scratch2); | |
| 1174 | |
| 1175 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | |
| 1176 reg = holder_reg; // From now on the object will be in holder_reg. | |
| 1177 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | |
| 1178 } else { | |
| 1179 Handle<Map> current_map(current->map()); | |
| 1180 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | |
| 1181 __ cmp(scratch1, Operand(current_map)); | |
| 1182 // Branch on the result of the map check. | |
| 1183 __ b(ne, miss); | |
| 1184 // Check access rights to the global object. This has to happen after | |
| 1185 // the map check so that we know that the object is actually a global | |
| 1186 // object. | |
| 1187 if (current->IsJSGlobalProxy()) { | |
| 1188 __ CheckAccessGlobalProxy(reg, scratch2, miss); | |
| 1189 } | |
| 1190 reg = holder_reg; // From now on the object will be in holder_reg. | |
| 1191 | |
| 1192 if (heap()->InNewSpace(*prototype)) { | |
| 1193 // The prototype is in new space; we cannot store a reference to it | |
| 1194 // in the code. Load it from the map. | |
| 1195 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | |
| 1196 } else { | |
| 1197 // The prototype is in old space; load it directly. | |
| 1198 __ mov(reg, Operand(prototype)); | |
| 1199 } | |
| 1200 } | |
| 1201 | |
| 1202 if (save_at_depth == depth) { | |
| 1203 __ str(reg, MemOperand(sp)); | |
| 1204 } | |
| 1205 | |
| 1206 // Go to the next object in the prototype chain. | |
| 1207 current = prototype; | |
| 1208 } | |
| 1209 | |
| 1210 // Log the check depth. | |
| 1211 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); | |
| 1212 | |
| 1213 // Check the holder map. | |
| 1214 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | |
| 1215 __ cmp(scratch1, Operand(Handle<Map>(current->map()))); | |
| 1216 __ b(ne, miss); | |
| 1217 | |
| 1218 // Perform security check for access to the global object. | |
| 1219 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | |
| 1220 if (holder->IsJSGlobalProxy()) { | |
| 1221 __ CheckAccessGlobalProxy(reg, scratch1, miss); | |
| 1222 } | |
| 1223 | |
| 1224 // If we've skipped any global objects, it's not enough to verify that | |
| 1225 // their maps haven't changed. We also need to check that the property | |
| 1226 // cell for the property is still empty. | |
| 1227 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); | |
| 1228 | |
| 1229 // Return the register containing the holder. | |
| 1230 return reg; | |
| 1231 } | |
| 1232 | |
| 1233 | |
| 1234 // TODO(kmillikin): Eliminate this function when the stub cache is fully | |
| 1235 // handlified. | |
| 1030 Register StubCompiler::CheckPrototypes(JSObject* object, | 1236 Register StubCompiler::CheckPrototypes(JSObject* object, |
| 1031 Register object_reg, | 1237 Register object_reg, |
| 1032 JSObject* holder, | 1238 JSObject* holder, |
| 1033 Register holder_reg, | 1239 Register holder_reg, |
| 1034 Register scratch1, | 1240 Register scratch1, |
| 1035 Register scratch2, | 1241 Register scratch2, |
| 1036 String* name, | 1242 String* name, |
| 1037 int save_at_depth, | 1243 int save_at_depth, |
| 1038 Label* miss) { | 1244 Label* miss) { |
| 1039 // Make sure there's no overlap between holder and object registers. | 1245 // Make sure there's no overlap between holder and object registers. |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 1069 Object* lookup_result = NULL; // Initialization to please compiler. | 1275 Object* lookup_result = NULL; // Initialization to please compiler. |
| 1070 if (!maybe_lookup_result->ToObject(&lookup_result)) { | 1276 if (!maybe_lookup_result->ToObject(&lookup_result)) { |
| 1071 set_failure(Failure::cast(maybe_lookup_result)); | 1277 set_failure(Failure::cast(maybe_lookup_result)); |
| 1072 return reg; | 1278 return reg; |
| 1073 } | 1279 } |
| 1074 name = String::cast(lookup_result); | 1280 name = String::cast(lookup_result); |
| 1075 } | 1281 } |
| 1076 ASSERT(current->property_dictionary()->FindEntry(name) == | 1282 ASSERT(current->property_dictionary()->FindEntry(name) == |
| 1077 StringDictionary::kNotFound); | 1283 StringDictionary::kNotFound); |
| 1078 | 1284 |
| 1079 MaybeObject* negative_lookup = GenerateDictionaryNegativeLookup(masm(), | 1285 MaybeObject* negative_lookup = |
| 1080 miss, | 1286 TryGenerateDictionaryNegativeLookup(masm(), |
| 1081 reg, | 1287 miss, |
| 1082 name, | 1288 reg, |
| 1083 scratch1, | 1289 name, |
| 1084 scratch2); | 1290 scratch1, |
| 1291 scratch2); | |
| 1085 if (negative_lookup->IsFailure()) { | 1292 if (negative_lookup->IsFailure()) { |
| 1086 set_failure(Failure::cast(negative_lookup)); | 1293 set_failure(Failure::cast(negative_lookup)); |
| 1087 return reg; | 1294 return reg; |
| 1088 } | 1295 } |
| 1089 | 1296 |
| 1090 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1297 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 1091 reg = holder_reg; // from now the object is in holder_reg | 1298 reg = holder_reg; // from now the object is in holder_reg |
| 1092 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | 1299 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); |
| 1093 } else if (heap()->InNewSpace(prototype)) { | 1300 } else if (heap()->InNewSpace(prototype)) { |
| 1094 // Get the map of the current object. | 1301 // Get the map of the current object. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1143 __ cmp(scratch1, Operand(Handle<Map>(current->map()))); | 1350 __ cmp(scratch1, Operand(Handle<Map>(current->map()))); |
| 1144 __ b(ne, miss); | 1351 __ b(ne, miss); |
| 1145 | 1352 |
| 1146 // Log the check depth. | 1353 // Log the check depth. |
| 1147 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); | 1354 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); |
| 1148 | 1355 |
| 1149 // Perform security check for access to the global object. | 1356 // Perform security check for access to the global object. |
| 1150 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 1357 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
| 1151 if (holder->IsJSGlobalProxy()) { | 1358 if (holder->IsJSGlobalProxy()) { |
| 1152 __ CheckAccessGlobalProxy(reg, scratch1, miss); | 1359 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
| 1153 }; | 1360 } |
| 1154 | 1361 |
| 1155 // If we've skipped any global objects, it's not enough to verify | 1362 // If we've skipped any global objects, it's not enough to verify |
| 1156 // that their maps haven't changed. We also need to check that the | 1363 // that their maps haven't changed. We also need to check that the |
| 1157 // property cell for the property is still empty. | 1364 // property cell for the property is still empty. |
| 1158 MaybeObject* result = GenerateCheckPropertyCells(masm(), | 1365 MaybeObject* result = TryGenerateCheckPropertyCells(masm(), |
| 1159 object, | 1366 object, |
| 1160 holder, | 1367 holder, |
| 1161 name, | 1368 name, |
| 1162 scratch1, | 1369 scratch1, |
| 1163 miss); | 1370 miss); |
| 1164 if (result->IsFailure()) set_failure(Failure::cast(result)); | 1371 if (result->IsFailure()) set_failure(Failure::cast(result)); |
| 1165 | 1372 |
| 1166 // Return the register containing the holder. | 1373 // Return the register containing the holder. |
| 1167 return reg; | 1374 return reg; |
| 1168 } | 1375 } |
| 1169 | 1376 |
| 1170 | 1377 |
| 1171 void StubCompiler::GenerateLoadField(JSObject* object, | 1378 void StubCompiler::GenerateLoadField(JSObject* object, |
| 1172 JSObject* holder, | 1379 JSObject* holder, |
| 1173 Register receiver, | 1380 Register receiver, |
| 1174 Register scratch1, | 1381 Register scratch1, |
| 1175 Register scratch2, | 1382 Register scratch2, |
| 1176 Register scratch3, | 1383 Register scratch3, |
| 1177 int index, | 1384 int index, |
| 1178 String* name, | 1385 String* name, |
| 1179 Label* miss) { | 1386 Label* miss) { |
| 1180 // Check that the receiver isn't a smi. | 1387 // Check that the receiver isn't a smi. |
| 1181 __ JumpIfSmi(receiver, miss); | 1388 __ JumpIfSmi(receiver, miss); |
| 1182 | 1389 |
| 1183 // Check that the maps haven't changed. | 1390 // Check that the maps haven't changed. |
| 1184 Register reg = | 1391 Register reg = |
| 1185 CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, | 1392 CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, |
| 1186 name, miss); | 1393 name, miss); |
| 1187 GenerateFastPropertyLoad(masm(), r0, reg, holder, index); | 1394 GenerateFastPropertyLoad(masm(), r0, reg, Handle<JSObject>(holder), index); |
| 1188 __ Ret(); | 1395 __ Ret(); |
| 1189 } | 1396 } |
| 1190 | 1397 |
| 1191 | 1398 |
| 1192 void StubCompiler::GenerateLoadConstant(JSObject* object, | 1399 void StubCompiler::GenerateLoadConstant(JSObject* object, |
| 1193 JSObject* holder, | 1400 JSObject* holder, |
| 1194 Register receiver, | 1401 Register receiver, |
| 1195 Register scratch1, | 1402 Register scratch1, |
| 1196 Register scratch2, | 1403 Register scratch2, |
| 1197 Register scratch3, | 1404 Register scratch3, |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1358 scratch2, | 1565 scratch2, |
| 1359 scratch3, | 1566 scratch3, |
| 1360 name, | 1567 name, |
| 1361 miss); | 1568 miss); |
| 1362 } | 1569 } |
| 1363 | 1570 |
| 1364 if (lookup->type() == FIELD) { | 1571 if (lookup->type() == FIELD) { |
| 1365 // We found FIELD property in prototype chain of interceptor's holder. | 1572 // We found FIELD property in prototype chain of interceptor's holder. |
| 1366 // Retrieve a field from field's holder. | 1573 // Retrieve a field from field's holder. |
| 1367 GenerateFastPropertyLoad(masm(), r0, holder_reg, | 1574 GenerateFastPropertyLoad(masm(), r0, holder_reg, |
| 1368 lookup->holder(), lookup->GetFieldIndex()); | 1575 Handle<JSObject>(lookup->holder()), |
| 1576 lookup->GetFieldIndex()); | |
| 1369 __ Ret(); | 1577 __ Ret(); |
| 1370 } else { | 1578 } else { |
| 1371 // We found CALLBACKS property in prototype chain of interceptor's | 1579 // We found CALLBACKS property in prototype chain of interceptor's |
| 1372 // holder. | 1580 // holder. |
| 1373 ASSERT(lookup->type() == CALLBACKS); | 1581 ASSERT(lookup->type() == CALLBACKS); |
| 1374 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); | 1582 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); |
| 1375 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); | 1583 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); |
| 1376 ASSERT(callback != NULL); | 1584 ASSERT(callback != NULL); |
| 1377 ASSERT(callback->getter() != NULL); | 1585 ASSERT(callback->getter() != NULL); |
| 1378 | 1586 |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1409 name_reg, interceptor_holder); | 1617 name_reg, interceptor_holder); |
| 1410 | 1618 |
| 1411 ExternalReference ref = | 1619 ExternalReference ref = |
| 1412 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), | 1620 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), |
| 1413 masm()->isolate()); | 1621 masm()->isolate()); |
| 1414 __ TailCallExternalReference(ref, 5, 1); | 1622 __ TailCallExternalReference(ref, 5, 1); |
| 1415 } | 1623 } |
| 1416 } | 1624 } |
| 1417 | 1625 |
| 1418 | 1626 |
| 1419 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { | 1627 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) { |
| 1420 if (kind_ == Code::KEYED_CALL_IC) { | 1628 if (kind_ == Code::KEYED_CALL_IC) { |
| 1421 __ cmp(r2, Operand(Handle<String>(name))); | 1629 __ cmp(r2, Operand(name)); |
| 1422 __ b(ne, miss); | 1630 __ b(ne, miss); |
| 1423 } | 1631 } |
| 1424 } | 1632 } |
| 1425 | 1633 |
| 1426 | 1634 |
| 1427 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, | 1635 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, |
| 1428 JSObject* holder, | 1636 JSObject* holder, |
| 1429 String* name, | 1637 String* name, |
| 1430 Label* miss) { | 1638 Label* miss) { |
| 1431 ASSERT(holder->IsGlobalObject()); | 1639 ASSERT(holder->IsGlobalObject()); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1471 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | 1679 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
| 1472 __ cmp(r4, r3); | 1680 __ cmp(r4, r3); |
| 1473 __ b(ne, miss); | 1681 __ b(ne, miss); |
| 1474 } else { | 1682 } else { |
| 1475 __ cmp(r1, Operand(Handle<JSFunction>(function))); | 1683 __ cmp(r1, Operand(Handle<JSFunction>(function))); |
| 1476 __ b(ne, miss); | 1684 __ b(ne, miss); |
| 1477 } | 1685 } |
| 1478 } | 1686 } |
| 1479 | 1687 |
| 1480 | 1688 |
| 1481 MaybeObject* CallStubCompiler::GenerateMissBranch() { | 1689 void CallStubCompiler::GenerateMissBranch() { |
| 1690 Handle<Code> code = | |
| 1691 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), | |
| 1692 kind_, | |
| 1693 extra_state_); | |
| 1694 __ Jump(code, RelocInfo::CODE_TARGET); | |
| 1695 } | |
| 1696 | |
| 1697 | |
| 1698 // TODO(kmillikin): Eliminate this function when the stub cache is fully | |
| 1699 // handlified. | |
| 1700 MaybeObject* CallStubCompiler::TryGenerateMissBranch() { | |
| 1482 MaybeObject* maybe_obj = | 1701 MaybeObject* maybe_obj = |
| 1483 isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(), | 1702 isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(), |
| 1484 kind_, | 1703 kind_, |
| 1485 extra_state_); | 1704 extra_state_); |
| 1486 Object* obj; | 1705 Object* obj; |
| 1487 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1706 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1488 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); | 1707 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); |
| 1489 return obj; | 1708 return obj; |
| 1490 } | 1709 } |
| 1491 | 1710 |
| 1492 | 1711 |
| 1493 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object, | 1712 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, |
|
Kevin Millikin (Chromium)
2011/10/24 15:55:12
This function is the only stub compiler one that w
| |
| 1494 JSObject* holder, | 1713 Handle<JSObject> holder, |
| 1495 int index, | 1714 int index, |
| 1496 String* name) { | 1715 Handle<String> name) { |
| 1497 // ----------- S t a t e ------------- | 1716 // ----------- S t a t e ------------- |
| 1498 // -- r2 : name | 1717 // -- r2 : name |
| 1499 // -- lr : return address | 1718 // -- lr : return address |
| 1500 // ----------------------------------- | 1719 // ----------------------------------- |
| 1501 Label miss; | 1720 Label miss; |
| 1502 | 1721 |
| 1503 GenerateNameCheck(name, &miss); | 1722 GenerateNameCheck(name, &miss); |
| 1504 | 1723 |
| 1505 const int argc = arguments().immediate(); | 1724 const int argc = arguments().immediate(); |
| 1506 | 1725 |
| 1507 // Get the receiver of the function from the stack into r0. | 1726 // Get the receiver of the function from the stack into r0. |
| 1508 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 1727 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
| 1509 // Check that the receiver isn't a smi. | 1728 // Check that the receiver isn't a smi. |
| 1510 __ JumpIfSmi(r0, &miss); | 1729 __ JumpIfSmi(r0, &miss); |
| 1511 | 1730 |
| 1512 // Do the right check and compute the holder register. | 1731 // Do the right check and compute the holder register. |
| 1513 Register reg = CheckPrototypes(object, r0, holder, r1, r3, r4, name, &miss); | 1732 Register reg = CheckPrototypes(object, r0, holder, r1, r3, r4, name, &miss); |
| 1514 GenerateFastPropertyLoad(masm(), r1, reg, holder, index); | 1733 GenerateFastPropertyLoad(masm(), r1, reg, holder, index); |
| 1515 | 1734 |
| 1516 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); | 1735 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); |
| 1517 | 1736 |
| 1518 // Handle call cache miss. | 1737 // Handle call cache miss. |
| 1519 __ bind(&miss); | 1738 __ bind(&miss); |
| 1520 MaybeObject* maybe_result = GenerateMissBranch(); | 1739 GenerateMissBranch(); |
| 1521 if (maybe_result->IsFailure()) return maybe_result; | |
| 1522 | 1740 |
| 1523 // Return the generated code. | 1741 // Return the generated code. |
| 1524 return GetCode(FIELD, name); | 1742 return GetCode(FIELD, name); |
| 1525 } | 1743 } |
| 1526 | 1744 |
| 1527 | 1745 |
| 1528 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, | 1746 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, |
| 1529 JSObject* holder, | 1747 JSObject* holder, |
| 1530 JSGlobalPropertyCell* cell, | 1748 JSGlobalPropertyCell* cell, |
| 1531 JSFunction* function, | 1749 JSFunction* function, |
| 1532 String* name) { | 1750 String* name) { |
| 1533 // ----------- S t a t e ------------- | 1751 // ----------- S t a t e ------------- |
| 1534 // -- r2 : name | 1752 // -- r2 : name |
| 1535 // -- lr : return address | 1753 // -- lr : return address |
| 1536 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 1754 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
| 1537 // -- ... | 1755 // -- ... |
| 1538 // -- sp[argc * 4] : receiver | 1756 // -- sp[argc * 4] : receiver |
| 1539 // ----------------------------------- | 1757 // ----------------------------------- |
| 1540 | 1758 |
| 1541 // If object is not an array, bail out to regular call. | 1759 // If object is not an array, bail out to regular call. |
| 1542 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); | 1760 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); |
| 1543 | 1761 |
| 1544 Label miss; | 1762 Label miss; |
| 1545 | 1763 |
| 1546 GenerateNameCheck(name, &miss); | 1764 GenerateNameCheck(Handle<String>(name), &miss); |
| 1547 | 1765 |
| 1548 Register receiver = r1; | 1766 Register receiver = r1; |
| 1549 | 1767 |
| 1550 // Get the receiver from the stack | 1768 // Get the receiver from the stack |
| 1551 const int argc = arguments().immediate(); | 1769 const int argc = arguments().immediate(); |
| 1552 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); | 1770 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); |
| 1553 | 1771 |
| 1554 // Check that the receiver isn't a smi. | 1772 // Check that the receiver isn't a smi. |
| 1555 __ JumpIfSmi(receiver, &miss); | 1773 __ JumpIfSmi(receiver, &miss); |
| 1556 | 1774 |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1702 } | 1920 } |
| 1703 __ bind(&call_builtin); | 1921 __ bind(&call_builtin); |
| 1704 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, | 1922 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, |
| 1705 masm()->isolate()), | 1923 masm()->isolate()), |
| 1706 argc + 1, | 1924 argc + 1, |
| 1707 1); | 1925 1); |
| 1708 } | 1926 } |
| 1709 | 1927 |
| 1710 // Handle call cache miss. | 1928 // Handle call cache miss. |
| 1711 __ bind(&miss); | 1929 __ bind(&miss); |
| 1712 MaybeObject* maybe_result = GenerateMissBranch(); | 1930 MaybeObject* maybe_result = TryGenerateMissBranch(); |
| 1713 if (maybe_result->IsFailure()) return maybe_result; | 1931 if (maybe_result->IsFailure()) return maybe_result; |
| 1714 | 1932 |
| 1715 // Return the generated code. | 1933 // Return the generated code. |
| 1716 return GetCode(function); | 1934 return TryGetCode(function); |
| 1717 } | 1935 } |
| 1718 | 1936 |
| 1719 | 1937 |
| 1720 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, | 1938 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, |
| 1721 JSObject* holder, | 1939 JSObject* holder, |
| 1722 JSGlobalPropertyCell* cell, | 1940 JSGlobalPropertyCell* cell, |
| 1723 JSFunction* function, | 1941 JSFunction* function, |
| 1724 String* name) { | 1942 String* name) { |
| 1725 // ----------- S t a t e ------------- | 1943 // ----------- S t a t e ------------- |
| 1726 // -- r2 : name | 1944 // -- r2 : name |
| 1727 // -- lr : return address | 1945 // -- lr : return address |
| 1728 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 1946 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
| 1729 // -- ... | 1947 // -- ... |
| 1730 // -- sp[argc * 4] : receiver | 1948 // -- sp[argc * 4] : receiver |
| 1731 // ----------------------------------- | 1949 // ----------------------------------- |
| 1732 | 1950 |
| 1733 // If object is not an array, bail out to regular call. | 1951 // If object is not an array, bail out to regular call. |
| 1734 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); | 1952 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); |
| 1735 | 1953 |
| 1736 Label miss, return_undefined, call_builtin; | 1954 Label miss, return_undefined, call_builtin; |
| 1737 | 1955 |
| 1738 Register receiver = r1; | 1956 Register receiver = r1; |
| 1739 Register elements = r3; | 1957 Register elements = r3; |
| 1740 | 1958 |
| 1741 GenerateNameCheck(name, &miss); | 1959 GenerateNameCheck(Handle<String>(name), &miss); |
| 1742 | 1960 |
| 1743 // Get the receiver from the stack | 1961 // Get the receiver from the stack |
| 1744 const int argc = arguments().immediate(); | 1962 const int argc = arguments().immediate(); |
| 1745 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); | 1963 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); |
| 1746 | 1964 |
| 1747 // Check that the receiver isn't a smi. | 1965 // Check that the receiver isn't a smi. |
| 1748 __ JumpIfSmi(receiver, &miss); | 1966 __ JumpIfSmi(receiver, &miss); |
| 1749 | 1967 |
| 1750 // Check that the maps haven't changed. | 1968 // Check that the maps haven't changed. |
| 1751 CheckPrototypes(JSObject::cast(object), | 1969 CheckPrototypes(JSObject::cast(object), |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1791 __ Ret(); | 2009 __ Ret(); |
| 1792 | 2010 |
| 1793 __ bind(&call_builtin); | 2011 __ bind(&call_builtin); |
| 1794 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop, | 2012 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop, |
| 1795 masm()->isolate()), | 2013 masm()->isolate()), |
| 1796 argc + 1, | 2014 argc + 1, |
| 1797 1); | 2015 1); |
| 1798 | 2016 |
| 1799 // Handle call cache miss. | 2017 // Handle call cache miss. |
| 1800 __ bind(&miss); | 2018 __ bind(&miss); |
| 1801 MaybeObject* maybe_result = GenerateMissBranch(); | 2019 MaybeObject* maybe_result = TryGenerateMissBranch(); |
| 1802 if (maybe_result->IsFailure()) return maybe_result; | 2020 if (maybe_result->IsFailure()) return maybe_result; |
| 1803 | 2021 |
| 1804 // Return the generated code. | 2022 // Return the generated code. |
| 1805 return GetCode(function); | 2023 return TryGetCode(function); |
| 1806 } | 2024 } |
| 1807 | 2025 |
| 1808 | 2026 |
| 1809 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( | 2027 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( |
| 1810 Object* object, | 2028 Object* object, |
| 1811 JSObject* holder, | 2029 JSObject* holder, |
| 1812 JSGlobalPropertyCell* cell, | 2030 JSGlobalPropertyCell* cell, |
| 1813 JSFunction* function, | 2031 JSFunction* function, |
| 1814 String* name) { | 2032 String* name) { |
| 1815 // ----------- S t a t e ------------- | 2033 // ----------- S t a t e ------------- |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1829 Label name_miss; | 2047 Label name_miss; |
| 1830 Label index_out_of_range; | 2048 Label index_out_of_range; |
| 1831 Label* index_out_of_range_label = &index_out_of_range; | 2049 Label* index_out_of_range_label = &index_out_of_range; |
| 1832 | 2050 |
| 1833 if (kind_ == Code::CALL_IC && | 2051 if (kind_ == Code::CALL_IC && |
| 1834 (CallICBase::StringStubState::decode(extra_state_) == | 2052 (CallICBase::StringStubState::decode(extra_state_) == |
| 1835 DEFAULT_STRING_STUB)) { | 2053 DEFAULT_STRING_STUB)) { |
| 1836 index_out_of_range_label = &miss; | 2054 index_out_of_range_label = &miss; |
| 1837 } | 2055 } |
| 1838 | 2056 |
| 1839 GenerateNameCheck(name, &name_miss); | 2057 GenerateNameCheck(Handle<String>(name), &name_miss); |
| 1840 | 2058 |
| 1841 // Check that the maps starting from the prototype haven't changed. | 2059 // Check that the maps starting from the prototype haven't changed. |
| 1842 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2060 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
| 1843 Context::STRING_FUNCTION_INDEX, | 2061 Context::STRING_FUNCTION_INDEX, |
| 1844 r0, | 2062 r0, |
| 1845 &miss); | 2063 &miss); |
| 1846 ASSERT(object != holder); | 2064 ASSERT(object != holder); |
| 1847 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, | 2065 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, |
| 1848 r1, r3, r4, name, &miss); | 2066 r1, r3, r4, name, &miss); |
| 1849 | 2067 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 1877 __ bind(&index_out_of_range); | 2095 __ bind(&index_out_of_range); |
| 1878 __ LoadRoot(r0, Heap::kNanValueRootIndex); | 2096 __ LoadRoot(r0, Heap::kNanValueRootIndex); |
| 1879 __ Drop(argc + 1); | 2097 __ Drop(argc + 1); |
| 1880 __ Ret(); | 2098 __ Ret(); |
| 1881 } | 2099 } |
| 1882 | 2100 |
| 1883 __ bind(&miss); | 2101 __ bind(&miss); |
| 1884 // Restore function name in r2. | 2102 // Restore function name in r2. |
| 1885 __ Move(r2, Handle<String>(name)); | 2103 __ Move(r2, Handle<String>(name)); |
| 1886 __ bind(&name_miss); | 2104 __ bind(&name_miss); |
| 1887 MaybeObject* maybe_result = GenerateMissBranch(); | 2105 MaybeObject* maybe_result = TryGenerateMissBranch(); |
| 1888 if (maybe_result->IsFailure()) return maybe_result; | 2106 if (maybe_result->IsFailure()) return maybe_result; |
| 1889 | 2107 |
| 1890 // Return the generated code. | 2108 // Return the generated code. |
| 1891 return GetCode(function); | 2109 return TryGetCode(function); |
| 1892 } | 2110 } |
| 1893 | 2111 |
| 1894 | 2112 |
| 1895 MaybeObject* CallStubCompiler::CompileStringCharAtCall( | 2113 MaybeObject* CallStubCompiler::CompileStringCharAtCall( |
| 1896 Object* object, | 2114 Object* object, |
| 1897 JSObject* holder, | 2115 JSObject* holder, |
| 1898 JSGlobalPropertyCell* cell, | 2116 JSGlobalPropertyCell* cell, |
| 1899 JSFunction* function, | 2117 JSFunction* function, |
| 1900 String* name) { | 2118 String* name) { |
| 1901 // ----------- S t a t e ------------- | 2119 // ----------- S t a t e ------------- |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1915 Label name_miss; | 2133 Label name_miss; |
| 1916 Label index_out_of_range; | 2134 Label index_out_of_range; |
| 1917 Label* index_out_of_range_label = &index_out_of_range; | 2135 Label* index_out_of_range_label = &index_out_of_range; |
| 1918 | 2136 |
| 1919 if (kind_ == Code::CALL_IC && | 2137 if (kind_ == Code::CALL_IC && |
| 1920 (CallICBase::StringStubState::decode(extra_state_) == | 2138 (CallICBase::StringStubState::decode(extra_state_) == |
| 1921 DEFAULT_STRING_STUB)) { | 2139 DEFAULT_STRING_STUB)) { |
| 1922 index_out_of_range_label = &miss; | 2140 index_out_of_range_label = &miss; |
| 1923 } | 2141 } |
| 1924 | 2142 |
| 1925 GenerateNameCheck(name, &name_miss); | 2143 GenerateNameCheck(Handle<String>(name), &name_miss); |
| 1926 | 2144 |
| 1927 // Check that the maps starting from the prototype haven't changed. | 2145 // Check that the maps starting from the prototype haven't changed. |
| 1928 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2146 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
| 1929 Context::STRING_FUNCTION_INDEX, | 2147 Context::STRING_FUNCTION_INDEX, |
| 1930 r0, | 2148 r0, |
| 1931 &miss); | 2149 &miss); |
| 1932 ASSERT(object != holder); | 2150 ASSERT(object != holder); |
| 1933 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, | 2151 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, |
| 1934 r1, r3, r4, name, &miss); | 2152 r1, r3, r4, name, &miss); |
| 1935 | 2153 |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 1965 __ bind(&index_out_of_range); | 2183 __ bind(&index_out_of_range); |
| 1966 __ LoadRoot(r0, Heap::kEmptyStringRootIndex); | 2184 __ LoadRoot(r0, Heap::kEmptyStringRootIndex); |
| 1967 __ Drop(argc + 1); | 2185 __ Drop(argc + 1); |
| 1968 __ Ret(); | 2186 __ Ret(); |
| 1969 } | 2187 } |
| 1970 | 2188 |
| 1971 __ bind(&miss); | 2189 __ bind(&miss); |
| 1972 // Restore function name in r2. | 2190 // Restore function name in r2. |
| 1973 __ Move(r2, Handle<String>(name)); | 2191 __ Move(r2, Handle<String>(name)); |
| 1974 __ bind(&name_miss); | 2192 __ bind(&name_miss); |
| 1975 MaybeObject* maybe_result = GenerateMissBranch(); | 2193 MaybeObject* maybe_result = TryGenerateMissBranch(); |
| 1976 if (maybe_result->IsFailure()) return maybe_result; | 2194 if (maybe_result->IsFailure()) return maybe_result; |
| 1977 | 2195 |
| 1978 // Return the generated code. | 2196 // Return the generated code. |
| 1979 return GetCode(function); | 2197 return TryGetCode(function); |
| 1980 } | 2198 } |
| 1981 | 2199 |
| 1982 | 2200 |
| 1983 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( | 2201 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( |
| 1984 Object* object, | 2202 Object* object, |
| 1985 JSObject* holder, | 2203 JSObject* holder, |
| 1986 JSGlobalPropertyCell* cell, | 2204 JSGlobalPropertyCell* cell, |
| 1987 JSFunction* function, | 2205 JSFunction* function, |
| 1988 String* name) { | 2206 String* name) { |
| 1989 // ----------- S t a t e ------------- | 2207 // ----------- S t a t e ------------- |
| 1990 // -- r2 : function name | 2208 // -- r2 : function name |
| 1991 // -- lr : return address | 2209 // -- lr : return address |
| 1992 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2210 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
| 1993 // -- ... | 2211 // -- ... |
| 1994 // -- sp[argc * 4] : receiver | 2212 // -- sp[argc * 4] : receiver |
| 1995 // ----------------------------------- | 2213 // ----------------------------------- |
| 1996 | 2214 |
| 1997 const int argc = arguments().immediate(); | 2215 const int argc = arguments().immediate(); |
| 1998 | 2216 |
| 1999 // If the object is not a JSObject or we got an unexpected number of | 2217 // If the object is not a JSObject or we got an unexpected number of |
| 2000 // arguments, bail out to the regular call. | 2218 // arguments, bail out to the regular call. |
| 2001 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 2219 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); |
| 2002 | 2220 |
| 2003 Label miss; | 2221 Label miss; |
| 2004 GenerateNameCheck(name, &miss); | 2222 GenerateNameCheck(Handle<String>(name), &miss); |
| 2005 | 2223 |
| 2006 if (cell == NULL) { | 2224 if (cell == NULL) { |
| 2007 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); | 2225 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); |
| 2008 | 2226 |
| 2009 STATIC_ASSERT(kSmiTag == 0); | 2227 STATIC_ASSERT(kSmiTag == 0); |
| 2010 __ JumpIfSmi(r1, &miss); | 2228 __ JumpIfSmi(r1, &miss); |
| 2011 | 2229 |
| 2012 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, | 2230 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, |
| 2013 &miss); | 2231 &miss); |
| 2014 } else { | 2232 } else { |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 2037 StubRuntimeCallHelper call_helper; | 2255 StubRuntimeCallHelper call_helper; |
| 2038 char_from_code_generator.GenerateSlow(masm(), call_helper); | 2256 char_from_code_generator.GenerateSlow(masm(), call_helper); |
| 2039 | 2257 |
| 2040 // Tail call the full function. We do not have to patch the receiver | 2258 // Tail call the full function. We do not have to patch the receiver |
| 2041 // because the function makes no use of it. | 2259 // because the function makes no use of it. |
| 2042 __ bind(&slow); | 2260 __ bind(&slow); |
| 2043 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); | 2261 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); |
| 2044 | 2262 |
| 2045 __ bind(&miss); | 2263 __ bind(&miss); |
| 2046 // r2: function name. | 2264 // r2: function name. |
| 2047 MaybeObject* maybe_result = GenerateMissBranch(); | 2265 MaybeObject* maybe_result = TryGenerateMissBranch(); |
| 2048 if (maybe_result->IsFailure()) return maybe_result; | 2266 if (maybe_result->IsFailure()) return maybe_result; |
| 2049 | 2267 |
| 2050 // Return the generated code. | 2268 // Return the generated code. |
| 2051 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2269 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); |
| 2052 } | 2270 } |
| 2053 | 2271 |
| 2054 | 2272 |
| 2055 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, | 2273 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, |
| 2056 JSObject* holder, | 2274 JSObject* holder, |
| 2057 JSGlobalPropertyCell* cell, | 2275 JSGlobalPropertyCell* cell, |
| 2058 JSFunction* function, | 2276 JSFunction* function, |
| 2059 String* name) { | 2277 String* name) { |
| 2060 // ----------- S t a t e ------------- | 2278 // ----------- S t a t e ------------- |
| 2061 // -- r2 : function name | 2279 // -- r2 : function name |
| 2062 // -- lr : return address | 2280 // -- lr : return address |
| 2063 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2281 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
| 2064 // -- ... | 2282 // -- ... |
| 2065 // -- sp[argc * 4] : receiver | 2283 // -- sp[argc * 4] : receiver |
| 2066 // ----------------------------------- | 2284 // ----------------------------------- |
| 2067 | 2285 |
| 2068 if (!CpuFeatures::IsSupported(VFP3)) { | 2286 if (!CpuFeatures::IsSupported(VFP3)) { |
| 2069 return heap()->undefined_value(); | 2287 return heap()->undefined_value(); |
| 2070 } | 2288 } |
| 2071 | 2289 |
| 2072 CpuFeatures::Scope scope_vfp3(VFP3); | 2290 CpuFeatures::Scope scope_vfp3(VFP3); |
| 2073 | 2291 |
| 2074 const int argc = arguments().immediate(); | 2292 const int argc = arguments().immediate(); |
| 2075 | 2293 |
| 2076 // If the object is not a JSObject or we got an unexpected number of | 2294 // If the object is not a JSObject or we got an unexpected number of |
| 2077 // arguments, bail out to the regular call. | 2295 // arguments, bail out to the regular call. |
| 2078 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 2296 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); |
| 2079 | 2297 |
| 2080 Label miss, slow; | 2298 Label miss, slow; |
| 2081 GenerateNameCheck(name, &miss); | 2299 GenerateNameCheck(Handle<String>(name), &miss); |
| 2082 | 2300 |
| 2083 if (cell == NULL) { | 2301 if (cell == NULL) { |
| 2084 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); | 2302 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); |
| 2085 | 2303 |
| 2086 STATIC_ASSERT(kSmiTag == 0); | 2304 STATIC_ASSERT(kSmiTag == 0); |
| 2087 __ JumpIfSmi(r1, &miss); | 2305 __ JumpIfSmi(r1, &miss); |
| 2088 | 2306 |
| 2089 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, | 2307 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, |
| 2090 &miss); | 2308 &miss); |
| 2091 } else { | 2309 } else { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2185 // Restore FPCSR and fall to slow case. | 2403 // Restore FPCSR and fall to slow case. |
| 2186 __ vmsr(r3); | 2404 __ vmsr(r3); |
| 2187 | 2405 |
| 2188 __ bind(&slow); | 2406 __ bind(&slow); |
| 2189 // Tail call the full function. We do not have to patch the receiver | 2407 // Tail call the full function. We do not have to patch the receiver |
| 2190 // because the function makes no use of it. | 2408 // because the function makes no use of it. |
| 2191 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); | 2409 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); |
| 2192 | 2410 |
| 2193 __ bind(&miss); | 2411 __ bind(&miss); |
| 2194 // r2: function name. | 2412 // r2: function name. |
| 2195 MaybeObject* maybe_result = GenerateMissBranch(); | 2413 MaybeObject* maybe_result = TryGenerateMissBranch(); |
| 2196 if (maybe_result->IsFailure()) return maybe_result; | 2414 if (maybe_result->IsFailure()) return maybe_result; |
| 2197 | 2415 |
| 2198 // Return the generated code. | 2416 // Return the generated code. |
| 2199 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2417 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); |
| 2200 } | 2418 } |
| 2201 | 2419 |
| 2202 | 2420 |
| 2203 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, | 2421 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, |
| 2204 JSObject* holder, | 2422 JSObject* holder, |
| 2205 JSGlobalPropertyCell* cell, | 2423 JSGlobalPropertyCell* cell, |
| 2206 JSFunction* function, | 2424 JSFunction* function, |
| 2207 String* name) { | 2425 String* name) { |
| 2208 // ----------- S t a t e ------------- | 2426 // ----------- S t a t e ------------- |
| 2209 // -- r2 : function name | 2427 // -- r2 : function name |
| 2210 // -- lr : return address | 2428 // -- lr : return address |
| 2211 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2429 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
| 2212 // -- ... | 2430 // -- ... |
| 2213 // -- sp[argc * 4] : receiver | 2431 // -- sp[argc * 4] : receiver |
| 2214 // ----------------------------------- | 2432 // ----------------------------------- |
| 2215 | 2433 |
| 2216 const int argc = arguments().immediate(); | 2434 const int argc = arguments().immediate(); |
| 2217 | 2435 |
| 2218 // If the object is not a JSObject or we got an unexpected number of | 2436 // If the object is not a JSObject or we got an unexpected number of |
| 2219 // arguments, bail out to the regular call. | 2437 // arguments, bail out to the regular call. |
| 2220 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 2438 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); |
| 2221 | 2439 |
| 2222 Label miss; | 2440 Label miss; |
| 2223 GenerateNameCheck(name, &miss); | 2441 GenerateNameCheck(Handle<String>(name), &miss); |
| 2224 | 2442 |
| 2225 if (cell == NULL) { | 2443 if (cell == NULL) { |
| 2226 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); | 2444 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); |
| 2227 | 2445 |
| 2228 STATIC_ASSERT(kSmiTag == 0); | 2446 STATIC_ASSERT(kSmiTag == 0); |
| 2229 __ JumpIfSmi(r1, &miss); | 2447 __ JumpIfSmi(r1, &miss); |
| 2230 | 2448 |
| 2231 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, | 2449 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, |
| 2232 &miss); | 2450 &miss); |
| 2233 } else { | 2451 } else { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2286 __ Drop(argc + 1); | 2504 __ Drop(argc + 1); |
| 2287 __ Ret(); | 2505 __ Ret(); |
| 2288 | 2506 |
| 2289 // Tail call the full function. We do not have to patch the receiver | 2507 // Tail call the full function. We do not have to patch the receiver |
| 2290 // because the function makes no use of it. | 2508 // because the function makes no use of it. |
| 2291 __ bind(&slow); | 2509 __ bind(&slow); |
| 2292 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); | 2510 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); |
| 2293 | 2511 |
| 2294 __ bind(&miss); | 2512 __ bind(&miss); |
| 2295 // r2: function name. | 2513 // r2: function name. |
| 2296 MaybeObject* maybe_result = GenerateMissBranch(); | 2514 MaybeObject* maybe_result = TryGenerateMissBranch(); |
| 2297 if (maybe_result->IsFailure()) return maybe_result; | 2515 if (maybe_result->IsFailure()) return maybe_result; |
| 2298 | 2516 |
| 2299 // Return the generated code. | 2517 // Return the generated code. |
| 2300 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2518 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); |
| 2301 } | 2519 } |
| 2302 | 2520 |
| 2303 | 2521 |
| 2304 MaybeObject* CallStubCompiler::CompileFastApiCall( | 2522 MaybeObject* CallStubCompiler::CompileFastApiCall( |
| 2305 const CallOptimization& optimization, | 2523 const CallOptimization& optimization, |
| 2306 Object* object, | 2524 Object* object, |
| 2307 JSObject* holder, | 2525 JSObject* holder, |
| 2308 JSGlobalPropertyCell* cell, | 2526 JSGlobalPropertyCell* cell, |
| 2309 JSFunction* function, | 2527 JSFunction* function, |
| 2310 String* name) { | 2528 String* name) { |
| 2311 Counters* counters = isolate()->counters(); | 2529 Counters* counters = isolate()->counters(); |
| 2312 | 2530 |
| 2313 ASSERT(optimization.is_simple_api_call()); | 2531 ASSERT(optimization.is_simple_api_call()); |
| 2314 // Bail out if object is a global object as we don't want to | 2532 // Bail out if object is a global object as we don't want to |
| 2315 // repatch it to global receiver. | 2533 // repatch it to global receiver. |
| 2316 if (object->IsGlobalObject()) return heap()->undefined_value(); | 2534 if (object->IsGlobalObject()) return heap()->undefined_value(); |
| 2317 if (cell != NULL) return heap()->undefined_value(); | 2535 if (cell != NULL) return heap()->undefined_value(); |
| 2318 if (!object->IsJSObject()) return heap()->undefined_value(); | 2536 if (!object->IsJSObject()) return heap()->undefined_value(); |
| 2319 int depth = optimization.GetPrototypeDepthOfExpectedType( | 2537 int depth = optimization.GetPrototypeDepthOfExpectedType( |
| 2320 JSObject::cast(object), holder); | 2538 JSObject::cast(object), holder); |
| 2321 if (depth == kInvalidProtoDepth) return heap()->undefined_value(); | 2539 if (depth == kInvalidProtoDepth) return heap()->undefined_value(); |
| 2322 | 2540 |
| 2323 Label miss, miss_before_stack_reserved; | 2541 Label miss, miss_before_stack_reserved; |
| 2324 | 2542 |
| 2325 GenerateNameCheck(name, &miss_before_stack_reserved); | 2543 GenerateNameCheck(Handle<String>(name), &miss_before_stack_reserved); |
| 2326 | 2544 |
| 2327 // Get the receiver from the stack. | 2545 // Get the receiver from the stack. |
| 2328 const int argc = arguments().immediate(); | 2546 const int argc = arguments().immediate(); |
| 2329 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 2547 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
| 2330 | 2548 |
| 2331 // Check that the receiver isn't a smi. | 2549 // Check that the receiver isn't a smi. |
| 2332 __ JumpIfSmi(r1, &miss_before_stack_reserved); | 2550 __ JumpIfSmi(r1, &miss_before_stack_reserved); |
| 2333 | 2551 |
| 2334 __ IncrementCounter(counters->call_const(), 1, r0, r3); | 2552 __ IncrementCounter(counters->call_const(), 1, r0, r3); |
| 2335 __ IncrementCounter(counters->call_const_fast_api(), 1, r0, r3); | 2553 __ IncrementCounter(counters->call_const_fast_api(), 1, r0, r3); |
| 2336 | 2554 |
| 2337 ReserveSpaceForFastApiCall(masm(), r0); | 2555 ReserveSpaceForFastApiCall(masm(), r0); |
| 2338 | 2556 |
| 2339 // Check that the maps haven't changed and find a Holder as a side effect. | 2557 // Check that the maps haven't changed and find a Holder as a side effect. |
| 2340 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, | 2558 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, |
| 2341 depth, &miss); | 2559 depth, &miss); |
| 2342 | 2560 |
| 2343 MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); | 2561 MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); |
| 2344 if (result->IsFailure()) return result; | 2562 if (result->IsFailure()) return result; |
| 2345 | 2563 |
| 2346 __ bind(&miss); | 2564 __ bind(&miss); |
| 2347 FreeSpaceForFastApiCall(masm()); | 2565 FreeSpaceForFastApiCall(masm()); |
| 2348 | 2566 |
| 2349 __ bind(&miss_before_stack_reserved); | 2567 __ bind(&miss_before_stack_reserved); |
| 2350 MaybeObject* maybe_result = GenerateMissBranch(); | 2568 MaybeObject* maybe_result = TryGenerateMissBranch(); |
| 2351 if (maybe_result->IsFailure()) return maybe_result; | 2569 if (maybe_result->IsFailure()) return maybe_result; |
| 2352 | 2570 |
| 2353 // Return the generated code. | 2571 // Return the generated code. |
| 2354 return GetCode(function); | 2572 return TryGetCode(function); |
| 2355 } | 2573 } |
| 2356 | 2574 |
| 2357 | 2575 |
| 2358 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, | 2576 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, |
| 2359 JSObject* holder, | 2577 JSObject* holder, |
| 2360 JSFunction* function, | 2578 JSFunction* function, |
| 2361 String* name, | 2579 String* name, |
| 2362 CheckType check) { | 2580 CheckType check) { |
| 2363 // ----------- S t a t e ------------- | 2581 // ----------- S t a t e ------------- |
| 2364 // -- r2 : name | 2582 // -- r2 : name |
| 2365 // -- lr : return address | 2583 // -- lr : return address |
| 2366 // ----------------------------------- | 2584 // ----------------------------------- |
| 2367 if (HasCustomCallGenerator(function)) { | 2585 if (HasCustomCallGenerator(function)) { |
| 2368 MaybeObject* maybe_result = CompileCustomCall( | 2586 MaybeObject* maybe_result = CompileCustomCall( |
| 2369 object, holder, NULL, function, name); | 2587 object, holder, NULL, function, name); |
| 2370 Object* result; | 2588 Object* result; |
| 2371 if (!maybe_result->ToObject(&result)) return maybe_result; | 2589 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 2372 // undefined means bail out to regular compiler. | 2590 // undefined means bail out to regular compiler. |
| 2373 if (!result->IsUndefined()) return result; | 2591 if (!result->IsUndefined()) return result; |
| 2374 } | 2592 } |
| 2375 | 2593 |
| 2376 Label miss; | 2594 Label miss; |
| 2377 | 2595 |
| 2378 GenerateNameCheck(name, &miss); | 2596 GenerateNameCheck(Handle<String>(name), &miss); |
| 2379 | 2597 |
| 2380 // Get the receiver from the stack | 2598 // Get the receiver from the stack |
| 2381 const int argc = arguments().immediate(); | 2599 const int argc = arguments().immediate(); |
| 2382 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 2600 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
| 2383 | 2601 |
| 2384 // Check that the receiver isn't a smi. | 2602 // Check that the receiver isn't a smi. |
| 2385 if (check != NUMBER_CHECK) { | 2603 if (check != NUMBER_CHECK) { |
| 2386 __ JumpIfSmi(r1, &miss); | 2604 __ JumpIfSmi(r1, &miss); |
| 2387 } | 2605 } |
| 2388 | 2606 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2474 UNREACHABLE(); | 2692 UNREACHABLE(); |
| 2475 } | 2693 } |
| 2476 | 2694 |
| 2477 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2695 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
| 2478 ? CALL_AS_FUNCTION | 2696 ? CALL_AS_FUNCTION |
| 2479 : CALL_AS_METHOD; | 2697 : CALL_AS_METHOD; |
| 2480 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind); | 2698 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind); |
| 2481 | 2699 |
| 2482 // Handle call cache miss. | 2700 // Handle call cache miss. |
| 2483 __ bind(&miss); | 2701 __ bind(&miss); |
| 2484 MaybeObject* maybe_result = GenerateMissBranch(); | 2702 MaybeObject* maybe_result = TryGenerateMissBranch(); |
| 2485 if (maybe_result->IsFailure()) return maybe_result; | 2703 if (maybe_result->IsFailure()) return maybe_result; |
| 2486 | 2704 |
| 2487 // Return the generated code. | 2705 // Return the generated code. |
| 2488 return GetCode(function); | 2706 return TryGetCode(function); |
| 2489 } | 2707 } |
| 2490 | 2708 |
| 2491 | 2709 |
| 2492 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, | 2710 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, |
| 2493 JSObject* holder, | 2711 JSObject* holder, |
| 2494 String* name) { | 2712 String* name) { |
| 2495 // ----------- S t a t e ------------- | 2713 // ----------- S t a t e ------------- |
| 2496 // -- r2 : name | 2714 // -- r2 : name |
| 2497 // -- lr : return address | 2715 // -- lr : return address |
| 2498 // ----------------------------------- | 2716 // ----------------------------------- |
| 2499 | 2717 |
| 2500 Label miss; | 2718 Label miss; |
| 2501 | 2719 |
| 2502 GenerateNameCheck(name, &miss); | 2720 GenerateNameCheck(Handle<String>(name), &miss); |
| 2503 | 2721 |
| 2504 // Get the number of arguments. | 2722 // Get the number of arguments. |
| 2505 const int argc = arguments().immediate(); | 2723 const int argc = arguments().immediate(); |
| 2506 | 2724 |
| 2507 LookupResult lookup(isolate()); | 2725 LookupResult lookup(isolate()); |
| 2508 LookupPostInterceptor(holder, name, &lookup); | 2726 LookupPostInterceptor(holder, name, &lookup); |
| 2509 | 2727 |
| 2510 // Get the receiver from the stack. | 2728 // Get the receiver from the stack. |
| 2511 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 2729 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
| 2512 | 2730 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 2523 &miss); | 2741 &miss); |
| 2524 if (result->IsFailure()) { | 2742 if (result->IsFailure()) { |
| 2525 return result; | 2743 return result; |
| 2526 } | 2744 } |
| 2527 | 2745 |
| 2528 // Move returned value, the function to call, to r1. | 2746 // Move returned value, the function to call, to r1. |
| 2529 __ mov(r1, r0); | 2747 __ mov(r1, r0); |
| 2530 // Restore receiver. | 2748 // Restore receiver. |
| 2531 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 2749 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
| 2532 | 2750 |
| 2533 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); | 2751 GenerateCallFunction(masm(), Handle<Object>(object), arguments(), &miss, |
| 2752 extra_state_); | |
| 2534 | 2753 |
| 2535 // Handle call cache miss. | 2754 // Handle call cache miss. |
| 2536 __ bind(&miss); | 2755 __ bind(&miss); |
| 2537 MaybeObject* maybe_result = GenerateMissBranch(); | 2756 MaybeObject* maybe_result = TryGenerateMissBranch(); |
| 2538 if (maybe_result->IsFailure()) return maybe_result; | 2757 if (maybe_result->IsFailure()) return maybe_result; |
| 2539 | 2758 |
| 2540 // Return the generated code. | 2759 // Return the generated code. |
| 2541 return GetCode(INTERCEPTOR, name); | 2760 return TryGetCode(INTERCEPTOR, name); |
| 2542 } | 2761 } |
| 2543 | 2762 |
| 2544 | 2763 |
| 2545 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, | 2764 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, |
| 2546 GlobalObject* holder, | 2765 GlobalObject* holder, |
| 2547 JSGlobalPropertyCell* cell, | 2766 JSGlobalPropertyCell* cell, |
| 2548 JSFunction* function, | 2767 JSFunction* function, |
| 2549 String* name) { | 2768 String* name) { |
| 2550 // ----------- S t a t e ------------- | 2769 // ----------- S t a t e ------------- |
| 2551 // -- r2 : name | 2770 // -- r2 : name |
| 2552 // -- lr : return address | 2771 // -- lr : return address |
| 2553 // ----------------------------------- | 2772 // ----------------------------------- |
| 2554 | 2773 |
| 2555 if (HasCustomCallGenerator(function)) { | 2774 if (HasCustomCallGenerator(function)) { |
| 2556 MaybeObject* maybe_result = CompileCustomCall( | 2775 MaybeObject* maybe_result = CompileCustomCall( |
| 2557 object, holder, cell, function, name); | 2776 object, holder, cell, function, name); |
| 2558 Object* result; | 2777 Object* result; |
| 2559 if (!maybe_result->ToObject(&result)) return maybe_result; | 2778 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 2560 // undefined means bail out to regular compiler. | 2779 // undefined means bail out to regular compiler. |
| 2561 if (!result->IsUndefined()) return result; | 2780 if (!result->IsUndefined()) return result; |
| 2562 } | 2781 } |
| 2563 | 2782 |
| 2564 Label miss; | 2783 Label miss; |
| 2565 | 2784 |
| 2566 GenerateNameCheck(name, &miss); | 2785 GenerateNameCheck(Handle<String>(name), &miss); |
| 2567 | 2786 |
| 2568 // Get the number of arguments. | 2787 // Get the number of arguments. |
| 2569 const int argc = arguments().immediate(); | 2788 const int argc = arguments().immediate(); |
| 2570 | 2789 |
| 2571 GenerateGlobalReceiverCheck(object, holder, name, &miss); | 2790 GenerateGlobalReceiverCheck(object, holder, name, &miss); |
| 2572 | 2791 |
| 2573 GenerateLoadFunctionFromCell(cell, function, &miss); | 2792 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 2574 | 2793 |
| 2575 // Patch the receiver on the stack with the global proxy if | 2794 // Patch the receiver on the stack with the global proxy if |
| 2576 // necessary. | 2795 // necessary. |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 2593 // We call indirectly through the code field in the function to | 2812 // We call indirectly through the code field in the function to |
| 2594 // allow recompilation to take effect without changing any of the | 2813 // allow recompilation to take effect without changing any of the |
| 2595 // call sites. | 2814 // call sites. |
| 2596 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); | 2815 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); |
| 2597 __ InvokeCode(r3, expected, arguments(), JUMP_FUNCTION, | 2816 __ InvokeCode(r3, expected, arguments(), JUMP_FUNCTION, |
| 2598 NullCallWrapper(), call_kind); | 2817 NullCallWrapper(), call_kind); |
| 2599 | 2818 |
| 2600 // Handle call cache miss. | 2819 // Handle call cache miss. |
| 2601 __ bind(&miss); | 2820 __ bind(&miss); |
| 2602 __ IncrementCounter(counters->call_global_inline_miss(), 1, r1, r3); | 2821 __ IncrementCounter(counters->call_global_inline_miss(), 1, r1, r3); |
| 2603 MaybeObject* maybe_result = GenerateMissBranch(); | 2822 MaybeObject* maybe_result = TryGenerateMissBranch(); |
| 2604 if (maybe_result->IsFailure()) return maybe_result; | 2823 if (maybe_result->IsFailure()) return maybe_result; |
| 2605 | 2824 |
| 2606 // Return the generated code. | 2825 // Return the generated code. |
| 2607 return GetCode(NORMAL, name); | 2826 return TryGetCode(NORMAL, name); |
| 2608 } | 2827 } |
| 2609 | 2828 |
| 2610 | 2829 |
| 2611 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, | 2830 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, |
| 2612 int index, | 2831 int index, |
| 2613 Map* transition, | 2832 Map* transition, |
| 2614 String* name) { | 2833 String* name) { |
| 2615 // ----------- S t a t e ------------- | 2834 // ----------- S t a t e ------------- |
| 2616 // -- r0 : value | 2835 // -- r0 : value |
| 2617 // -- r1 : receiver | 2836 // -- r1 : receiver |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2795 | 3014 |
| 2796 // Check that receiver is not a smi. | 3015 // Check that receiver is not a smi. |
| 2797 __ JumpIfSmi(r0, &miss); | 3016 __ JumpIfSmi(r0, &miss); |
| 2798 | 3017 |
| 2799 // Check the maps of the full prototype chain. | 3018 // Check the maps of the full prototype chain. |
| 2800 CheckPrototypes(object, r0, last, r3, r1, r4, name, &miss); | 3019 CheckPrototypes(object, r0, last, r3, r1, r4, name, &miss); |
| 2801 | 3020 |
| 2802 // If the last object in the prototype chain is a global object, | 3021 // If the last object in the prototype chain is a global object, |
| 2803 // check that the global property cell is empty. | 3022 // check that the global property cell is empty. |
| 2804 if (last->IsGlobalObject()) { | 3023 if (last->IsGlobalObject()) { |
| 2805 MaybeObject* cell = GenerateCheckPropertyCell(masm(), | 3024 MaybeObject* cell = TryGenerateCheckPropertyCell(masm(), |
| 2806 GlobalObject::cast(last), | 3025 GlobalObject::cast(last), |
| 2807 name, | 3026 name, |
| 2808 r1, | 3027 r1, |
| 2809 &miss); | 3028 &miss); |
| 2810 if (cell->IsFailure()) { | 3029 if (cell->IsFailure()) { |
| 2811 miss.Unuse(); | 3030 miss.Unuse(); |
| 2812 return cell; | 3031 return cell; |
| 2813 } | 3032 } |
| 2814 } | 3033 } |
| 2815 | 3034 |
| 2816 // Return undefined if maps of the full prototype chain are still the | 3035 // Return undefined if maps of the full prototype chain are still the |
| 2817 // same and no global property with this name contains a value. | 3036 // same and no global property with this name contains a value. |
| 2818 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); | 3037 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
| 2819 __ Ret(); | 3038 __ Ret(); |
| (...skipping 1634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4454 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 4673 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
| 4455 __ Jump(ic_miss, RelocInfo::CODE_TARGET); | 4674 __ Jump(ic_miss, RelocInfo::CODE_TARGET); |
| 4456 } | 4675 } |
| 4457 | 4676 |
| 4458 | 4677 |
| 4459 #undef __ | 4678 #undef __ |
| 4460 | 4679 |
| 4461 } } // namespace v8::internal | 4680 } } // namespace v8::internal |
| 4462 | 4681 |
| 4463 #endif // V8_TARGET_ARCH_ARM | 4682 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |