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, |
| 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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 __ mov(r0, scratch1); | 418 __ mov(r0, scratch1); |
361 __ Ret(); | 419 __ Ret(); |
362 } | 420 } |
363 | 421 |
364 | 422 |
365 // Generate StoreField code, value is passed in r0 register. | 423 // Generate StoreField code, value is passed in r0 register. |
366 // When leaving generated code after success, the receiver_reg and name_reg | 424 // When leaving generated code after success, the receiver_reg and name_reg |
367 // may be clobbered. Upon branch to miss_label, the receiver and name | 425 // may be clobbered. Upon branch to miss_label, the receiver and name |
368 // registers have their original values. | 426 // registers have their original values. |
369 void StubCompiler::GenerateStoreField(MacroAssembler* masm, | 427 void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
370 JSObject* object, | 428 Handle<JSObject> object, |
371 int index, | 429 int index, |
372 Map* transition, | 430 Handle<Map> transition, |
373 Register receiver_reg, | 431 Register receiver_reg, |
374 Register name_reg, | 432 Register name_reg, |
375 Register scratch, | 433 Register scratch, |
376 Label* miss_label) { | 434 Label* miss_label) { |
377 // r0 : value | 435 // r0 : value |
378 Label exit; | 436 Label exit; |
379 | 437 |
380 // Check that the receiver isn't a smi. | 438 // Check that the receiver isn't a smi. |
381 __ JumpIfSmi(receiver_reg, miss_label); | 439 __ JumpIfSmi(receiver_reg, miss_label); |
382 | 440 |
383 // Check that the map of the receiver hasn't changed. | 441 // Check that the map of the receiver hasn't changed. |
384 __ ldr(scratch, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); | 442 __ ldr(scratch, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); |
385 __ cmp(scratch, Operand(Handle<Map>(object->map()))); | 443 __ cmp(scratch, Operand(Handle<Map>(object->map()))); |
386 __ b(ne, miss_label); | 444 __ b(ne, miss_label); |
387 | 445 |
388 // Perform global security token check if needed. | 446 // Perform global security token check if needed. |
389 if (object->IsJSGlobalProxy()) { | 447 if (object->IsJSGlobalProxy()) { |
390 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); | 448 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); |
391 } | 449 } |
392 | 450 |
393 // Stub never generated for non-global objects that require access | 451 // Stub never generated for non-global objects that require access |
394 // checks. | 452 // checks. |
395 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 453 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
396 | 454 |
397 // Perform map transition for the receiver if necessary. | 455 // Perform map transition for the receiver if necessary. |
398 if ((transition != NULL) && (object->map()->unused_property_fields() == 0)) { | 456 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) { |
399 // The properties must be extended before we can store the value. | 457 // The properties must be extended before we can store the value. |
400 // We jump to a runtime call that extends the properties array. | 458 // We jump to a runtime call that extends the properties array. |
401 __ push(receiver_reg); | 459 __ push(receiver_reg); |
402 __ mov(r2, Operand(Handle<Map>(transition))); | 460 __ mov(r2, Operand(transition)); |
403 __ Push(r2, r0); | 461 __ Push(r2, r0); |
404 __ TailCallExternalReference( | 462 __ TailCallExternalReference( |
405 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), | 463 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), |
406 masm->isolate()), | 464 masm->isolate()), |
407 3, | 465 3, |
408 1); | 466 1); |
409 return; | 467 return; |
410 } | 468 } |
411 | 469 |
412 if (transition != NULL) { | 470 if (!transition.is_null()) { |
413 // Update the map of the object; no write barrier updating is | 471 // Update the map of the object; no write barrier updating is |
414 // needed because the map is never in new space. | 472 // needed because the map is never in new space. |
415 __ mov(ip, Operand(Handle<Map>(transition))); | 473 __ mov(ip, Operand(transition)); |
416 __ str(ip, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); | 474 __ str(ip, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); |
417 } | 475 } |
418 | 476 |
419 // Adjust for the number of properties stored in the object. Even in the | 477 // Adjust for the number of properties stored in the object. Even in the |
420 // face of a transition we can use the old map here because the size of the | 478 // face of a transition we can use the old map here because the size of the |
421 // object and the number of in-object properties is not going to change. | 479 // object and the number of in-object properties is not going to change. |
422 index -= object->map()->inobject_properties(); | 480 index -= object->map()->inobject_properties(); |
423 | 481 |
424 if (index < 0) { | 482 if (index < 0) { |
425 // Set the property straight into the object. | 483 // Set the property straight into the object. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 } | 518 } |
461 | 519 |
462 // Return the value (register r0). | 520 // Return the value (register r0). |
463 __ bind(&exit); | 521 __ bind(&exit); |
464 __ Ret(); | 522 __ Ret(); |
465 } | 523 } |
466 | 524 |
467 | 525 |
468 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { | 526 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { |
469 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); | 527 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); |
470 Code* code = NULL; | 528 Handle<Code> code = (kind == Code::LOAD_IC) |
471 if (kind == Code::LOAD_IC) { | 529 ? masm->isolate()->builtins()->LoadIC_Miss() |
472 code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss); | 530 : masm->isolate()->builtins()->KeyedLoadIC_Miss(); |
473 } else { | 531 __ Jump(code, RelocInfo::CODE_TARGET); |
474 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss); | |
475 } | |
476 | |
477 Handle<Code> ic(code); | |
478 __ Jump(ic, RelocInfo::CODE_TARGET); | |
479 } | 532 } |
480 | 533 |
481 | 534 |
482 static void GenerateCallFunction(MacroAssembler* masm, | 535 static void GenerateCallFunction(MacroAssembler* masm, |
483 Object* object, | 536 Handle<Object> object, |
484 const ParameterCount& arguments, | 537 const ParameterCount& arguments, |
485 Label* miss, | 538 Label* miss, |
486 Code::ExtraICState extra_ic_state) { | 539 Code::ExtraICState extra_ic_state) { |
487 // ----------- S t a t e ------------- | 540 // ----------- S t a t e ------------- |
488 // -- r0: receiver | 541 // -- r0: receiver |
489 // -- r1: function to call | 542 // -- r1: function to call |
490 // ----------------------------------- | 543 // ----------------------------------- |
491 | 544 |
492 // Check that the function really is a function. | 545 // Check that the function really is a function. |
493 __ JumpIfSmi(r1, miss); | 546 __ JumpIfSmi(r1, miss); |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
861 StubCompiler* stub_compiler_; | 914 StubCompiler* stub_compiler_; |
862 const ParameterCount& arguments_; | 915 const ParameterCount& arguments_; |
863 Register name_; | 916 Register name_; |
864 Code::ExtraICState extra_ic_state_; | 917 Code::ExtraICState extra_ic_state_; |
865 }; | 918 }; |
866 | 919 |
867 | 920 |
868 // Generate code to check that a global property cell is empty. Create | 921 // 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 | 922 // the property cell at compilation time if no cell exists for the |
870 // property. | 923 // property. |
871 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCell( | 924 static void GenerateCheckPropertyCell(MacroAssembler* masm, |
| 925 Handle<GlobalObject> global, |
| 926 Handle<String> name, |
| 927 Register scratch, |
| 928 Label* miss) { |
| 929 Handle<JSGlobalPropertyCell> cell = |
| 930 GlobalObject::EnsurePropertyCell(global, name); |
| 931 ASSERT(cell->value()->IsTheHole()); |
| 932 __ mov(scratch, Operand(cell)); |
| 933 __ ldr(scratch, |
| 934 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); |
| 935 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
| 936 __ cmp(scratch, ip); |
| 937 __ b(ne, miss); |
| 938 } |
| 939 |
| 940 |
| 941 // TODO(kmillikin): Eliminate this function when the stub cache is fully |
| 942 // handlified. |
| 943 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCell( |
872 MacroAssembler* masm, | 944 MacroAssembler* masm, |
873 GlobalObject* global, | 945 GlobalObject* global, |
874 String* name, | 946 String* name, |
875 Register scratch, | 947 Register scratch, |
876 Label* miss) { | 948 Label* miss) { |
877 Object* probe; | 949 Object* probe; |
878 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); | 950 { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); |
879 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 951 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
880 } | 952 } |
881 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); | 953 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); |
882 ASSERT(cell->value()->IsTheHole()); | 954 ASSERT(cell->value()->IsTheHole()); |
883 __ mov(scratch, Operand(Handle<Object>(cell))); | 955 __ mov(scratch, Operand(Handle<Object>(cell))); |
884 __ ldr(scratch, | 956 __ ldr(scratch, |
885 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); | 957 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); |
886 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 958 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
887 __ cmp(scratch, ip); | 959 __ cmp(scratch, ip); |
888 __ b(ne, miss); | 960 __ b(ne, miss); |
889 return cell; | 961 return cell; |
890 } | 962 } |
891 | 963 |
| 964 |
892 // Calls GenerateCheckPropertyCell for each global object in the prototype chain | 965 // Calls GenerateCheckPropertyCell for each global object in the prototype chain |
893 // from object to (but not including) holder. | 966 // from object to (but not including) holder. |
894 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCells( | 967 static void GenerateCheckPropertyCells(MacroAssembler* masm, |
| 968 Handle<JSObject> object, |
| 969 Handle<JSObject> holder, |
| 970 Handle<String> name, |
| 971 Register scratch, |
| 972 Label* miss) { |
| 973 Handle<JSObject> current = object; |
| 974 while (!current.is_identical_to(holder)) { |
| 975 if (current->IsGlobalObject()) { |
| 976 GenerateCheckPropertyCell(masm, |
| 977 Handle<GlobalObject>::cast(current), |
| 978 name, |
| 979 scratch, |
| 980 miss); |
| 981 } |
| 982 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); |
| 983 } |
| 984 } |
| 985 |
| 986 |
| 987 // TODO(kmillikin): Eliminate this function when the stub cache is fully |
| 988 // handlified. |
| 989 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCells( |
895 MacroAssembler* masm, | 990 MacroAssembler* masm, |
896 JSObject* object, | 991 JSObject* object, |
897 JSObject* holder, | 992 JSObject* holder, |
898 String* name, | 993 String* name, |
899 Register scratch, | 994 Register scratch, |
900 Label* miss) { | 995 Label* miss) { |
901 JSObject* current = object; | 996 JSObject* current = object; |
902 while (current != holder) { | 997 while (current != holder) { |
903 if (current->IsGlobalObject()) { | 998 if (current->IsGlobalObject()) { |
904 // Returns a cell or a failure. | 999 // Returns a cell or a failure. |
905 MaybeObject* result = GenerateCheckPropertyCell( | 1000 MaybeObject* result = TryGenerateCheckPropertyCell( |
906 masm, | 1001 masm, |
907 GlobalObject::cast(current), | 1002 GlobalObject::cast(current), |
908 name, | 1003 name, |
909 scratch, | 1004 scratch, |
910 miss); | 1005 miss); |
911 if (result->IsFailure()) return result; | 1006 if (result->IsFailure()) return result; |
912 } | 1007 } |
913 ASSERT(current->IsJSObject()); | 1008 ASSERT(current->IsJSObject()); |
914 current = JSObject::cast(current->GetPrototype()); | 1009 current = JSObject::cast(current->GetPrototype()); |
915 } | 1010 } |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1020 if (!(biased_exponent & 1)) { | 1115 if (!(biased_exponent & 1)) { |
1021 __ bic(hiword, hiword, Operand(1 << HeapNumber::kExponentShift)); | 1116 __ bic(hiword, hiword, Operand(1 << HeapNumber::kExponentShift)); |
1022 } | 1117 } |
1023 } | 1118 } |
1024 | 1119 |
1025 | 1120 |
1026 #undef __ | 1121 #undef __ |
1027 #define __ ACCESS_MASM(masm()) | 1122 #define __ ACCESS_MASM(masm()) |
1028 | 1123 |
1029 | 1124 |
| 1125 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, |
| 1126 Register object_reg, |
| 1127 Handle<JSObject> holder, |
| 1128 Register holder_reg, |
| 1129 Register scratch1, |
| 1130 Register scratch2, |
| 1131 Handle<String> name, |
| 1132 int save_at_depth, |
| 1133 Label* miss) { |
| 1134 // Make sure there's no overlap between holder and object registers. |
| 1135 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
| 1136 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
| 1137 && !scratch2.is(scratch1)); |
| 1138 |
| 1139 // Keep track of the current object in register reg. |
| 1140 Register reg = object_reg; |
| 1141 int depth = 0; |
| 1142 |
| 1143 if (save_at_depth == depth) { |
| 1144 __ str(reg, MemOperand(sp)); |
| 1145 } |
| 1146 |
| 1147 // Check the maps in the prototype chain. |
| 1148 // Traverse the prototype chain from the object and do map checks. |
| 1149 Handle<JSObject> current = object; |
| 1150 while (!current.is_identical_to(holder)) { |
| 1151 ++depth; |
| 1152 |
| 1153 // Only global objects and objects that do not require access |
| 1154 // checks are allowed in stubs. |
| 1155 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); |
| 1156 |
| 1157 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); |
| 1158 if (!current->HasFastProperties() && |
| 1159 !current->IsJSGlobalObject() && |
| 1160 !current->IsJSGlobalProxy()) { |
| 1161 if (!name->IsSymbol()) { |
| 1162 name = factory()->LookupSymbol(name); |
| 1163 } |
| 1164 ASSERT(current->property_dictionary()->FindEntry(*name) == |
| 1165 StringDictionary::kNotFound); |
| 1166 |
| 1167 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, |
| 1168 scratch1, scratch2); |
| 1169 |
| 1170 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 1171 reg = holder_reg; // From now on the object will be in holder_reg. |
| 1172 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); |
| 1173 } else { |
| 1174 Handle<Map> current_map(current->map()); |
| 1175 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 1176 __ cmp(scratch1, Operand(current_map)); |
| 1177 // Branch on the result of the map check. |
| 1178 __ b(ne, miss); |
| 1179 // Check access rights to the global object. This has to happen after |
| 1180 // the map check so that we know that the object is actually a global |
| 1181 // object. |
| 1182 if (current->IsJSGlobalProxy()) { |
| 1183 __ CheckAccessGlobalProxy(reg, scratch2, miss); |
| 1184 } |
| 1185 reg = holder_reg; // From now on the object will be in holder_reg. |
| 1186 |
| 1187 if (heap()->InNewSpace(*prototype)) { |
| 1188 // The prototype is in new space; we cannot store a reference to it |
| 1189 // in the code. Load it from the map. |
| 1190 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); |
| 1191 } else { |
| 1192 // The prototype is in old space; load it directly. |
| 1193 __ mov(reg, Operand(prototype)); |
| 1194 } |
| 1195 } |
| 1196 |
| 1197 if (save_at_depth == depth) { |
| 1198 __ str(reg, MemOperand(sp)); |
| 1199 } |
| 1200 |
| 1201 // Go to the next object in the prototype chain. |
| 1202 current = prototype; |
| 1203 } |
| 1204 |
| 1205 // Log the check depth. |
| 1206 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); |
| 1207 |
| 1208 // Check the holder map. |
| 1209 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 1210 __ cmp(scratch1, Operand(Handle<Map>(current->map()))); |
| 1211 __ b(ne, miss); |
| 1212 |
| 1213 // Perform security check for access to the global object. |
| 1214 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
| 1215 if (holder->IsJSGlobalProxy()) { |
| 1216 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
| 1217 } |
| 1218 |
| 1219 // If we've skipped any global objects, it's not enough to verify that |
| 1220 // their maps haven't changed. We also need to check that the property |
| 1221 // cell for the property is still empty. |
| 1222 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); |
| 1223 |
| 1224 // Return the register containing the holder. |
| 1225 return reg; |
| 1226 } |
| 1227 |
| 1228 |
| 1229 // TODO(kmillikin): Eliminate this function when the stub cache is fully |
| 1230 // handlified. |
1030 Register StubCompiler::CheckPrototypes(JSObject* object, | 1231 Register StubCompiler::CheckPrototypes(JSObject* object, |
1031 Register object_reg, | 1232 Register object_reg, |
1032 JSObject* holder, | 1233 JSObject* holder, |
1033 Register holder_reg, | 1234 Register holder_reg, |
1034 Register scratch1, | 1235 Register scratch1, |
1035 Register scratch2, | 1236 Register scratch2, |
1036 String* name, | 1237 String* name, |
1037 int save_at_depth, | 1238 int save_at_depth, |
1038 Label* miss) { | 1239 Label* miss) { |
1039 // Make sure there's no overlap between holder and object registers. | 1240 // 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. | 1270 Object* lookup_result = NULL; // Initialization to please compiler. |
1070 if (!maybe_lookup_result->ToObject(&lookup_result)) { | 1271 if (!maybe_lookup_result->ToObject(&lookup_result)) { |
1071 set_failure(Failure::cast(maybe_lookup_result)); | 1272 set_failure(Failure::cast(maybe_lookup_result)); |
1072 return reg; | 1273 return reg; |
1073 } | 1274 } |
1074 name = String::cast(lookup_result); | 1275 name = String::cast(lookup_result); |
1075 } | 1276 } |
1076 ASSERT(current->property_dictionary()->FindEntry(name) == | 1277 ASSERT(current->property_dictionary()->FindEntry(name) == |
1077 StringDictionary::kNotFound); | 1278 StringDictionary::kNotFound); |
1078 | 1279 |
1079 MaybeObject* negative_lookup = GenerateDictionaryNegativeLookup(masm(), | 1280 MaybeObject* negative_lookup = |
1080 miss, | 1281 TryGenerateDictionaryNegativeLookup(masm(), |
1081 reg, | 1282 miss, |
1082 name, | 1283 reg, |
1083 scratch1, | 1284 name, |
1084 scratch2); | 1285 scratch1, |
| 1286 scratch2); |
1085 if (negative_lookup->IsFailure()) { | 1287 if (negative_lookup->IsFailure()) { |
1086 set_failure(Failure::cast(negative_lookup)); | 1288 set_failure(Failure::cast(negative_lookup)); |
1087 return reg; | 1289 return reg; |
1088 } | 1290 } |
1089 | 1291 |
1090 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1292 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
1091 reg = holder_reg; // from now the object is in holder_reg | 1293 reg = holder_reg; // from now the object is in holder_reg |
1092 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | 1294 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); |
1093 } else if (heap()->InNewSpace(prototype)) { | 1295 } else if (heap()->InNewSpace(prototype)) { |
1094 // Get the map of the current object. | 1296 // 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()))); | 1345 __ cmp(scratch1, Operand(Handle<Map>(current->map()))); |
1144 __ b(ne, miss); | 1346 __ b(ne, miss); |
1145 | 1347 |
1146 // Log the check depth. | 1348 // Log the check depth. |
1147 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); | 1349 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); |
1148 | 1350 |
1149 // Perform security check for access to the global object. | 1351 // Perform security check for access to the global object. |
1150 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 1352 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
1151 if (holder->IsJSGlobalProxy()) { | 1353 if (holder->IsJSGlobalProxy()) { |
1152 __ CheckAccessGlobalProxy(reg, scratch1, miss); | 1354 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
1153 }; | 1355 } |
1154 | 1356 |
1155 // If we've skipped any global objects, it's not enough to verify | 1357 // 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 | 1358 // that their maps haven't changed. We also need to check that the |
1157 // property cell for the property is still empty. | 1359 // property cell for the property is still empty. |
1158 MaybeObject* result = GenerateCheckPropertyCells(masm(), | 1360 MaybeObject* result = TryGenerateCheckPropertyCells(masm(), |
1159 object, | 1361 object, |
1160 holder, | 1362 holder, |
1161 name, | 1363 name, |
1162 scratch1, | 1364 scratch1, |
1163 miss); | 1365 miss); |
1164 if (result->IsFailure()) set_failure(Failure::cast(result)); | 1366 if (result->IsFailure()) set_failure(Failure::cast(result)); |
1165 | 1367 |
1166 // Return the register containing the holder. | 1368 // Return the register containing the holder. |
1167 return reg; | 1369 return reg; |
1168 } | 1370 } |
1169 | 1371 |
1170 | 1372 |
1171 void StubCompiler::GenerateLoadField(JSObject* object, | 1373 void StubCompiler::GenerateLoadField(Handle<JSObject> object, |
1172 JSObject* holder, | 1374 Handle<JSObject> holder, |
1173 Register receiver, | 1375 Register receiver, |
1174 Register scratch1, | 1376 Register scratch1, |
1175 Register scratch2, | 1377 Register scratch2, |
1176 Register scratch3, | 1378 Register scratch3, |
1177 int index, | 1379 int index, |
1178 String* name, | 1380 Handle<String> name, |
1179 Label* miss) { | 1381 Label* miss) { |
1180 // Check that the receiver isn't a smi. | 1382 // Check that the receiver isn't a smi. |
1181 __ JumpIfSmi(receiver, miss); | 1383 __ JumpIfSmi(receiver, miss); |
1182 | 1384 |
1183 // Check that the maps haven't changed. | 1385 // Check that the maps haven't changed. |
1184 Register reg = | 1386 Register reg = CheckPrototypes( |
1185 CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, | 1387 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); |
1186 name, miss); | |
1187 GenerateFastPropertyLoad(masm(), r0, reg, holder, index); | 1388 GenerateFastPropertyLoad(masm(), r0, reg, holder, index); |
1188 __ Ret(); | 1389 __ Ret(); |
1189 } | 1390 } |
1190 | 1391 |
1191 | 1392 |
1192 void StubCompiler::GenerateLoadConstant(JSObject* object, | 1393 void StubCompiler::GenerateLoadConstant(Handle<JSObject> object, |
1193 JSObject* holder, | 1394 Handle<JSObject> holder, |
1194 Register receiver, | 1395 Register receiver, |
1195 Register scratch1, | 1396 Register scratch1, |
1196 Register scratch2, | 1397 Register scratch2, |
1197 Register scratch3, | 1398 Register scratch3, |
1198 Object* value, | 1399 Handle<Object> value, |
1199 String* name, | 1400 Handle<String> name, |
1200 Label* miss) { | 1401 Label* miss) { |
1201 // Check that the receiver isn't a smi. | 1402 // Check that the receiver isn't a smi. |
1202 __ JumpIfSmi(receiver, miss); | 1403 __ JumpIfSmi(receiver, miss); |
1203 | 1404 |
1204 // Check that the maps haven't changed. | 1405 // Check that the maps haven't changed. |
1205 CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, name, | 1406 CheckPrototypes( |
1206 miss); | 1407 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); |
1207 | 1408 |
1208 // Return the constant value. | 1409 // Return the constant value. |
1209 __ mov(r0, Operand(Handle<Object>(value))); | 1410 __ mov(r0, Operand(value)); |
1210 __ Ret(); | 1411 __ Ret(); |
1211 } | 1412 } |
1212 | 1413 |
1213 | 1414 |
1214 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, | 1415 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, |
1215 JSObject* holder, | 1416 JSObject* holder, |
1216 Register receiver, | 1417 Register receiver, |
1217 Register name_reg, | 1418 Register name_reg, |
1218 Register scratch1, | 1419 Register scratch1, |
1219 Register scratch2, | 1420 Register scratch2, |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1358 scratch2, | 1559 scratch2, |
1359 scratch3, | 1560 scratch3, |
1360 name, | 1561 name, |
1361 miss); | 1562 miss); |
1362 } | 1563 } |
1363 | 1564 |
1364 if (lookup->type() == FIELD) { | 1565 if (lookup->type() == FIELD) { |
1365 // We found FIELD property in prototype chain of interceptor's holder. | 1566 // We found FIELD property in prototype chain of interceptor's holder. |
1366 // Retrieve a field from field's holder. | 1567 // Retrieve a field from field's holder. |
1367 GenerateFastPropertyLoad(masm(), r0, holder_reg, | 1568 GenerateFastPropertyLoad(masm(), r0, holder_reg, |
1368 lookup->holder(), lookup->GetFieldIndex()); | 1569 Handle<JSObject>(lookup->holder()), |
| 1570 lookup->GetFieldIndex()); |
1369 __ Ret(); | 1571 __ Ret(); |
1370 } else { | 1572 } else { |
1371 // We found CALLBACKS property in prototype chain of interceptor's | 1573 // We found CALLBACKS property in prototype chain of interceptor's |
1372 // holder. | 1574 // holder. |
1373 ASSERT(lookup->type() == CALLBACKS); | 1575 ASSERT(lookup->type() == CALLBACKS); |
1374 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); | 1576 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); |
1375 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); | 1577 AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); |
1376 ASSERT(callback != NULL); | 1578 ASSERT(callback != NULL); |
1377 ASSERT(callback->getter() != NULL); | 1579 ASSERT(callback->getter() != NULL); |
1378 | 1580 |
(...skipping 30 matching lines...) Expand all Loading... |
1409 name_reg, interceptor_holder); | 1611 name_reg, interceptor_holder); |
1410 | 1612 |
1411 ExternalReference ref = | 1613 ExternalReference ref = |
1412 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), | 1614 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), |
1413 masm()->isolate()); | 1615 masm()->isolate()); |
1414 __ TailCallExternalReference(ref, 5, 1); | 1616 __ TailCallExternalReference(ref, 5, 1); |
1415 } | 1617 } |
1416 } | 1618 } |
1417 | 1619 |
1418 | 1620 |
1419 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { | 1621 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) { |
1420 if (kind_ == Code::KEYED_CALL_IC) { | 1622 if (kind_ == Code::KEYED_CALL_IC) { |
1421 __ cmp(r2, Operand(Handle<String>(name))); | 1623 __ cmp(r2, Operand(name)); |
1422 __ b(ne, miss); | 1624 __ b(ne, miss); |
1423 } | 1625 } |
1424 } | 1626 } |
1425 | 1627 |
1426 | 1628 |
1427 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, | 1629 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, |
1428 JSObject* holder, | 1630 JSObject* holder, |
1429 String* name, | 1631 String* name, |
1430 Label* miss) { | 1632 Label* miss) { |
1431 ASSERT(holder->IsGlobalObject()); | 1633 ASSERT(holder->IsGlobalObject()); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1471 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | 1673 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
1472 __ cmp(r4, r3); | 1674 __ cmp(r4, r3); |
1473 __ b(ne, miss); | 1675 __ b(ne, miss); |
1474 } else { | 1676 } else { |
1475 __ cmp(r1, Operand(Handle<JSFunction>(function))); | 1677 __ cmp(r1, Operand(Handle<JSFunction>(function))); |
1476 __ b(ne, miss); | 1678 __ b(ne, miss); |
1477 } | 1679 } |
1478 } | 1680 } |
1479 | 1681 |
1480 | 1682 |
1481 MaybeObject* CallStubCompiler::GenerateMissBranch() { | 1683 void CallStubCompiler::GenerateMissBranch() { |
1482 MaybeObject* maybe_obj = | 1684 Handle<Code> code = |
1483 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), | 1685 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), |
1484 kind_, | 1686 kind_, |
1485 extra_ic_state_); | 1687 extra_state_); |
| 1688 __ Jump(code, RelocInfo::CODE_TARGET); |
| 1689 } |
| 1690 |
| 1691 |
| 1692 // TODO(kmillikin): Eliminate this function when the stub cache is fully |
| 1693 // handlified. |
| 1694 MaybeObject* CallStubCompiler::TryGenerateMissBranch() { |
| 1695 MaybeObject* maybe_obj = |
| 1696 isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(), |
| 1697 kind_, |
| 1698 extra_state_); |
1486 Object* obj; | 1699 Object* obj; |
1487 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1700 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
1488 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); | 1701 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); |
1489 return obj; | 1702 return obj; |
1490 } | 1703 } |
1491 | 1704 |
1492 | 1705 |
1493 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object, | 1706 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, |
1494 JSObject* holder, | 1707 Handle<JSObject> holder, |
1495 int index, | 1708 int index, |
1496 String* name) { | 1709 Handle<String> name) { |
1497 // ----------- S t a t e ------------- | 1710 // ----------- S t a t e ------------- |
1498 // -- r2 : name | 1711 // -- r2 : name |
1499 // -- lr : return address | 1712 // -- lr : return address |
1500 // ----------------------------------- | 1713 // ----------------------------------- |
1501 Label miss; | 1714 Label miss; |
1502 | 1715 |
1503 GenerateNameCheck(name, &miss); | 1716 GenerateNameCheck(name, &miss); |
1504 | 1717 |
1505 const int argc = arguments().immediate(); | 1718 const int argc = arguments().immediate(); |
1506 | 1719 |
1507 // Get the receiver of the function from the stack into r0. | 1720 // Get the receiver of the function from the stack into r0. |
1508 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 1721 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
1509 // Check that the receiver isn't a smi. | 1722 // Check that the receiver isn't a smi. |
1510 __ JumpIfSmi(r0, &miss); | 1723 __ JumpIfSmi(r0, &miss); |
1511 | 1724 |
1512 // Do the right check and compute the holder register. | 1725 // Do the right check and compute the holder register. |
1513 Register reg = CheckPrototypes(object, r0, holder, r1, r3, r4, name, &miss); | 1726 Register reg = CheckPrototypes(object, r0, holder, r1, r3, r4, name, &miss); |
1514 GenerateFastPropertyLoad(masm(), r1, reg, holder, index); | 1727 GenerateFastPropertyLoad(masm(), r1, reg, holder, index); |
1515 | 1728 |
1516 GenerateCallFunction(masm(), object, arguments(), &miss, extra_ic_state_); | 1729 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); |
1517 | 1730 |
1518 // Handle call cache miss. | 1731 // Handle call cache miss. |
1519 __ bind(&miss); | 1732 __ bind(&miss); |
1520 MaybeObject* maybe_result = GenerateMissBranch(); | 1733 GenerateMissBranch(); |
1521 if (maybe_result->IsFailure()) return maybe_result; | |
1522 | 1734 |
1523 // Return the generated code. | 1735 // Return the generated code. |
1524 return GetCode(FIELD, name); | 1736 return GetCode(FIELD, name); |
1525 } | 1737 } |
1526 | 1738 |
1527 | 1739 |
1528 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, | 1740 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, |
1529 JSObject* holder, | 1741 JSObject* holder, |
1530 JSGlobalPropertyCell* cell, | 1742 JSGlobalPropertyCell* cell, |
1531 JSFunction* function, | 1743 JSFunction* function, |
1532 String* name) { | 1744 String* name) { |
1533 // ----------- S t a t e ------------- | 1745 // ----------- S t a t e ------------- |
1534 // -- r2 : name | 1746 // -- r2 : name |
1535 // -- lr : return address | 1747 // -- lr : return address |
1536 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 1748 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
1537 // -- ... | 1749 // -- ... |
1538 // -- sp[argc * 4] : receiver | 1750 // -- sp[argc * 4] : receiver |
1539 // ----------------------------------- | 1751 // ----------------------------------- |
1540 | 1752 |
1541 // If object is not an array, bail out to regular call. | 1753 // If object is not an array, bail out to regular call. |
1542 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); | 1754 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); |
1543 | 1755 |
1544 Label miss; | 1756 Label miss; |
1545 | 1757 |
1546 GenerateNameCheck(name, &miss); | 1758 GenerateNameCheck(Handle<String>(name), &miss); |
1547 | 1759 |
1548 Register receiver = r1; | 1760 Register receiver = r1; |
1549 | 1761 |
1550 // Get the receiver from the stack | 1762 // Get the receiver from the stack |
1551 const int argc = arguments().immediate(); | 1763 const int argc = arguments().immediate(); |
1552 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); | 1764 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); |
1553 | 1765 |
1554 // Check that the receiver isn't a smi. | 1766 // Check that the receiver isn't a smi. |
1555 __ JumpIfSmi(receiver, &miss); | 1767 __ JumpIfSmi(receiver, &miss); |
1556 | 1768 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1612 FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize; | 1824 FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize; |
1613 __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex)); | 1825 __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex)); |
1614 | 1826 |
1615 // Check for a smi. | 1827 // Check for a smi. |
1616 __ Drop(argc + 1); | 1828 __ Drop(argc + 1); |
1617 __ Ret(); | 1829 __ Ret(); |
1618 | 1830 |
1619 __ bind(&with_write_barrier); | 1831 __ bind(&with_write_barrier); |
1620 | 1832 |
1621 __ ldr(r6, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 1833 __ ldr(r6, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
1622 __ CheckFastSmiOnlyElements(r6, r6, &call_builtin); | 1834 __ CheckFastObjectElements(r6, r6, &call_builtin); |
1623 | 1835 |
1624 // Save new length. | 1836 // Save new length. |
1625 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1837 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
1626 | 1838 |
1627 // Push the element. | 1839 // Push the element. |
1628 // We may need a register containing the address end_elements below, | 1840 // We may need a register containing the address end_elements below, |
1629 // so write back the value in end_elements. | 1841 // so write back the value in end_elements. |
1630 __ add(end_elements, elements, | 1842 __ add(end_elements, elements, |
1631 Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); | 1843 Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); |
1632 __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex)); | 1844 __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex)); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1702 } | 1914 } |
1703 __ bind(&call_builtin); | 1915 __ bind(&call_builtin); |
1704 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, | 1916 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, |
1705 masm()->isolate()), | 1917 masm()->isolate()), |
1706 argc + 1, | 1918 argc + 1, |
1707 1); | 1919 1); |
1708 } | 1920 } |
1709 | 1921 |
1710 // Handle call cache miss. | 1922 // Handle call cache miss. |
1711 __ bind(&miss); | 1923 __ bind(&miss); |
1712 MaybeObject* maybe_result = GenerateMissBranch(); | 1924 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1713 if (maybe_result->IsFailure()) return maybe_result; | 1925 if (maybe_result->IsFailure()) return maybe_result; |
1714 | 1926 |
1715 // Return the generated code. | 1927 // Return the generated code. |
1716 return GetCode(function); | 1928 return TryGetCode(function); |
1717 } | 1929 } |
1718 | 1930 |
1719 | 1931 |
1720 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, | 1932 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, |
1721 JSObject* holder, | 1933 JSObject* holder, |
1722 JSGlobalPropertyCell* cell, | 1934 JSGlobalPropertyCell* cell, |
1723 JSFunction* function, | 1935 JSFunction* function, |
1724 String* name) { | 1936 String* name) { |
1725 // ----------- S t a t e ------------- | 1937 // ----------- S t a t e ------------- |
1726 // -- r2 : name | 1938 // -- r2 : name |
1727 // -- lr : return address | 1939 // -- lr : return address |
1728 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 1940 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
1729 // -- ... | 1941 // -- ... |
1730 // -- sp[argc * 4] : receiver | 1942 // -- sp[argc * 4] : receiver |
1731 // ----------------------------------- | 1943 // ----------------------------------- |
1732 | 1944 |
1733 // If object is not an array, bail out to regular call. | 1945 // If object is not an array, bail out to regular call. |
1734 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); | 1946 if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); |
1735 | 1947 |
1736 Label miss, return_undefined, call_builtin; | 1948 Label miss, return_undefined, call_builtin; |
1737 | 1949 |
1738 Register receiver = r1; | 1950 Register receiver = r1; |
1739 Register elements = r3; | 1951 Register elements = r3; |
1740 | 1952 |
1741 GenerateNameCheck(name, &miss); | 1953 GenerateNameCheck(Handle<String>(name), &miss); |
1742 | 1954 |
1743 // Get the receiver from the stack | 1955 // Get the receiver from the stack |
1744 const int argc = arguments().immediate(); | 1956 const int argc = arguments().immediate(); |
1745 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); | 1957 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); |
1746 | 1958 |
1747 // Check that the receiver isn't a smi. | 1959 // Check that the receiver isn't a smi. |
1748 __ JumpIfSmi(receiver, &miss); | 1960 __ JumpIfSmi(receiver, &miss); |
1749 | 1961 |
1750 // Check that the maps haven't changed. | 1962 // Check that the maps haven't changed. |
1751 CheckPrototypes(JSObject::cast(object), | 1963 CheckPrototypes(JSObject::cast(object), |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1791 __ Ret(); | 2003 __ Ret(); |
1792 | 2004 |
1793 __ bind(&call_builtin); | 2005 __ bind(&call_builtin); |
1794 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop, | 2006 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop, |
1795 masm()->isolate()), | 2007 masm()->isolate()), |
1796 argc + 1, | 2008 argc + 1, |
1797 1); | 2009 1); |
1798 | 2010 |
1799 // Handle call cache miss. | 2011 // Handle call cache miss. |
1800 __ bind(&miss); | 2012 __ bind(&miss); |
1801 MaybeObject* maybe_result = GenerateMissBranch(); | 2013 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1802 if (maybe_result->IsFailure()) return maybe_result; | 2014 if (maybe_result->IsFailure()) return maybe_result; |
1803 | 2015 |
1804 // Return the generated code. | 2016 // Return the generated code. |
1805 return GetCode(function); | 2017 return TryGetCode(function); |
1806 } | 2018 } |
1807 | 2019 |
1808 | 2020 |
1809 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( | 2021 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( |
1810 Object* object, | 2022 Object* object, |
1811 JSObject* holder, | 2023 JSObject* holder, |
1812 JSGlobalPropertyCell* cell, | 2024 JSGlobalPropertyCell* cell, |
1813 JSFunction* function, | 2025 JSFunction* function, |
1814 String* name) { | 2026 String* name) { |
1815 // ----------- S t a t e ------------- | 2027 // ----------- S t a t e ------------- |
1816 // -- r2 : function name | 2028 // -- r2 : function name |
1817 // -- lr : return address | 2029 // -- lr : return address |
1818 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2030 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
1819 // -- ... | 2031 // -- ... |
1820 // -- sp[argc * 4] : receiver | 2032 // -- sp[argc * 4] : receiver |
1821 // ----------------------------------- | 2033 // ----------------------------------- |
1822 | 2034 |
1823 // If object is not a string, bail out to regular call. | 2035 // If object is not a string, bail out to regular call. |
1824 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); | 2036 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); |
1825 | 2037 |
1826 const int argc = arguments().immediate(); | 2038 const int argc = arguments().immediate(); |
1827 | 2039 |
1828 Label miss; | 2040 Label miss; |
1829 Label name_miss; | 2041 Label name_miss; |
1830 Label index_out_of_range; | 2042 Label index_out_of_range; |
1831 Label* index_out_of_range_label = &index_out_of_range; | 2043 Label* index_out_of_range_label = &index_out_of_range; |
1832 | 2044 |
1833 if (kind_ == Code::CALL_IC && | 2045 if (kind_ == Code::CALL_IC && |
1834 (CallICBase::StringStubState::decode(extra_ic_state_) == | 2046 (CallICBase::StringStubState::decode(extra_state_) == |
1835 DEFAULT_STRING_STUB)) { | 2047 DEFAULT_STRING_STUB)) { |
1836 index_out_of_range_label = &miss; | 2048 index_out_of_range_label = &miss; |
1837 } | 2049 } |
1838 | 2050 |
1839 GenerateNameCheck(name, &name_miss); | 2051 GenerateNameCheck(Handle<String>(name), &name_miss); |
1840 | 2052 |
1841 // Check that the maps starting from the prototype haven't changed. | 2053 // Check that the maps starting from the prototype haven't changed. |
1842 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2054 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
1843 Context::STRING_FUNCTION_INDEX, | 2055 Context::STRING_FUNCTION_INDEX, |
1844 r0, | 2056 r0, |
1845 &miss); | 2057 &miss); |
1846 ASSERT(object != holder); | 2058 ASSERT(object != holder); |
1847 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, | 2059 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, |
1848 r1, r3, r4, name, &miss); | 2060 r1, r3, r4, name, &miss); |
1849 | 2061 |
(...skipping 27 matching lines...) Expand all Loading... |
1877 __ bind(&index_out_of_range); | 2089 __ bind(&index_out_of_range); |
1878 __ LoadRoot(r0, Heap::kNanValueRootIndex); | 2090 __ LoadRoot(r0, Heap::kNanValueRootIndex); |
1879 __ Drop(argc + 1); | 2091 __ Drop(argc + 1); |
1880 __ Ret(); | 2092 __ Ret(); |
1881 } | 2093 } |
1882 | 2094 |
1883 __ bind(&miss); | 2095 __ bind(&miss); |
1884 // Restore function name in r2. | 2096 // Restore function name in r2. |
1885 __ Move(r2, Handle<String>(name)); | 2097 __ Move(r2, Handle<String>(name)); |
1886 __ bind(&name_miss); | 2098 __ bind(&name_miss); |
1887 MaybeObject* maybe_result = GenerateMissBranch(); | 2099 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1888 if (maybe_result->IsFailure()) return maybe_result; | 2100 if (maybe_result->IsFailure()) return maybe_result; |
1889 | 2101 |
1890 // Return the generated code. | 2102 // Return the generated code. |
1891 return GetCode(function); | 2103 return TryGetCode(function); |
1892 } | 2104 } |
1893 | 2105 |
1894 | 2106 |
1895 MaybeObject* CallStubCompiler::CompileStringCharAtCall( | 2107 MaybeObject* CallStubCompiler::CompileStringCharAtCall( |
1896 Object* object, | 2108 Object* object, |
1897 JSObject* holder, | 2109 JSObject* holder, |
1898 JSGlobalPropertyCell* cell, | 2110 JSGlobalPropertyCell* cell, |
1899 JSFunction* function, | 2111 JSFunction* function, |
1900 String* name) { | 2112 String* name) { |
1901 // ----------- S t a t e ------------- | 2113 // ----------- S t a t e ------------- |
1902 // -- r2 : function name | 2114 // -- r2 : function name |
1903 // -- lr : return address | 2115 // -- lr : return address |
1904 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2116 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
1905 // -- ... | 2117 // -- ... |
1906 // -- sp[argc * 4] : receiver | 2118 // -- sp[argc * 4] : receiver |
1907 // ----------------------------------- | 2119 // ----------------------------------- |
1908 | 2120 |
1909 // If object is not a string, bail out to regular call. | 2121 // If object is not a string, bail out to regular call. |
1910 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); | 2122 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); |
1911 | 2123 |
1912 const int argc = arguments().immediate(); | 2124 const int argc = arguments().immediate(); |
1913 | 2125 |
1914 Label miss; | 2126 Label miss; |
1915 Label name_miss; | 2127 Label name_miss; |
1916 Label index_out_of_range; | 2128 Label index_out_of_range; |
1917 Label* index_out_of_range_label = &index_out_of_range; | 2129 Label* index_out_of_range_label = &index_out_of_range; |
1918 | 2130 |
1919 if (kind_ == Code::CALL_IC && | 2131 if (kind_ == Code::CALL_IC && |
1920 (CallICBase::StringStubState::decode(extra_ic_state_) == | 2132 (CallICBase::StringStubState::decode(extra_state_) == |
1921 DEFAULT_STRING_STUB)) { | 2133 DEFAULT_STRING_STUB)) { |
1922 index_out_of_range_label = &miss; | 2134 index_out_of_range_label = &miss; |
1923 } | 2135 } |
1924 | 2136 |
1925 GenerateNameCheck(name, &name_miss); | 2137 GenerateNameCheck(Handle<String>(name), &name_miss); |
1926 | 2138 |
1927 // Check that the maps starting from the prototype haven't changed. | 2139 // Check that the maps starting from the prototype haven't changed. |
1928 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2140 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
1929 Context::STRING_FUNCTION_INDEX, | 2141 Context::STRING_FUNCTION_INDEX, |
1930 r0, | 2142 r0, |
1931 &miss); | 2143 &miss); |
1932 ASSERT(object != holder); | 2144 ASSERT(object != holder); |
1933 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, | 2145 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, |
1934 r1, r3, r4, name, &miss); | 2146 r1, r3, r4, name, &miss); |
1935 | 2147 |
(...skipping 29 matching lines...) Expand all Loading... |
1965 __ bind(&index_out_of_range); | 2177 __ bind(&index_out_of_range); |
1966 __ LoadRoot(r0, Heap::kEmptyStringRootIndex); | 2178 __ LoadRoot(r0, Heap::kEmptyStringRootIndex); |
1967 __ Drop(argc + 1); | 2179 __ Drop(argc + 1); |
1968 __ Ret(); | 2180 __ Ret(); |
1969 } | 2181 } |
1970 | 2182 |
1971 __ bind(&miss); | 2183 __ bind(&miss); |
1972 // Restore function name in r2. | 2184 // Restore function name in r2. |
1973 __ Move(r2, Handle<String>(name)); | 2185 __ Move(r2, Handle<String>(name)); |
1974 __ bind(&name_miss); | 2186 __ bind(&name_miss); |
1975 MaybeObject* maybe_result = GenerateMissBranch(); | 2187 MaybeObject* maybe_result = TryGenerateMissBranch(); |
1976 if (maybe_result->IsFailure()) return maybe_result; | 2188 if (maybe_result->IsFailure()) return maybe_result; |
1977 | 2189 |
1978 // Return the generated code. | 2190 // Return the generated code. |
1979 return GetCode(function); | 2191 return TryGetCode(function); |
1980 } | 2192 } |
1981 | 2193 |
1982 | 2194 |
1983 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( | 2195 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( |
1984 Object* object, | 2196 Object* object, |
1985 JSObject* holder, | 2197 JSObject* holder, |
1986 JSGlobalPropertyCell* cell, | 2198 JSGlobalPropertyCell* cell, |
1987 JSFunction* function, | 2199 JSFunction* function, |
1988 String* name) { | 2200 String* name) { |
1989 // ----------- S t a t e ------------- | 2201 // ----------- S t a t e ------------- |
1990 // -- r2 : function name | 2202 // -- r2 : function name |
1991 // -- lr : return address | 2203 // -- lr : return address |
1992 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2204 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
1993 // -- ... | 2205 // -- ... |
1994 // -- sp[argc * 4] : receiver | 2206 // -- sp[argc * 4] : receiver |
1995 // ----------------------------------- | 2207 // ----------------------------------- |
1996 | 2208 |
1997 const int argc = arguments().immediate(); | 2209 const int argc = arguments().immediate(); |
1998 | 2210 |
1999 // If the object is not a JSObject or we got an unexpected number of | 2211 // If the object is not a JSObject or we got an unexpected number of |
2000 // arguments, bail out to the regular call. | 2212 // arguments, bail out to the regular call. |
2001 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 2213 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); |
2002 | 2214 |
2003 Label miss; | 2215 Label miss; |
2004 GenerateNameCheck(name, &miss); | 2216 GenerateNameCheck(Handle<String>(name), &miss); |
2005 | 2217 |
2006 if (cell == NULL) { | 2218 if (cell == NULL) { |
2007 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); | 2219 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); |
2008 | 2220 |
2009 STATIC_ASSERT(kSmiTag == 0); | 2221 STATIC_ASSERT(kSmiTag == 0); |
2010 __ JumpIfSmi(r1, &miss); | 2222 __ JumpIfSmi(r1, &miss); |
2011 | 2223 |
2012 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, | 2224 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, |
2013 &miss); | 2225 &miss); |
2014 } else { | 2226 } else { |
(...skipping 22 matching lines...) Expand all Loading... |
2037 StubRuntimeCallHelper call_helper; | 2249 StubRuntimeCallHelper call_helper; |
2038 char_from_code_generator.GenerateSlow(masm(), call_helper); | 2250 char_from_code_generator.GenerateSlow(masm(), call_helper); |
2039 | 2251 |
2040 // Tail call the full function. We do not have to patch the receiver | 2252 // Tail call the full function. We do not have to patch the receiver |
2041 // because the function makes no use of it. | 2253 // because the function makes no use of it. |
2042 __ bind(&slow); | 2254 __ bind(&slow); |
2043 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); | 2255 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); |
2044 | 2256 |
2045 __ bind(&miss); | 2257 __ bind(&miss); |
2046 // r2: function name. | 2258 // r2: function name. |
2047 MaybeObject* maybe_result = GenerateMissBranch(); | 2259 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2048 if (maybe_result->IsFailure()) return maybe_result; | 2260 if (maybe_result->IsFailure()) return maybe_result; |
2049 | 2261 |
2050 // Return the generated code. | 2262 // Return the generated code. |
2051 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2263 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); |
2052 } | 2264 } |
2053 | 2265 |
2054 | 2266 |
2055 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, | 2267 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, |
2056 JSObject* holder, | 2268 JSObject* holder, |
2057 JSGlobalPropertyCell* cell, | 2269 JSGlobalPropertyCell* cell, |
2058 JSFunction* function, | 2270 JSFunction* function, |
2059 String* name) { | 2271 String* name) { |
2060 // ----------- S t a t e ------------- | 2272 // ----------- S t a t e ------------- |
2061 // -- r2 : function name | 2273 // -- r2 : function name |
2062 // -- lr : return address | 2274 // -- lr : return address |
2063 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2275 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
2064 // -- ... | 2276 // -- ... |
2065 // -- sp[argc * 4] : receiver | 2277 // -- sp[argc * 4] : receiver |
2066 // ----------------------------------- | 2278 // ----------------------------------- |
2067 | 2279 |
2068 if (!CpuFeatures::IsSupported(VFP3)) { | 2280 if (!CpuFeatures::IsSupported(VFP3)) { |
2069 return heap()->undefined_value(); | 2281 return heap()->undefined_value(); |
2070 } | 2282 } |
2071 | 2283 |
2072 CpuFeatures::Scope scope_vfp3(VFP3); | 2284 CpuFeatures::Scope scope_vfp3(VFP3); |
2073 | 2285 |
2074 const int argc = arguments().immediate(); | 2286 const int argc = arguments().immediate(); |
2075 | 2287 |
2076 // If the object is not a JSObject or we got an unexpected number of | 2288 // If the object is not a JSObject or we got an unexpected number of |
2077 // arguments, bail out to the regular call. | 2289 // arguments, bail out to the regular call. |
2078 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 2290 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); |
2079 | 2291 |
2080 Label miss, slow; | 2292 Label miss, slow; |
2081 GenerateNameCheck(name, &miss); | 2293 GenerateNameCheck(Handle<String>(name), &miss); |
2082 | 2294 |
2083 if (cell == NULL) { | 2295 if (cell == NULL) { |
2084 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); | 2296 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); |
2085 | 2297 |
2086 STATIC_ASSERT(kSmiTag == 0); | 2298 STATIC_ASSERT(kSmiTag == 0); |
2087 __ JumpIfSmi(r1, &miss); | 2299 __ JumpIfSmi(r1, &miss); |
2088 | 2300 |
2089 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, | 2301 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, |
2090 &miss); | 2302 &miss); |
2091 } else { | 2303 } else { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2185 // Restore FPCSR and fall to slow case. | 2397 // Restore FPCSR and fall to slow case. |
2186 __ vmsr(r3); | 2398 __ vmsr(r3); |
2187 | 2399 |
2188 __ bind(&slow); | 2400 __ bind(&slow); |
2189 // Tail call the full function. We do not have to patch the receiver | 2401 // Tail call the full function. We do not have to patch the receiver |
2190 // because the function makes no use of it. | 2402 // because the function makes no use of it. |
2191 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); | 2403 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); |
2192 | 2404 |
2193 __ bind(&miss); | 2405 __ bind(&miss); |
2194 // r2: function name. | 2406 // r2: function name. |
2195 MaybeObject* maybe_result = GenerateMissBranch(); | 2407 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2196 if (maybe_result->IsFailure()) return maybe_result; | 2408 if (maybe_result->IsFailure()) return maybe_result; |
2197 | 2409 |
2198 // Return the generated code. | 2410 // Return the generated code. |
2199 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2411 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); |
2200 } | 2412 } |
2201 | 2413 |
2202 | 2414 |
2203 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, | 2415 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, |
2204 JSObject* holder, | 2416 JSObject* holder, |
2205 JSGlobalPropertyCell* cell, | 2417 JSGlobalPropertyCell* cell, |
2206 JSFunction* function, | 2418 JSFunction* function, |
2207 String* name) { | 2419 String* name) { |
2208 // ----------- S t a t e ------------- | 2420 // ----------- S t a t e ------------- |
2209 // -- r2 : function name | 2421 // -- r2 : function name |
2210 // -- lr : return address | 2422 // -- lr : return address |
2211 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2423 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
2212 // -- ... | 2424 // -- ... |
2213 // -- sp[argc * 4] : receiver | 2425 // -- sp[argc * 4] : receiver |
2214 // ----------------------------------- | 2426 // ----------------------------------- |
2215 | 2427 |
2216 const int argc = arguments().immediate(); | 2428 const int argc = arguments().immediate(); |
2217 | 2429 |
2218 // If the object is not a JSObject or we got an unexpected number of | 2430 // If the object is not a JSObject or we got an unexpected number of |
2219 // arguments, bail out to the regular call. | 2431 // arguments, bail out to the regular call. |
2220 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 2432 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); |
2221 | 2433 |
2222 Label miss; | 2434 Label miss; |
2223 GenerateNameCheck(name, &miss); | 2435 GenerateNameCheck(Handle<String>(name), &miss); |
2224 | 2436 |
2225 if (cell == NULL) { | 2437 if (cell == NULL) { |
2226 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); | 2438 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); |
2227 | 2439 |
2228 STATIC_ASSERT(kSmiTag == 0); | 2440 STATIC_ASSERT(kSmiTag == 0); |
2229 __ JumpIfSmi(r1, &miss); | 2441 __ JumpIfSmi(r1, &miss); |
2230 | 2442 |
2231 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, | 2443 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, |
2232 &miss); | 2444 &miss); |
2233 } else { | 2445 } else { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2286 __ Drop(argc + 1); | 2498 __ Drop(argc + 1); |
2287 __ Ret(); | 2499 __ Ret(); |
2288 | 2500 |
2289 // Tail call the full function. We do not have to patch the receiver | 2501 // Tail call the full function. We do not have to patch the receiver |
2290 // because the function makes no use of it. | 2502 // because the function makes no use of it. |
2291 __ bind(&slow); | 2503 __ bind(&slow); |
2292 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); | 2504 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); |
2293 | 2505 |
2294 __ bind(&miss); | 2506 __ bind(&miss); |
2295 // r2: function name. | 2507 // r2: function name. |
2296 MaybeObject* maybe_result = GenerateMissBranch(); | 2508 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2297 if (maybe_result->IsFailure()) return maybe_result; | 2509 if (maybe_result->IsFailure()) return maybe_result; |
2298 | 2510 |
2299 // Return the generated code. | 2511 // Return the generated code. |
2300 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2512 return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); |
2301 } | 2513 } |
2302 | 2514 |
2303 | 2515 |
2304 MaybeObject* CallStubCompiler::CompileFastApiCall( | 2516 MaybeObject* CallStubCompiler::CompileFastApiCall( |
2305 const CallOptimization& optimization, | 2517 const CallOptimization& optimization, |
2306 Object* object, | 2518 Object* object, |
2307 JSObject* holder, | 2519 JSObject* holder, |
2308 JSGlobalPropertyCell* cell, | 2520 JSGlobalPropertyCell* cell, |
2309 JSFunction* function, | 2521 JSFunction* function, |
2310 String* name) { | 2522 String* name) { |
2311 Counters* counters = isolate()->counters(); | 2523 Counters* counters = isolate()->counters(); |
2312 | 2524 |
2313 ASSERT(optimization.is_simple_api_call()); | 2525 ASSERT(optimization.is_simple_api_call()); |
2314 // Bail out if object is a global object as we don't want to | 2526 // Bail out if object is a global object as we don't want to |
2315 // repatch it to global receiver. | 2527 // repatch it to global receiver. |
2316 if (object->IsGlobalObject()) return heap()->undefined_value(); | 2528 if (object->IsGlobalObject()) return heap()->undefined_value(); |
2317 if (cell != NULL) return heap()->undefined_value(); | 2529 if (cell != NULL) return heap()->undefined_value(); |
2318 if (!object->IsJSObject()) return heap()->undefined_value(); | 2530 if (!object->IsJSObject()) return heap()->undefined_value(); |
2319 int depth = optimization.GetPrototypeDepthOfExpectedType( | 2531 int depth = optimization.GetPrototypeDepthOfExpectedType( |
2320 JSObject::cast(object), holder); | 2532 JSObject::cast(object), holder); |
2321 if (depth == kInvalidProtoDepth) return heap()->undefined_value(); | 2533 if (depth == kInvalidProtoDepth) return heap()->undefined_value(); |
2322 | 2534 |
2323 Label miss, miss_before_stack_reserved; | 2535 Label miss, miss_before_stack_reserved; |
2324 | 2536 |
2325 GenerateNameCheck(name, &miss_before_stack_reserved); | 2537 GenerateNameCheck(Handle<String>(name), &miss_before_stack_reserved); |
2326 | 2538 |
2327 // Get the receiver from the stack. | 2539 // Get the receiver from the stack. |
2328 const int argc = arguments().immediate(); | 2540 const int argc = arguments().immediate(); |
2329 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 2541 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
2330 | 2542 |
2331 // Check that the receiver isn't a smi. | 2543 // Check that the receiver isn't a smi. |
2332 __ JumpIfSmi(r1, &miss_before_stack_reserved); | 2544 __ JumpIfSmi(r1, &miss_before_stack_reserved); |
2333 | 2545 |
2334 __ IncrementCounter(counters->call_const(), 1, r0, r3); | 2546 __ IncrementCounter(counters->call_const(), 1, r0, r3); |
2335 __ IncrementCounter(counters->call_const_fast_api(), 1, r0, r3); | 2547 __ IncrementCounter(counters->call_const_fast_api(), 1, r0, r3); |
2336 | 2548 |
2337 ReserveSpaceForFastApiCall(masm(), r0); | 2549 ReserveSpaceForFastApiCall(masm(), r0); |
2338 | 2550 |
2339 // Check that the maps haven't changed and find a Holder as a side effect. | 2551 // 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, | 2552 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, |
2341 depth, &miss); | 2553 depth, &miss); |
2342 | 2554 |
2343 MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); | 2555 MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); |
2344 if (result->IsFailure()) return result; | 2556 if (result->IsFailure()) return result; |
2345 | 2557 |
2346 __ bind(&miss); | 2558 __ bind(&miss); |
2347 FreeSpaceForFastApiCall(masm()); | 2559 FreeSpaceForFastApiCall(masm()); |
2348 | 2560 |
2349 __ bind(&miss_before_stack_reserved); | 2561 __ bind(&miss_before_stack_reserved); |
2350 MaybeObject* maybe_result = GenerateMissBranch(); | 2562 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2351 if (maybe_result->IsFailure()) return maybe_result; | 2563 if (maybe_result->IsFailure()) return maybe_result; |
2352 | 2564 |
2353 // Return the generated code. | 2565 // Return the generated code. |
2354 return GetCode(function); | 2566 return TryGetCode(function); |
2355 } | 2567 } |
2356 | 2568 |
2357 | 2569 |
2358 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, | 2570 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, |
2359 JSObject* holder, | 2571 JSObject* holder, |
2360 JSFunction* function, | 2572 JSFunction* function, |
2361 String* name, | 2573 String* name, |
2362 CheckType check) { | 2574 CheckType check) { |
2363 // ----------- S t a t e ------------- | 2575 // ----------- S t a t e ------------- |
2364 // -- r2 : name | 2576 // -- r2 : name |
2365 // -- lr : return address | 2577 // -- lr : return address |
2366 // ----------------------------------- | 2578 // ----------------------------------- |
2367 if (HasCustomCallGenerator(function)) { | 2579 if (HasCustomCallGenerator(function)) { |
2368 MaybeObject* maybe_result = CompileCustomCall( | 2580 MaybeObject* maybe_result = CompileCustomCall( |
2369 object, holder, NULL, function, name); | 2581 object, holder, NULL, function, name); |
2370 Object* result; | 2582 Object* result; |
2371 if (!maybe_result->ToObject(&result)) return maybe_result; | 2583 if (!maybe_result->ToObject(&result)) return maybe_result; |
2372 // undefined means bail out to regular compiler. | 2584 // undefined means bail out to regular compiler. |
2373 if (!result->IsUndefined()) return result; | 2585 if (!result->IsUndefined()) return result; |
2374 } | 2586 } |
2375 | 2587 |
2376 Label miss; | 2588 Label miss; |
2377 | 2589 |
2378 GenerateNameCheck(name, &miss); | 2590 GenerateNameCheck(Handle<String>(name), &miss); |
2379 | 2591 |
2380 // Get the receiver from the stack | 2592 // Get the receiver from the stack |
2381 const int argc = arguments().immediate(); | 2593 const int argc = arguments().immediate(); |
2382 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 2594 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
2383 | 2595 |
2384 // Check that the receiver isn't a smi. | 2596 // Check that the receiver isn't a smi. |
2385 if (check != NUMBER_CHECK) { | 2597 if (check != NUMBER_CHECK) { |
2386 __ JumpIfSmi(r1, &miss); | 2598 __ JumpIfSmi(r1, &miss); |
2387 } | 2599 } |
2388 | 2600 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2467 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, r3, | 2679 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, r3, |
2468 r1, r4, name, &miss); | 2680 r1, r4, name, &miss); |
2469 } | 2681 } |
2470 break; | 2682 break; |
2471 } | 2683 } |
2472 | 2684 |
2473 default: | 2685 default: |
2474 UNREACHABLE(); | 2686 UNREACHABLE(); |
2475 } | 2687 } |
2476 | 2688 |
2477 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 2689 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
2478 ? CALL_AS_FUNCTION | 2690 ? CALL_AS_FUNCTION |
2479 : CALL_AS_METHOD; | 2691 : CALL_AS_METHOD; |
2480 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind); | 2692 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind); |
2481 | 2693 |
2482 // Handle call cache miss. | 2694 // Handle call cache miss. |
2483 __ bind(&miss); | 2695 __ bind(&miss); |
2484 MaybeObject* maybe_result = GenerateMissBranch(); | 2696 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2485 if (maybe_result->IsFailure()) return maybe_result; | 2697 if (maybe_result->IsFailure()) return maybe_result; |
2486 | 2698 |
2487 // Return the generated code. | 2699 // Return the generated code. |
2488 return GetCode(function); | 2700 return TryGetCode(function); |
2489 } | 2701 } |
2490 | 2702 |
2491 | 2703 |
2492 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, | 2704 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, |
2493 JSObject* holder, | 2705 JSObject* holder, |
2494 String* name) { | 2706 String* name) { |
2495 // ----------- S t a t e ------------- | 2707 // ----------- S t a t e ------------- |
2496 // -- r2 : name | 2708 // -- r2 : name |
2497 // -- lr : return address | 2709 // -- lr : return address |
2498 // ----------------------------------- | 2710 // ----------------------------------- |
2499 | 2711 |
2500 Label miss; | 2712 Label miss; |
2501 | 2713 |
2502 GenerateNameCheck(name, &miss); | 2714 GenerateNameCheck(Handle<String>(name), &miss); |
2503 | 2715 |
2504 // Get the number of arguments. | 2716 // Get the number of arguments. |
2505 const int argc = arguments().immediate(); | 2717 const int argc = arguments().immediate(); |
2506 | 2718 |
2507 LookupResult lookup; | 2719 LookupResult lookup(isolate()); |
2508 LookupPostInterceptor(holder, name, &lookup); | 2720 LookupPostInterceptor(holder, name, &lookup); |
2509 | 2721 |
2510 // Get the receiver from the stack. | 2722 // Get the receiver from the stack. |
2511 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 2723 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
2512 | 2724 |
2513 CallInterceptorCompiler compiler(this, arguments(), r2, extra_ic_state_); | 2725 CallInterceptorCompiler compiler(this, arguments(), r2, extra_state_); |
2514 MaybeObject* result = compiler.Compile(masm(), | 2726 MaybeObject* result = compiler.Compile(masm(), |
2515 object, | 2727 object, |
2516 holder, | 2728 holder, |
2517 name, | 2729 name, |
2518 &lookup, | 2730 &lookup, |
2519 r1, | 2731 r1, |
2520 r3, | 2732 r3, |
2521 r4, | 2733 r4, |
2522 r0, | 2734 r0, |
2523 &miss); | 2735 &miss); |
2524 if (result->IsFailure()) { | 2736 if (result->IsFailure()) { |
2525 return result; | 2737 return result; |
2526 } | 2738 } |
2527 | 2739 |
2528 // Move returned value, the function to call, to r1. | 2740 // Move returned value, the function to call, to r1. |
2529 __ mov(r1, r0); | 2741 __ mov(r1, r0); |
2530 // Restore receiver. | 2742 // Restore receiver. |
2531 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 2743 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
2532 | 2744 |
2533 GenerateCallFunction(masm(), object, arguments(), &miss, extra_ic_state_); | 2745 GenerateCallFunction(masm(), Handle<Object>(object), arguments(), &miss, |
| 2746 extra_state_); |
2534 | 2747 |
2535 // Handle call cache miss. | 2748 // Handle call cache miss. |
2536 __ bind(&miss); | 2749 __ bind(&miss); |
2537 MaybeObject* maybe_result = GenerateMissBranch(); | 2750 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2538 if (maybe_result->IsFailure()) return maybe_result; | 2751 if (maybe_result->IsFailure()) return maybe_result; |
2539 | 2752 |
2540 // Return the generated code. | 2753 // Return the generated code. |
2541 return GetCode(INTERCEPTOR, name); | 2754 return TryGetCode(INTERCEPTOR, name); |
2542 } | 2755 } |
2543 | 2756 |
2544 | 2757 |
2545 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, | 2758 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, |
2546 GlobalObject* holder, | 2759 GlobalObject* holder, |
2547 JSGlobalPropertyCell* cell, | 2760 JSGlobalPropertyCell* cell, |
2548 JSFunction* function, | 2761 JSFunction* function, |
2549 String* name) { | 2762 String* name) { |
2550 // ----------- S t a t e ------------- | 2763 // ----------- S t a t e ------------- |
2551 // -- r2 : name | 2764 // -- r2 : name |
2552 // -- lr : return address | 2765 // -- lr : return address |
2553 // ----------------------------------- | 2766 // ----------------------------------- |
2554 | 2767 |
2555 if (HasCustomCallGenerator(function)) { | 2768 if (HasCustomCallGenerator(function)) { |
2556 MaybeObject* maybe_result = CompileCustomCall( | 2769 MaybeObject* maybe_result = CompileCustomCall( |
2557 object, holder, cell, function, name); | 2770 object, holder, cell, function, name); |
2558 Object* result; | 2771 Object* result; |
2559 if (!maybe_result->ToObject(&result)) return maybe_result; | 2772 if (!maybe_result->ToObject(&result)) return maybe_result; |
2560 // undefined means bail out to regular compiler. | 2773 // undefined means bail out to regular compiler. |
2561 if (!result->IsUndefined()) return result; | 2774 if (!result->IsUndefined()) return result; |
2562 } | 2775 } |
2563 | 2776 |
2564 Label miss; | 2777 Label miss; |
2565 | 2778 |
2566 GenerateNameCheck(name, &miss); | 2779 GenerateNameCheck(Handle<String>(name), &miss); |
2567 | 2780 |
2568 // Get the number of arguments. | 2781 // Get the number of arguments. |
2569 const int argc = arguments().immediate(); | 2782 const int argc = arguments().immediate(); |
2570 | 2783 |
2571 GenerateGlobalReceiverCheck(object, holder, name, &miss); | 2784 GenerateGlobalReceiverCheck(object, holder, name, &miss); |
2572 | 2785 |
2573 GenerateLoadFunctionFromCell(cell, function, &miss); | 2786 GenerateLoadFunctionFromCell(cell, function, &miss); |
2574 | 2787 |
2575 // Patch the receiver on the stack with the global proxy if | 2788 // Patch the receiver on the stack with the global proxy if |
2576 // necessary. | 2789 // necessary. |
2577 if (object->IsGlobalObject()) { | 2790 if (object->IsGlobalObject()) { |
2578 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); | 2791 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); |
2579 __ str(r3, MemOperand(sp, argc * kPointerSize)); | 2792 __ str(r3, MemOperand(sp, argc * kPointerSize)); |
2580 } | 2793 } |
2581 | 2794 |
2582 // Setup the context (function already in r1). | 2795 // Setup the context (function already in r1). |
2583 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | 2796 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
2584 | 2797 |
2585 // Jump to the cached code (tail call). | 2798 // Jump to the cached code (tail call). |
2586 Counters* counters = masm()->isolate()->counters(); | 2799 Counters* counters = masm()->isolate()->counters(); |
2587 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4); | 2800 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4); |
2588 ASSERT(function->is_compiled()); | |
2589 Handle<Code> code(function->code()); | 2801 Handle<Code> code(function->code()); |
2590 ParameterCount expected(function->shared()->formal_parameter_count()); | 2802 ParameterCount expected(function->shared()->formal_parameter_count()); |
2591 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 2803 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
2592 ? CALL_AS_FUNCTION | 2804 ? CALL_AS_FUNCTION |
2593 : CALL_AS_METHOD; | 2805 : CALL_AS_METHOD; |
2594 if (V8::UseCrankshaft()) { | 2806 // We call indirectly through the code field in the function to |
2595 // TODO(kasperl): For now, we always call indirectly through the | 2807 // allow recompilation to take effect without changing any of the |
2596 // code field in the function to allow recompilation to take effect | 2808 // call sites. |
2597 // without changing any of the call sites. | 2809 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); |
2598 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); | 2810 __ InvokeCode(r3, expected, arguments(), JUMP_FUNCTION, |
2599 __ InvokeCode(r3, expected, arguments(), JUMP_FUNCTION, | 2811 NullCallWrapper(), call_kind); |
2600 NullCallWrapper(), call_kind); | |
2601 } else { | |
2602 __ InvokeCode(code, expected, arguments(), RelocInfo::CODE_TARGET, | |
2603 JUMP_FUNCTION, call_kind); | |
2604 } | |
2605 | 2812 |
2606 // Handle call cache miss. | 2813 // Handle call cache miss. |
2607 __ bind(&miss); | 2814 __ bind(&miss); |
2608 __ IncrementCounter(counters->call_global_inline_miss(), 1, r1, r3); | 2815 __ IncrementCounter(counters->call_global_inline_miss(), 1, r1, r3); |
2609 MaybeObject* maybe_result = GenerateMissBranch(); | 2816 MaybeObject* maybe_result = TryGenerateMissBranch(); |
2610 if (maybe_result->IsFailure()) return maybe_result; | 2817 if (maybe_result->IsFailure()) return maybe_result; |
2611 | 2818 |
2612 // Return the generated code. | 2819 // Return the generated code. |
2613 return GetCode(NORMAL, name); | 2820 return TryGetCode(NORMAL, name); |
2614 } | 2821 } |
2615 | 2822 |
2616 | 2823 |
2617 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, | 2824 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
2618 int index, | 2825 int index, |
2619 Map* transition, | 2826 Handle<Map> transition, |
2620 String* name) { | 2827 Handle<String> name) { |
2621 // ----------- S t a t e ------------- | 2828 // ----------- S t a t e ------------- |
2622 // -- r0 : value | 2829 // -- r0 : value |
2623 // -- r1 : receiver | 2830 // -- r1 : receiver |
2624 // -- r2 : name | 2831 // -- r2 : name |
2625 // -- lr : return address | 2832 // -- lr : return address |
2626 // ----------------------------------- | 2833 // ----------------------------------- |
2627 Label miss; | 2834 Label miss; |
2628 | 2835 |
2629 GenerateStoreField(masm(), | 2836 GenerateStoreField(masm(), object, index, transition, r1, r2, r3, &miss); |
2630 object, | |
2631 index, | |
2632 transition, | |
2633 r1, r2, r3, | |
2634 &miss); | |
2635 __ bind(&miss); | 2837 __ bind(&miss); |
2636 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); | 2838 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); |
2637 __ Jump(ic, RelocInfo::CODE_TARGET); | 2839 __ Jump(ic, RelocInfo::CODE_TARGET); |
2638 | 2840 |
2639 // Return the generated code. | 2841 // Return the generated code. |
2640 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 2842 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name); |
2641 } | 2843 } |
2642 | 2844 |
2643 | 2845 |
2644 MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object, | 2846 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
2645 AccessorInfo* callback, | 2847 Handle<JSObject> object, |
2646 String* name) { | 2848 Handle<AccessorInfo> callback, |
| 2849 Handle<String> name) { |
2647 // ----------- S t a t e ------------- | 2850 // ----------- S t a t e ------------- |
2648 // -- r0 : value | 2851 // -- r0 : value |
2649 // -- r1 : receiver | 2852 // -- r1 : receiver |
2650 // -- r2 : name | 2853 // -- r2 : name |
2651 // -- lr : return address | 2854 // -- lr : return address |
2652 // ----------------------------------- | 2855 // ----------------------------------- |
2653 Label miss; | 2856 Label miss; |
2654 | 2857 |
2655 // Check that the object isn't a smi. | 2858 // Check that the object isn't a smi. |
2656 __ JumpIfSmi(r1, &miss); | 2859 __ JumpIfSmi(r1, &miss); |
2657 | 2860 |
2658 // Check that the map of the object hasn't changed. | 2861 // Check that the map of the object hasn't changed. |
2659 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset)); | 2862 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset)); |
2660 __ cmp(r3, Operand(Handle<Map>(object->map()))); | 2863 __ cmp(r3, Operand(Handle<Map>(object->map()))); |
2661 __ b(ne, &miss); | 2864 __ b(ne, &miss); |
2662 | 2865 |
2663 // Perform global security token check if needed. | 2866 // Perform global security token check if needed. |
2664 if (object->IsJSGlobalProxy()) { | 2867 if (object->IsJSGlobalProxy()) { |
2665 __ CheckAccessGlobalProxy(r1, r3, &miss); | 2868 __ CheckAccessGlobalProxy(r1, r3, &miss); |
2666 } | 2869 } |
2667 | 2870 |
2668 // Stub never generated for non-global objects that require access | 2871 // Stub never generated for non-global objects that require access |
2669 // checks. | 2872 // checks. |
2670 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 2873 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
2671 | 2874 |
2672 __ push(r1); // receiver | 2875 __ push(r1); // receiver |
2673 __ mov(ip, Operand(Handle<AccessorInfo>(callback))); // callback info | 2876 __ mov(ip, Operand(callback)); // callback info |
2674 __ Push(ip, r2, r0); | 2877 __ Push(ip, r2, r0); |
2675 | 2878 |
2676 // Do tail-call to the runtime system. | 2879 // Do tail-call to the runtime system. |
2677 ExternalReference store_callback_property = | 2880 ExternalReference store_callback_property = |
2678 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), | 2881 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), |
2679 masm()->isolate()); | 2882 masm()->isolate()); |
2680 __ TailCallExternalReference(store_callback_property, 4, 1); | 2883 __ TailCallExternalReference(store_callback_property, 4, 1); |
2681 | 2884 |
2682 // Handle store cache miss. | 2885 // Handle store cache miss. |
2683 __ bind(&miss); | 2886 __ bind(&miss); |
2684 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); | 2887 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); |
2685 __ Jump(ic, RelocInfo::CODE_TARGET); | 2888 __ Jump(ic, RelocInfo::CODE_TARGET); |
2686 | 2889 |
2687 // Return the generated code. | 2890 // Return the generated code. |
2688 return GetCode(CALLBACKS, name); | 2891 return GetCode(CALLBACKS, name); |
2689 } | 2892 } |
2690 | 2893 |
2691 | 2894 |
2692 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, | 2895 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( |
2693 String* name) { | 2896 Handle<JSObject> receiver, |
| 2897 Handle<String> name) { |
2694 // ----------- S t a t e ------------- | 2898 // ----------- S t a t e ------------- |
2695 // -- r0 : value | 2899 // -- r0 : value |
2696 // -- r1 : receiver | 2900 // -- r1 : receiver |
2697 // -- r2 : name | 2901 // -- r2 : name |
2698 // -- lr : return address | 2902 // -- lr : return address |
2699 // ----------------------------------- | 2903 // ----------------------------------- |
2700 Label miss; | 2904 Label miss; |
2701 | 2905 |
2702 // Check that the object isn't a smi. | 2906 // Check that the object isn't a smi. |
2703 __ JumpIfSmi(r1, &miss); | 2907 __ JumpIfSmi(r1, &miss); |
(...skipping 26 matching lines...) Expand all Loading... |
2730 // Handle store cache miss. | 2934 // Handle store cache miss. |
2731 __ bind(&miss); | 2935 __ bind(&miss); |
2732 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); | 2936 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); |
2733 __ Jump(ic, RelocInfo::CODE_TARGET); | 2937 __ Jump(ic, RelocInfo::CODE_TARGET); |
2734 | 2938 |
2735 // Return the generated code. | 2939 // Return the generated code. |
2736 return GetCode(INTERCEPTOR, name); | 2940 return GetCode(INTERCEPTOR, name); |
2737 } | 2941 } |
2738 | 2942 |
2739 | 2943 |
2740 MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object, | 2944 Handle<Code> StoreStubCompiler::CompileStoreGlobal( |
2741 JSGlobalPropertyCell* cell, | 2945 Handle<GlobalObject> object, |
2742 String* name) { | 2946 Handle<JSGlobalPropertyCell> cell, |
| 2947 Handle<String> name) { |
2743 // ----------- S t a t e ------------- | 2948 // ----------- S t a t e ------------- |
2744 // -- r0 : value | 2949 // -- r0 : value |
2745 // -- r1 : receiver | 2950 // -- r1 : receiver |
2746 // -- r2 : name | 2951 // -- r2 : name |
2747 // -- lr : return address | 2952 // -- lr : return address |
2748 // ----------------------------------- | 2953 // ----------------------------------- |
2749 Label miss; | 2954 Label miss; |
2750 | 2955 |
2751 // Check that the map of the global has not changed. | 2956 // Check that the map of the global has not changed. |
2752 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset)); | 2957 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset)); |
2753 __ cmp(r3, Operand(Handle<Map>(object->map()))); | 2958 __ cmp(r3, Operand(Handle<Map>(object->map()))); |
2754 __ b(ne, &miss); | 2959 __ b(ne, &miss); |
2755 | 2960 |
2756 // Check that the value in the cell is not the hole. If it is, this | 2961 // Check that the value in the cell is not the hole. If it is, this |
2757 // cell could have been deleted and reintroducing the global needs | 2962 // cell could have been deleted and reintroducing the global needs |
2758 // to update the property details in the property dictionary of the | 2963 // to update the property details in the property dictionary of the |
2759 // global object. We bail out to the runtime system to do that. | 2964 // global object. We bail out to the runtime system to do that. |
2760 __ mov(r4, Operand(Handle<JSGlobalPropertyCell>(cell))); | 2965 __ mov(r4, Operand(cell)); |
2761 __ LoadRoot(r5, Heap::kTheHoleValueRootIndex); | 2966 __ LoadRoot(r5, Heap::kTheHoleValueRootIndex); |
2762 __ ldr(r6, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset)); | 2967 __ ldr(r6, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset)); |
2763 __ cmp(r5, r6); | 2968 __ cmp(r5, r6); |
2764 __ b(eq, &miss); | 2969 __ b(eq, &miss); |
2765 | 2970 |
2766 // Store the value in the cell. | 2971 // Store the value in the cell. |
2767 __ str(r0, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset)); | 2972 __ str(r0, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset)); |
2768 | 2973 |
2769 __ mov(r1, r0); | 2974 __ mov(r1, r0); |
2770 __ RecordWriteField(r4, | 2975 __ RecordWriteField(r4, |
(...skipping 12 matching lines...) Expand all Loading... |
2783 __ bind(&miss); | 2988 __ bind(&miss); |
2784 __ IncrementCounter(counters->named_store_global_inline_miss(), 1, r4, r3); | 2989 __ IncrementCounter(counters->named_store_global_inline_miss(), 1, r4, r3); |
2785 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); | 2990 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); |
2786 __ Jump(ic, RelocInfo::CODE_TARGET); | 2991 __ Jump(ic, RelocInfo::CODE_TARGET); |
2787 | 2992 |
2788 // Return the generated code. | 2993 // Return the generated code. |
2789 return GetCode(NORMAL, name); | 2994 return GetCode(NORMAL, name); |
2790 } | 2995 } |
2791 | 2996 |
2792 | 2997 |
2793 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, | 2998 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<String> name, |
2794 JSObject* object, | 2999 Handle<JSObject> object, |
2795 JSObject* last) { | 3000 Handle<JSObject> last) { |
2796 // ----------- S t a t e ------------- | 3001 // ----------- S t a t e ------------- |
2797 // -- r0 : receiver | 3002 // -- r0 : receiver |
2798 // -- lr : return address | 3003 // -- lr : return address |
2799 // ----------------------------------- | 3004 // ----------------------------------- |
2800 Label miss; | 3005 Label miss; |
2801 | 3006 |
2802 // Check that receiver is not a smi. | 3007 // Check that receiver is not a smi. |
2803 __ JumpIfSmi(r0, &miss); | 3008 __ JumpIfSmi(r0, &miss); |
2804 | 3009 |
2805 // Check the maps of the full prototype chain. | 3010 // Check the maps of the full prototype chain. |
2806 CheckPrototypes(object, r0, last, r3, r1, r4, name, &miss); | 3011 CheckPrototypes(object, r0, last, r3, r1, r4, name, &miss); |
2807 | 3012 |
2808 // If the last object in the prototype chain is a global object, | 3013 // If the last object in the prototype chain is a global object, |
2809 // check that the global property cell is empty. | 3014 // check that the global property cell is empty. |
2810 if (last->IsGlobalObject()) { | 3015 if (last->IsGlobalObject()) { |
2811 MaybeObject* cell = GenerateCheckPropertyCell(masm(), | 3016 GenerateCheckPropertyCell( |
2812 GlobalObject::cast(last), | 3017 masm(), Handle<GlobalObject>::cast(last), name, r1, &miss); |
2813 name, | |
2814 r1, | |
2815 &miss); | |
2816 if (cell->IsFailure()) { | |
2817 miss.Unuse(); | |
2818 return cell; | |
2819 } | |
2820 } | 3018 } |
2821 | 3019 |
2822 // Return undefined if maps of the full prototype chain are still the | 3020 // Return undefined if maps of the full prototype chain are still the |
2823 // same and no global property with this name contains a value. | 3021 // same and no global property with this name contains a value. |
2824 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); | 3022 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
2825 __ Ret(); | 3023 __ Ret(); |
2826 | 3024 |
2827 __ bind(&miss); | 3025 __ bind(&miss); |
2828 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3026 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2829 | 3027 |
2830 // Return the generated code. | 3028 // Return the generated code. |
2831 return GetCode(NONEXISTENT, heap()->empty_string()); | 3029 return GetCode(NONEXISTENT, factory()->empty_string()); |
2832 } | 3030 } |
2833 | 3031 |
2834 | 3032 |
2835 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object, | 3033 Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object, |
2836 JSObject* holder, | 3034 Handle<JSObject> holder, |
2837 int index, | 3035 int index, |
2838 String* name) { | 3036 Handle<String> name) { |
2839 // ----------- S t a t e ------------- | 3037 // ----------- S t a t e ------------- |
2840 // -- r0 : receiver | 3038 // -- r0 : receiver |
2841 // -- r2 : name | 3039 // -- r2 : name |
2842 // -- lr : return address | 3040 // -- lr : return address |
2843 // ----------------------------------- | 3041 // ----------------------------------- |
2844 Label miss; | 3042 Label miss; |
2845 | 3043 |
2846 GenerateLoadField(object, holder, r0, r3, r1, r4, index, name, &miss); | 3044 GenerateLoadField(object, holder, r0, r3, r1, r4, index, name, &miss); |
2847 __ bind(&miss); | 3045 __ bind(&miss); |
2848 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3046 GenerateLoadMiss(masm(), Code::LOAD_IC); |
(...skipping 18 matching lines...) Expand all Loading... |
2867 callback, name, &miss); | 3065 callback, name, &miss); |
2868 if (result->IsFailure()) { | 3066 if (result->IsFailure()) { |
2869 miss.Unuse(); | 3067 miss.Unuse(); |
2870 return result; | 3068 return result; |
2871 } | 3069 } |
2872 | 3070 |
2873 __ bind(&miss); | 3071 __ bind(&miss); |
2874 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3072 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2875 | 3073 |
2876 // Return the generated code. | 3074 // Return the generated code. |
2877 return GetCode(CALLBACKS, name); | 3075 return TryGetCode(CALLBACKS, name); |
2878 } | 3076 } |
2879 | 3077 |
2880 | 3078 |
2881 MaybeObject* LoadStubCompiler::CompileLoadConstant(JSObject* object, | 3079 Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object, |
2882 JSObject* holder, | 3080 Handle<JSObject> holder, |
2883 Object* value, | 3081 Handle<Object> value, |
2884 String* name) { | 3082 Handle<String> name) { |
2885 // ----------- S t a t e ------------- | 3083 // ----------- S t a t e ------------- |
2886 // -- r0 : receiver | 3084 // -- r0 : receiver |
2887 // -- r2 : name | 3085 // -- r2 : name |
2888 // -- lr : return address | 3086 // -- lr : return address |
2889 // ----------------------------------- | 3087 // ----------------------------------- |
2890 Label miss; | 3088 Label miss; |
2891 | 3089 |
2892 GenerateLoadConstant(object, holder, r0, r3, r1, r4, value, name, &miss); | 3090 GenerateLoadConstant(object, holder, r0, r3, r1, r4, value, name, &miss); |
2893 __ bind(&miss); | 3091 __ bind(&miss); |
2894 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3092 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2895 | 3093 |
2896 // Return the generated code. | 3094 // Return the generated code. |
2897 return GetCode(CONSTANT_FUNCTION, name); | 3095 return GetCode(CONSTANT_FUNCTION, name); |
2898 } | 3096 } |
2899 | 3097 |
2900 | 3098 |
2901 MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* object, | 3099 MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* object, |
2902 JSObject* holder, | 3100 JSObject* holder, |
2903 String* name) { | 3101 String* name) { |
2904 // ----------- S t a t e ------------- | 3102 // ----------- S t a t e ------------- |
2905 // -- r0 : receiver | 3103 // -- r0 : receiver |
2906 // -- r2 : name | 3104 // -- r2 : name |
2907 // -- lr : return address | 3105 // -- lr : return address |
2908 // ----------------------------------- | 3106 // ----------------------------------- |
2909 Label miss; | 3107 Label miss; |
2910 | 3108 |
2911 LookupResult lookup; | 3109 LookupResult lookup(isolate()); |
2912 LookupPostInterceptor(holder, name, &lookup); | 3110 LookupPostInterceptor(holder, name, &lookup); |
2913 GenerateLoadInterceptor(object, | 3111 GenerateLoadInterceptor(object, |
2914 holder, | 3112 holder, |
2915 &lookup, | 3113 &lookup, |
2916 r0, | 3114 r0, |
2917 r2, | 3115 r2, |
2918 r3, | 3116 r3, |
2919 r1, | 3117 r1, |
2920 r4, | 3118 r4, |
2921 name, | 3119 name, |
2922 &miss); | 3120 &miss); |
2923 __ bind(&miss); | 3121 __ bind(&miss); |
2924 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3122 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2925 | 3123 |
2926 // Return the generated code. | 3124 // Return the generated code. |
2927 return GetCode(INTERCEPTOR, name); | 3125 return TryGetCode(INTERCEPTOR, name); |
2928 } | 3126 } |
2929 | 3127 |
2930 | 3128 |
2931 MaybeObject* LoadStubCompiler::CompileLoadGlobal(JSObject* object, | 3129 Handle<Code> LoadStubCompiler::CompileLoadGlobal( |
2932 GlobalObject* holder, | 3130 Handle<JSObject> object, |
2933 JSGlobalPropertyCell* cell, | 3131 Handle<GlobalObject> holder, |
2934 String* name, | 3132 Handle<JSGlobalPropertyCell> cell, |
2935 bool is_dont_delete) { | 3133 Handle<String> name, |
| 3134 bool is_dont_delete) { |
2936 // ----------- S t a t e ------------- | 3135 // ----------- S t a t e ------------- |
2937 // -- r0 : receiver | 3136 // -- r0 : receiver |
2938 // -- r2 : name | 3137 // -- r2 : name |
2939 // -- lr : return address | 3138 // -- lr : return address |
2940 // ----------------------------------- | 3139 // ----------------------------------- |
2941 Label miss; | 3140 Label miss; |
2942 | 3141 |
2943 // If the object is the holder then we know that it's a global | 3142 // If the object is the holder then we know that it's a global |
2944 // object which can only happen for contextual calls. In this case, | 3143 // object which can only happen for contextual calls. In this case, |
2945 // the receiver cannot be a smi. | 3144 // the receiver cannot be a smi. |
2946 if (object != holder) { | 3145 if (!object.is_identical_to(holder)) { |
2947 __ JumpIfSmi(r0, &miss); | 3146 __ JumpIfSmi(r0, &miss); |
2948 } | 3147 } |
2949 | 3148 |
2950 // Check that the map of the global has not changed. | 3149 // Check that the map of the global has not changed. |
2951 CheckPrototypes(object, r0, holder, r3, r4, r1, name, &miss); | 3150 CheckPrototypes(object, r0, holder, r3, r4, r1, name, &miss); |
2952 | 3151 |
2953 // Get the value from the cell. | 3152 // Get the value from the cell. |
2954 __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell))); | 3153 __ mov(r3, Operand(cell)); |
2955 __ ldr(r4, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); | 3154 __ ldr(r4, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); |
2956 | 3155 |
2957 // Check for deleted property if property can actually be deleted. | 3156 // Check for deleted property if property can actually be deleted. |
2958 if (!is_dont_delete) { | 3157 if (!is_dont_delete) { |
2959 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 3158 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
2960 __ cmp(r4, ip); | 3159 __ cmp(r4, ip); |
2961 __ b(eq, &miss); | 3160 __ b(eq, &miss); |
2962 } | 3161 } |
2963 | 3162 |
2964 __ mov(r0, r4); | 3163 __ mov(r0, r4); |
2965 Counters* counters = masm()->isolate()->counters(); | 3164 Counters* counters = masm()->isolate()->counters(); |
2966 __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3); | 3165 __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3); |
2967 __ Ret(); | 3166 __ Ret(); |
2968 | 3167 |
2969 __ bind(&miss); | 3168 __ bind(&miss); |
2970 __ IncrementCounter(counters->named_load_global_stub_miss(), 1, r1, r3); | 3169 __ IncrementCounter(counters->named_load_global_stub_miss(), 1, r1, r3); |
2971 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3170 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2972 | 3171 |
2973 // Return the generated code. | 3172 // Return the generated code. |
2974 return GetCode(NORMAL, name); | 3173 return GetCode(NORMAL, name); |
2975 } | 3174 } |
2976 | 3175 |
2977 | 3176 |
2978 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, | 3177 Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name, |
2979 JSObject* receiver, | 3178 Handle<JSObject> receiver, |
2980 JSObject* holder, | 3179 Handle<JSObject> holder, |
2981 int index) { | 3180 int index) { |
2982 // ----------- S t a t e ------------- | 3181 // ----------- S t a t e ------------- |
2983 // -- lr : return address | 3182 // -- lr : return address |
2984 // -- r0 : key | 3183 // -- r0 : key |
2985 // -- r1 : receiver | 3184 // -- r1 : receiver |
2986 // ----------------------------------- | 3185 // ----------------------------------- |
2987 Label miss; | 3186 Label miss; |
2988 | 3187 |
2989 // Check the key is the cached one. | 3188 // Check the key is the cached one. |
2990 __ cmp(r0, Operand(Handle<String>(name))); | 3189 __ cmp(r0, Operand(name)); |
2991 __ b(ne, &miss); | 3190 __ b(ne, &miss); |
2992 | 3191 |
2993 GenerateLoadField(receiver, holder, r1, r2, r3, r4, index, name, &miss); | 3192 GenerateLoadField(receiver, holder, r1, r2, r3, r4, index, name, &miss); |
2994 __ bind(&miss); | 3193 __ bind(&miss); |
2995 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3194 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2996 | 3195 |
2997 return GetCode(FIELD, name); | 3196 return GetCode(FIELD, name); |
2998 } | 3197 } |
2999 | 3198 |
3000 | 3199 |
(...skipping 16 matching lines...) Expand all Loading... |
3017 MaybeObject* result = GenerateLoadCallback(receiver, holder, r1, r0, r2, r3, | 3216 MaybeObject* result = GenerateLoadCallback(receiver, holder, r1, r0, r2, r3, |
3018 r4, callback, name, &miss); | 3217 r4, callback, name, &miss); |
3019 if (result->IsFailure()) { | 3218 if (result->IsFailure()) { |
3020 miss.Unuse(); | 3219 miss.Unuse(); |
3021 return result; | 3220 return result; |
3022 } | 3221 } |
3023 | 3222 |
3024 __ bind(&miss); | 3223 __ bind(&miss); |
3025 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3224 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3026 | 3225 |
3027 return GetCode(CALLBACKS, name); | 3226 return TryGetCode(CALLBACKS, name); |
3028 } | 3227 } |
3029 | 3228 |
3030 | 3229 |
3031 MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name, | 3230 Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant( |
3032 JSObject* receiver, | 3231 Handle<String> name, |
3033 JSObject* holder, | 3232 Handle<JSObject> receiver, |
3034 Object* value) { | 3233 Handle<JSObject> holder, |
| 3234 Handle<Object> value) { |
3035 // ----------- S t a t e ------------- | 3235 // ----------- S t a t e ------------- |
3036 // -- lr : return address | 3236 // -- lr : return address |
3037 // -- r0 : key | 3237 // -- r0 : key |
3038 // -- r1 : receiver | 3238 // -- r1 : receiver |
3039 // ----------------------------------- | 3239 // ----------------------------------- |
3040 Label miss; | 3240 Label miss; |
3041 | 3241 |
3042 // Check the key is the cached one. | 3242 // Check the key is the cached one. |
3043 __ cmp(r0, Operand(Handle<String>(name))); | 3243 __ cmp(r0, Operand(name)); |
3044 __ b(ne, &miss); | 3244 __ b(ne, &miss); |
3045 | 3245 |
3046 GenerateLoadConstant(receiver, holder, r1, r2, r3, r4, value, name, &miss); | 3246 GenerateLoadConstant(receiver, holder, r1, r2, r3, r4, value, name, &miss); |
3047 __ bind(&miss); | 3247 __ bind(&miss); |
3048 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3248 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3049 | 3249 |
3050 // Return the generated code. | 3250 // Return the generated code. |
3051 return GetCode(CONSTANT_FUNCTION, name); | 3251 return GetCode(CONSTANT_FUNCTION, name); |
3052 } | 3252 } |
3053 | 3253 |
3054 | 3254 |
3055 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 3255 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, |
3056 JSObject* holder, | 3256 JSObject* holder, |
3057 String* name) { | 3257 String* name) { |
3058 // ----------- S t a t e ------------- | 3258 // ----------- S t a t e ------------- |
3059 // -- lr : return address | 3259 // -- lr : return address |
3060 // -- r0 : key | 3260 // -- r0 : key |
3061 // -- r1 : receiver | 3261 // -- r1 : receiver |
3062 // ----------------------------------- | 3262 // ----------------------------------- |
3063 Label miss; | 3263 Label miss; |
3064 | 3264 |
3065 // Check the key is the cached one. | 3265 // Check the key is the cached one. |
3066 __ cmp(r0, Operand(Handle<String>(name))); | 3266 __ cmp(r0, Operand(Handle<String>(name))); |
3067 __ b(ne, &miss); | 3267 __ b(ne, &miss); |
3068 | 3268 |
3069 LookupResult lookup; | 3269 LookupResult lookup(isolate()); |
3070 LookupPostInterceptor(holder, name, &lookup); | 3270 LookupPostInterceptor(holder, name, &lookup); |
3071 GenerateLoadInterceptor(receiver, | 3271 GenerateLoadInterceptor(receiver, |
3072 holder, | 3272 holder, |
3073 &lookup, | 3273 &lookup, |
3074 r1, | 3274 r1, |
3075 r0, | 3275 r0, |
3076 r2, | 3276 r2, |
3077 r3, | 3277 r3, |
3078 r4, | 3278 r4, |
3079 name, | 3279 name, |
3080 &miss); | 3280 &miss); |
3081 __ bind(&miss); | 3281 __ bind(&miss); |
3082 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3282 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3083 | 3283 |
3084 return GetCode(INTERCEPTOR, name); | 3284 return TryGetCode(INTERCEPTOR, name); |
3085 } | 3285 } |
3086 | 3286 |
3087 | 3287 |
3088 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { | 3288 Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength( |
| 3289 Handle<String> name) { |
3089 // ----------- S t a t e ------------- | 3290 // ----------- S t a t e ------------- |
3090 // -- lr : return address | 3291 // -- lr : return address |
3091 // -- r0 : key | 3292 // -- r0 : key |
3092 // -- r1 : receiver | 3293 // -- r1 : receiver |
3093 // ----------------------------------- | 3294 // ----------------------------------- |
3094 Label miss; | 3295 Label miss; |
3095 | 3296 |
3096 // Check the key is the cached one. | 3297 // Check the key is the cached one. |
3097 __ cmp(r0, Operand(Handle<String>(name))); | 3298 __ cmp(r0, Operand(name)); |
3098 __ b(ne, &miss); | 3299 __ b(ne, &miss); |
3099 | 3300 |
3100 GenerateLoadArrayLength(masm(), r1, r2, &miss); | 3301 GenerateLoadArrayLength(masm(), r1, r2, &miss); |
3101 __ bind(&miss); | 3302 __ bind(&miss); |
3102 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3303 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3103 | 3304 |
3104 return GetCode(CALLBACKS, name); | 3305 return GetCode(CALLBACKS, name); |
3105 } | 3306 } |
3106 | 3307 |
3107 | 3308 |
3108 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { | 3309 Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength( |
| 3310 Handle<String> name) { |
3109 // ----------- S t a t e ------------- | 3311 // ----------- S t a t e ------------- |
3110 // -- lr : return address | 3312 // -- lr : return address |
3111 // -- r0 : key | 3313 // -- r0 : key |
3112 // -- r1 : receiver | 3314 // -- r1 : receiver |
3113 // ----------------------------------- | 3315 // ----------------------------------- |
3114 Label miss; | 3316 Label miss; |
3115 | 3317 |
3116 Counters* counters = masm()->isolate()->counters(); | 3318 Counters* counters = masm()->isolate()->counters(); |
3117 __ IncrementCounter(counters->keyed_load_string_length(), 1, r2, r3); | 3319 __ IncrementCounter(counters->keyed_load_string_length(), 1, r2, r3); |
3118 | 3320 |
3119 // Check the key is the cached one. | 3321 // Check the key is the cached one. |
3120 __ cmp(r0, Operand(Handle<String>(name))); | 3322 __ cmp(r0, Operand(name)); |
3121 __ b(ne, &miss); | 3323 __ b(ne, &miss); |
3122 | 3324 |
3123 GenerateLoadStringLength(masm(), r1, r2, r3, &miss, true); | 3325 GenerateLoadStringLength(masm(), r1, r2, r3, &miss, true); |
3124 __ bind(&miss); | 3326 __ bind(&miss); |
3125 __ DecrementCounter(counters->keyed_load_string_length(), 1, r2, r3); | 3327 __ DecrementCounter(counters->keyed_load_string_length(), 1, r2, r3); |
3126 | 3328 |
3127 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3329 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3128 | 3330 |
3129 return GetCode(CALLBACKS, name); | 3331 return GetCode(CALLBACKS, name); |
3130 } | 3332 } |
3131 | 3333 |
3132 | 3334 |
3133 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { | 3335 Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype( |
| 3336 Handle<String> name) { |
3134 // ----------- S t a t e ------------- | 3337 // ----------- S t a t e ------------- |
3135 // -- lr : return address | 3338 // -- lr : return address |
3136 // -- r0 : key | 3339 // -- r0 : key |
3137 // -- r1 : receiver | 3340 // -- r1 : receiver |
3138 // ----------------------------------- | 3341 // ----------------------------------- |
3139 Label miss; | 3342 Label miss; |
3140 | 3343 |
3141 Counters* counters = masm()->isolate()->counters(); | 3344 Counters* counters = masm()->isolate()->counters(); |
3142 __ IncrementCounter(counters->keyed_load_function_prototype(), 1, r2, r3); | 3345 __ IncrementCounter(counters->keyed_load_function_prototype(), 1, r2, r3); |
3143 | 3346 |
3144 // Check the name hasn't changed. | 3347 // Check the name hasn't changed. |
3145 __ cmp(r0, Operand(Handle<String>(name))); | 3348 __ cmp(r0, Operand(name)); |
3146 __ b(ne, &miss); | 3349 __ b(ne, &miss); |
3147 | 3350 |
3148 GenerateLoadFunctionPrototype(masm(), r1, r2, r3, &miss); | 3351 GenerateLoadFunctionPrototype(masm(), r1, r2, r3, &miss); |
3149 __ bind(&miss); | 3352 __ bind(&miss); |
3150 __ DecrementCounter(counters->keyed_load_function_prototype(), 1, r2, r3); | 3353 __ DecrementCounter(counters->keyed_load_function_prototype(), 1, r2, r3); |
3151 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3354 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3152 | 3355 |
3153 return GetCode(CALLBACKS, name); | 3356 return GetCode(CALLBACKS, name); |
3154 } | 3357 } |
3155 | 3358 |
3156 | 3359 |
3157 MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) { | 3360 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( |
| 3361 Handle<Map> receiver_map) { |
3158 // ----------- S t a t e ------------- | 3362 // ----------- S t a t e ------------- |
3159 // -- lr : return address | 3363 // -- lr : return address |
3160 // -- r0 : key | 3364 // -- r0 : key |
3161 // -- r1 : receiver | 3365 // -- r1 : receiver |
3162 // ----------------------------------- | 3366 // ----------------------------------- |
3163 Code* stub; | |
3164 ElementsKind elements_kind = receiver_map->elements_kind(); | 3367 ElementsKind elements_kind = receiver_map->elements_kind(); |
3165 MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode(); | 3368 Handle<Code> stub = KeyedLoadElementStub(elements_kind).GetCode(); |
3166 if (!maybe_stub->To(&stub)) return maybe_stub; | 3369 |
3167 __ DispatchMap(r1, | 3370 __ DispatchMap(r1, r2, receiver_map, stub, DO_SMI_CHECK); |
3168 r2, | |
3169 Handle<Map>(receiver_map), | |
3170 Handle<Code>(stub), | |
3171 DO_SMI_CHECK); | |
3172 | 3371 |
3173 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); | 3372 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); |
3174 __ Jump(ic, RelocInfo::CODE_TARGET); | 3373 __ Jump(ic, RelocInfo::CODE_TARGET); |
3175 | 3374 |
3176 // Return the generated code. | 3375 // Return the generated code. |
3177 return GetCode(NORMAL, NULL); | 3376 return GetCode(NORMAL, factory()->empty_string()); |
3178 } | 3377 } |
3179 | 3378 |
3180 | 3379 |
3181 MaybeObject* KeyedLoadStubCompiler::CompileLoadPolymorphic( | 3380 Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic( |
3182 MapList* receiver_maps, | 3381 MapHandleList* receiver_maps, |
3183 CodeList* handler_ics) { | 3382 CodeHandleList* handler_ics) { |
3184 // ----------- S t a t e ------------- | 3383 // ----------- S t a t e ------------- |
3185 // -- lr : return address | 3384 // -- lr : return address |
3186 // -- r0 : key | 3385 // -- r0 : key |
3187 // -- r1 : receiver | 3386 // -- r1 : receiver |
3188 // ----------------------------------- | 3387 // ----------------------------------- |
3189 Label miss; | 3388 Label miss; |
3190 __ JumpIfSmi(r1, &miss); | 3389 __ JumpIfSmi(r1, &miss); |
3191 | 3390 |
3192 int receiver_count = receiver_maps->length(); | 3391 int receiver_count = receiver_maps->length(); |
3193 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); | 3392 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); |
3194 for (int current = 0; current < receiver_count; ++current) { | 3393 for (int current = 0; current < receiver_count; ++current) { |
3195 Handle<Map> map(receiver_maps->at(current)); | 3394 __ mov(ip, Operand(receiver_maps->at(current))); |
3196 Handle<Code> code(handler_ics->at(current)); | |
3197 __ mov(ip, Operand(map)); | |
3198 __ cmp(r2, ip); | 3395 __ cmp(r2, ip); |
3199 __ Jump(code, RelocInfo::CODE_TARGET, eq); | 3396 __ Jump(handler_ics->at(current), RelocInfo::CODE_TARGET, eq); |
3200 } | 3397 } |
3201 | 3398 |
3202 __ bind(&miss); | 3399 __ bind(&miss); |
3203 Handle<Code> miss_ic = isolate()->builtins()->KeyedLoadIC_Miss(); | 3400 Handle<Code> miss_ic = isolate()->builtins()->KeyedLoadIC_Miss(); |
3204 __ Jump(miss_ic, RelocInfo::CODE_TARGET, al); | 3401 __ Jump(miss_ic, RelocInfo::CODE_TARGET, al); |
3205 | 3402 |
3206 // Return the generated code. | 3403 // Return the generated code. |
3207 return GetCode(NORMAL, NULL, MEGAMORPHIC); | 3404 return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC); |
3208 } | 3405 } |
3209 | 3406 |
3210 | 3407 |
3211 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, | 3408 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
3212 int index, | 3409 int index, |
3213 Map* transition, | 3410 Handle<Map> transition, |
3214 String* name) { | 3411 Handle<String> name) { |
3215 // ----------- S t a t e ------------- | 3412 // ----------- S t a t e ------------- |
3216 // -- r0 : value | 3413 // -- r0 : value |
3217 // -- r1 : name | 3414 // -- r1 : name |
3218 // -- r2 : receiver | 3415 // -- r2 : receiver |
3219 // -- lr : return address | 3416 // -- lr : return address |
3220 // ----------------------------------- | 3417 // ----------------------------------- |
3221 Label miss; | 3418 Label miss; |
3222 | 3419 |
3223 Counters* counters = masm()->isolate()->counters(); | 3420 Counters* counters = masm()->isolate()->counters(); |
3224 __ IncrementCounter(counters->keyed_store_field(), 1, r3, r4); | 3421 __ IncrementCounter(counters->keyed_store_field(), 1, r3, r4); |
3225 | 3422 |
3226 // Check that the name has not changed. | 3423 // Check that the name has not changed. |
3227 __ cmp(r1, Operand(Handle<String>(name))); | 3424 __ cmp(r1, Operand(name)); |
3228 __ b(ne, &miss); | 3425 __ b(ne, &miss); |
3229 | 3426 |
3230 // r3 is used as scratch register. r1 and r2 keep their values if a jump to | 3427 // r3 is used as scratch register. r1 and r2 keep their values if a jump to |
3231 // the miss label is generated. | 3428 // the miss label is generated. |
3232 GenerateStoreField(masm(), | 3429 GenerateStoreField(masm(), object, index, transition, r2, r1, r3, &miss); |
3233 object, | |
3234 index, | |
3235 transition, | |
3236 r2, r1, r3, | |
3237 &miss); | |
3238 __ bind(&miss); | 3430 __ bind(&miss); |
3239 | 3431 |
3240 __ DecrementCounter(counters->keyed_store_field(), 1, r3, r4); | 3432 __ DecrementCounter(counters->keyed_store_field(), 1, r3, r4); |
3241 Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss(); | 3433 Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss(); |
3242 __ Jump(ic, RelocInfo::CODE_TARGET); | 3434 __ Jump(ic, RelocInfo::CODE_TARGET); |
3243 | 3435 |
3244 // Return the generated code. | 3436 // Return the generated code. |
3245 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 3437 return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name); |
3246 } | 3438 } |
3247 | 3439 |
3248 | 3440 |
3249 MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(Map* receiver_map) { | 3441 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement( |
| 3442 Handle<Map> receiver_map) { |
3250 // ----------- S t a t e ------------- | 3443 // ----------- S t a t e ------------- |
3251 // -- r0 : value | 3444 // -- r0 : value |
3252 // -- r1 : key | 3445 // -- r1 : key |
3253 // -- r2 : receiver | 3446 // -- r2 : receiver |
3254 // -- lr : return address | 3447 // -- lr : return address |
3255 // -- r3 : scratch | 3448 // -- r3 : scratch |
3256 // ----------------------------------- | 3449 // ----------------------------------- |
3257 Code* stub; | |
3258 ElementsKind elements_kind = receiver_map->elements_kind(); | 3450 ElementsKind elements_kind = receiver_map->elements_kind(); |
3259 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; | 3451 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; |
3260 MaybeObject* maybe_stub = | 3452 Handle<Code> stub = |
3261 KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode(); | 3453 KeyedStoreElementStub(is_js_array, elements_kind).GetCode(); |
3262 if (!maybe_stub->To(&stub)) return maybe_stub; | 3454 |
3263 __ DispatchMap(r2, | 3455 __ DispatchMap(r2, r3, receiver_map, stub, DO_SMI_CHECK); |
3264 r3, | |
3265 Handle<Map>(receiver_map), | |
3266 Handle<Code>(stub), | |
3267 DO_SMI_CHECK); | |
3268 | 3456 |
3269 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 3457 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
3270 __ Jump(ic, RelocInfo::CODE_TARGET); | 3458 __ Jump(ic, RelocInfo::CODE_TARGET); |
3271 | 3459 |
3272 // Return the generated code. | 3460 // Return the generated code. |
3273 return GetCode(NORMAL, NULL); | 3461 return GetCode(NORMAL, factory()->empty_string()); |
3274 } | 3462 } |
3275 | 3463 |
3276 | 3464 |
3277 MaybeObject* KeyedStoreStubCompiler::CompileStorePolymorphic( | 3465 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( |
3278 MapList* receiver_maps, | 3466 MapHandleList* receiver_maps, |
3279 CodeList* handler_stubs, | 3467 CodeHandleList* handler_stubs, |
3280 MapList* transitioned_maps) { | 3468 MapHandleList* transitioned_maps) { |
3281 // ----------- S t a t e ------------- | 3469 // ----------- S t a t e ------------- |
3282 // -- r0 : value | 3470 // -- r0 : value |
3283 // -- r1 : key | 3471 // -- r1 : key |
3284 // -- r2 : receiver | 3472 // -- r2 : receiver |
3285 // -- lr : return address | 3473 // -- lr : return address |
3286 // -- r3 : scratch | 3474 // -- r3 : scratch |
3287 // ----------------------------------- | 3475 // ----------------------------------- |
3288 Label miss; | 3476 Label miss; |
3289 __ JumpIfSmi(r2, &miss); | 3477 __ JumpIfSmi(r2, &miss); |
3290 | 3478 |
3291 int receiver_count = receiver_maps->length(); | 3479 int receiver_count = receiver_maps->length(); |
3292 __ ldr(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); | 3480 __ ldr(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); |
3293 for (int i = 0; i < receiver_count; ++i) { | 3481 for (int i = 0; i < receiver_count; ++i) { |
3294 Handle<Map> map(receiver_maps->at(i)); | 3482 __ mov(ip, Operand(receiver_maps->at(i))); |
3295 Handle<Code> code(handler_stubs->at(i)); | |
3296 __ mov(ip, Operand(map)); | |
3297 __ cmp(r3, ip); | 3483 __ cmp(r3, ip); |
3298 if (transitioned_maps->at(i) == NULL) { | 3484 if (transitioned_maps->at(i).is_null()) { |
3299 __ Jump(code, RelocInfo::CODE_TARGET, eq); | 3485 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq); |
3300 } else { | 3486 } else { |
3301 Label next_map; | 3487 Label next_map; |
3302 __ b(eq, &next_map); | 3488 __ b(ne, &next_map); |
3303 __ mov(r4, Operand(Handle<Map>(transitioned_maps->at(i)))); | 3489 __ mov(r3, Operand(transitioned_maps->at(i))); |
3304 __ Jump(code, RelocInfo::CODE_TARGET, al); | 3490 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, al); |
3305 __ bind(&next_map); | 3491 __ bind(&next_map); |
3306 } | 3492 } |
3307 } | 3493 } |
3308 | 3494 |
3309 __ bind(&miss); | 3495 __ bind(&miss); |
3310 Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 3496 Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
3311 __ Jump(miss_ic, RelocInfo::CODE_TARGET, al); | 3497 __ Jump(miss_ic, RelocInfo::CODE_TARGET, al); |
3312 | 3498 |
3313 // Return the generated code. | 3499 // Return the generated code. |
3314 return GetCode(NORMAL, NULL, MEGAMORPHIC); | 3500 return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC); |
3315 } | 3501 } |
3316 | 3502 |
3317 | 3503 |
3318 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { | 3504 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { |
3319 // ----------- S t a t e ------------- | 3505 // ----------- S t a t e ------------- |
3320 // -- r0 : argc | 3506 // -- r0 : argc |
3321 // -- r1 : constructor | 3507 // -- r1 : constructor |
3322 // -- lr : return address | 3508 // -- lr : return address |
3323 // -- [sp] : last argument | 3509 // -- [sp] : last argument |
3324 // ----------------------------------- | 3510 // ----------------------------------- |
(...skipping 1135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4460 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 4646 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
4461 __ Jump(ic_miss, RelocInfo::CODE_TARGET); | 4647 __ Jump(ic_miss, RelocInfo::CODE_TARGET); |
4462 } | 4648 } |
4463 | 4649 |
4464 | 4650 |
4465 #undef __ | 4651 #undef __ |
4466 | 4652 |
4467 } } // namespace v8::internal | 4653 } } // namespace v8::internal |
4468 | 4654 |
4469 #endif // V8_TARGET_ARCH_ARM | 4655 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |