| 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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 92   // Miss: fall through. | 92   // Miss: fall through. | 
| 93   __ bind(&miss); | 93   __ bind(&miss); | 
| 94 } | 94 } | 
| 95 | 95 | 
| 96 | 96 | 
| 97 // Helper function used to check that the dictionary doesn't contain | 97 // Helper function used to check that the dictionary doesn't contain | 
| 98 // the property. This function may return false negatives, so miss_label | 98 // the property. This function may return false negatives, so miss_label | 
| 99 // must always call a backup property check that is complete. | 99 // must always call a backup property check that is complete. | 
| 100 // This function is safe to call if the receiver has fast properties. | 100 // This function is safe to call if the receiver has fast properties. | 
| 101 // Name must be a symbol and receiver must be a heap object. | 101 // Name must be a symbol and receiver must be a heap object. | 
| 102 MUST_USE_RESULT static MaybeObject* GenerateDictionaryNegativeLookup( | 102 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, | 
|  | 103                                              Label* miss_label, | 
|  | 104                                              Register receiver, | 
|  | 105                                              Handle<String> name, | 
|  | 106                                              Register scratch0, | 
|  | 107                                              Register scratch1) { | 
|  | 108   ASSERT(name->IsSymbol()); | 
|  | 109   Counters* counters = masm->isolate()->counters(); | 
|  | 110   __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); | 
|  | 111   __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | 
|  | 112 | 
|  | 113   Label done; | 
|  | 114 | 
|  | 115   const int kInterceptorOrAccessCheckNeededMask = | 
|  | 116       (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 
|  | 117 | 
|  | 118   // Bail out if the receiver has a named interceptor or requires access checks. | 
|  | 119   Register map = scratch1; | 
|  | 120   __ lw(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 
|  | 121   __ lbu(scratch0, FieldMemOperand(map, Map::kBitFieldOffset)); | 
|  | 122   __ And(scratch0, scratch0, Operand(kInterceptorOrAccessCheckNeededMask)); | 
|  | 123   __ Branch(miss_label, ne, scratch0, Operand(zero_reg)); | 
|  | 124 | 
|  | 125   // Check that receiver is a JSObject. | 
|  | 126   __ lbu(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset)); | 
|  | 127   __ Branch(miss_label, lt, scratch0, Operand(FIRST_SPEC_OBJECT_TYPE)); | 
|  | 128 | 
|  | 129   // Load properties array. | 
|  | 130   Register properties = scratch0; | 
|  | 131   __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 
|  | 132   // Check that the properties array is a dictionary. | 
|  | 133   __ lw(map, FieldMemOperand(properties, HeapObject::kMapOffset)); | 
|  | 134   Register tmp = properties; | 
|  | 135   __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); | 
|  | 136   __ Branch(miss_label, ne, map, Operand(tmp)); | 
|  | 137 | 
|  | 138   // Restore the temporarily used register. | 
|  | 139   __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 
|  | 140 | 
|  | 141 | 
|  | 142   StringDictionaryLookupStub::GenerateNegativeLookup(masm, | 
|  | 143                                                      miss_label, | 
|  | 144                                                      &done, | 
|  | 145                                                      receiver, | 
|  | 146                                                      properties, | 
|  | 147                                                      name, | 
|  | 148                                                      scratch1); | 
|  | 149   __ bind(&done); | 
|  | 150   __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | 
|  | 151 } | 
|  | 152 | 
|  | 153 | 
|  | 154 // TODO(kmillikin): Eliminate this function when the stub cache is fully | 
|  | 155 // handlified. | 
|  | 156 MUST_USE_RESULT static MaybeObject* TryGenerateDictionaryNegativeLookup( | 
| 103     MacroAssembler* masm, | 157     MacroAssembler* masm, | 
| 104     Label* miss_label, | 158     Label* miss_label, | 
| 105     Register receiver, | 159     Register receiver, | 
| 106     String* name, | 160     String* name, | 
| 107     Register scratch0, | 161     Register scratch0, | 
| 108     Register scratch1) { | 162     Register scratch1) { | 
| 109   ASSERT(name->IsSymbol()); | 163   ASSERT(name->IsSymbol()); | 
| 110   Counters* counters = masm->isolate()->counters(); | 164   Counters* counters = masm->isolate()->counters(); | 
| 111   __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); | 165   __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); | 
| 112   __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | 166   __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 133   __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 187   __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 
| 134   // Check that the properties array is a dictionary. | 188   // Check that the properties array is a dictionary. | 
| 135   __ lw(map, FieldMemOperand(properties, HeapObject::kMapOffset)); | 189   __ lw(map, FieldMemOperand(properties, HeapObject::kMapOffset)); | 
| 136   Register tmp = properties; | 190   Register tmp = properties; | 
| 137   __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); | 191   __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); | 
| 138   __ Branch(miss_label, ne, map, Operand(tmp)); | 192   __ Branch(miss_label, ne, map, Operand(tmp)); | 
| 139 | 193 | 
| 140   // Restore the temporarily used register. | 194   // Restore the temporarily used register. | 
| 141   __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 195   __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 
| 142 | 196 | 
| 143   MaybeObject* result = StringDictionaryLookupStub::GenerateNegativeLookup( | 197   MaybeObject* result = StringDictionaryLookupStub::TryGenerateNegativeLookup( | 
| 144       masm, | 198       masm, | 
| 145       miss_label, | 199       miss_label, | 
| 146       &done, | 200       &done, | 
| 147       receiver, | 201       receiver, | 
| 148       properties, | 202       properties, | 
| 149       name, | 203       name, | 
| 150       scratch1); | 204       scratch1); | 
| 151   if (result->IsFailure()) return result; | 205   if (result->IsFailure()) return result; | 
| 152 | 206 | 
| 153   __ bind(&done); | 207   __ bind(&done); | 
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 254   __ li(prototype, Handle<Map>(function->initial_map())); | 308   __ li(prototype, Handle<Map>(function->initial_map())); | 
| 255   // Load the prototype from the initial map. | 309   // Load the prototype from the initial map. | 
| 256   __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); | 310   __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); | 
| 257 } | 311 } | 
| 258 | 312 | 
| 259 | 313 | 
| 260 // 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 | 
| 261 // are loaded directly otherwise the property is loaded from the properties | 315 // are loaded directly otherwise the property is loaded from the properties | 
| 262 // fixed array. | 316 // fixed array. | 
| 263 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, | 317 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, | 
| 264                                             Register dst, Register src, | 318                                             Register dst, | 
| 265                                             JSObject* holder, int index) { | 319                                             Register src, | 
|  | 320                                             Handle<JSObject> holder, | 
|  | 321                                             int index) { | 
| 266   // Adjust for the number of properties stored in the holder. | 322   // Adjust for the number of properties stored in the holder. | 
| 267   index -= holder->map()->inobject_properties(); | 323   index -= holder->map()->inobject_properties(); | 
| 268   if (index < 0) { | 324   if (index < 0) { | 
| 269     // Get the property straight out of the holder. | 325     // Get the property straight out of the holder. | 
| 270     int offset = holder->map()->instance_size() + (index * kPointerSize); | 326     int offset = holder->map()->instance_size() + (index * kPointerSize); | 
| 271     __ lw(dst, FieldMemOperand(src, offset)); | 327     __ lw(dst, FieldMemOperand(src, offset)); | 
| 272   } else { | 328   } else { | 
| 273     // Calculate the offset into the properties array. | 329     // Calculate the offset into the properties array. | 
| 274     int offset = index * kPointerSize + FixedArray::kHeaderSize; | 330     int offset = index * kPointerSize + FixedArray::kHeaderSize; | 
| 275     __ lw(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); | 331     __ lw(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); | 
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 462 | 518 | 
| 463   // Return the value (register v0). | 519   // Return the value (register v0). | 
| 464   __ bind(&exit); | 520   __ bind(&exit); | 
| 465   __ mov(v0, a0); | 521   __ mov(v0, a0); | 
| 466   __ Ret(); | 522   __ Ret(); | 
| 467 } | 523 } | 
| 468 | 524 | 
| 469 | 525 | 
| 470 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { | 526 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { | 
| 471   ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); | 527   ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); | 
| 472   Code* code = NULL; | 528   Handle<Code> code = (kind == Code::LOAD_IC) | 
| 473   if (kind == Code::LOAD_IC) { | 529       ? masm->isolate()->builtins()->LoadIC_Miss() | 
| 474     code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss); | 530       : masm->isolate()->builtins()->KeyedLoadIC_Miss(); | 
| 475   } else { | 531   __ Jump(code, RelocInfo::CODE_TARGET); | 
| 476     code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss); |  | 
| 477   } |  | 
| 478 |  | 
| 479   Handle<Code> ic(code); |  | 
| 480   __ Jump(ic, RelocInfo::CODE_TARGET); |  | 
| 481 } | 532 } | 
| 482 | 533 | 
| 483 | 534 | 
| 484 static void GenerateCallFunction(MacroAssembler* masm, | 535 static void GenerateCallFunction(MacroAssembler* masm, | 
| 485                                  Object* object, | 536                                  Handle<Object> object, | 
| 486                                  const ParameterCount& arguments, | 537                                  const ParameterCount& arguments, | 
| 487                                  Label* miss, | 538                                  Label* miss, | 
| 488                                  Code::ExtraICState extra_ic_state) { | 539                                  Code::ExtraICState extra_ic_state) { | 
| 489   // ----------- S t a t e ------------- | 540   // ----------- S t a t e ------------- | 
| 490   //  -- a0: receiver | 541   //  -- a0: receiver | 
| 491   //  -- a1: function to call | 542   //  -- a1: function to call | 
| 492   // ----------------------------------- | 543   // ----------------------------------- | 
| 493   // Check that the function really is a function. | 544   // Check that the function really is a function. | 
| 494   __ JumpIfSmi(a1, miss); | 545   __ JumpIfSmi(a1, miss); | 
| 495   __ GetObjectType(a1, a3, a3); | 546   __ GetObjectType(a1, a3, a3); | 
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 871   const ParameterCount& arguments_; | 922   const ParameterCount& arguments_; | 
| 872   Register name_; | 923   Register name_; | 
| 873   Code::ExtraICState extra_ic_state_; | 924   Code::ExtraICState extra_ic_state_; | 
| 874 }; | 925 }; | 
| 875 | 926 | 
| 876 | 927 | 
| 877 | 928 | 
| 878 // Generate code to check that a global property cell is empty. Create | 929 // Generate code to check that a global property cell is empty. Create | 
| 879 // the property cell at compilation time if no cell exists for the | 930 // the property cell at compilation time if no cell exists for the | 
| 880 // property. | 931 // property. | 
| 881 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCell( | 932 static void GenerateCheckPropertyCell(MacroAssembler* masm, | 
|  | 933                                       Handle<GlobalObject> global, | 
|  | 934                                       Handle<String> name, | 
|  | 935                                       Register scratch, | 
|  | 936                                       Label* miss) { | 
|  | 937   Handle<JSGlobalPropertyCell> cell = | 
|  | 938       GlobalObject::EnsurePropertyCell(global, name); | 
|  | 939   ASSERT(cell->value()->IsTheHole()); | 
|  | 940   __ li(scratch, Operand(cell)); | 
|  | 941   __ lw(scratch, | 
|  | 942         FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); | 
|  | 943   __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 
|  | 944   __ Branch(miss, ne, scratch, Operand(at)); | 
|  | 945 } | 
|  | 946 | 
|  | 947 | 
|  | 948 // TODO(kmillikin): Eliminate this function when the stub cache is fully | 
|  | 949 // handlified. | 
|  | 950 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCell( | 
| 882     MacroAssembler* masm, | 951     MacroAssembler* masm, | 
| 883     GlobalObject* global, | 952     GlobalObject* global, | 
| 884     String* name, | 953     String* name, | 
| 885     Register scratch, | 954     Register scratch, | 
| 886     Label* miss) { | 955     Label* miss) { | 
| 887   Object* probe; | 956   Object* probe; | 
| 888   { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); | 957   { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); | 
| 889     if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 958     if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 
| 890   } | 959   } | 
| 891   JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); | 960   JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); | 
| 892   ASSERT(cell->value()->IsTheHole()); | 961   ASSERT(cell->value()->IsTheHole()); | 
| 893   __ li(scratch, Operand(Handle<Object>(cell))); | 962   __ li(scratch, Operand(Handle<Object>(cell))); | 
| 894   __ lw(scratch, | 963   __ lw(scratch, | 
| 895         FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); | 964         FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); | 
| 896   __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 965   __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 
| 897   __ Branch(miss, ne, scratch, Operand(at)); | 966   __ Branch(miss, ne, scratch, Operand(at)); | 
| 898   return cell; | 967   return cell; | 
| 899 } | 968 } | 
| 900 | 969 | 
| 901 | 970 | 
| 902 // Calls GenerateCheckPropertyCell for each global object in the prototype chain | 971 // Calls GenerateCheckPropertyCell for each global object in the prototype chain | 
| 903 // from object to (but not including) holder. | 972 // from object to (but not including) holder. | 
| 904 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCells( | 973 static void GenerateCheckPropertyCells(MacroAssembler* masm, | 
|  | 974                                        Handle<JSObject> object, | 
|  | 975                                        Handle<JSObject> holder, | 
|  | 976                                        Handle<String> name, | 
|  | 977                                        Register scratch, | 
|  | 978                                        Label* miss) { | 
|  | 979   Handle<JSObject> current = object; | 
|  | 980   while (!current.is_identical_to(holder)) { | 
|  | 981     if (current->IsGlobalObject()) { | 
|  | 982       GenerateCheckPropertyCell(masm, | 
|  | 983                                 Handle<GlobalObject>::cast(current), | 
|  | 984                                 name, | 
|  | 985                                 scratch, | 
|  | 986                                 miss); | 
|  | 987     } | 
|  | 988     current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); | 
|  | 989   } | 
|  | 990 } | 
|  | 991 | 
|  | 992 | 
|  | 993 // TODO(kmillikin): Eliminate this function when the stub cache is fully | 
|  | 994 // handlified. | 
|  | 995 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCells( | 
| 905     MacroAssembler* masm, | 996     MacroAssembler* masm, | 
| 906     JSObject* object, | 997     JSObject* object, | 
| 907     JSObject* holder, | 998     JSObject* holder, | 
| 908     String* name, | 999     String* name, | 
| 909     Register scratch, | 1000     Register scratch, | 
| 910     Label* miss) { | 1001     Label* miss) { | 
| 911   JSObject* current = object; | 1002   JSObject* current = object; | 
| 912   while (current != holder) { | 1003   while (current != holder) { | 
| 913     if (current->IsGlobalObject()) { | 1004     if (current->IsGlobalObject()) { | 
| 914       // Returns a cell or a failure. | 1005       // Returns a cell or a failure. | 
| 915       MaybeObject* result = GenerateCheckPropertyCell( | 1006       MaybeObject* result = TryGenerateCheckPropertyCell( | 
| 916           masm, | 1007           masm, | 
| 917           GlobalObject::cast(current), | 1008           GlobalObject::cast(current), | 
| 918           name, | 1009           name, | 
| 919           scratch, | 1010           scratch, | 
| 920           miss); | 1011           miss); | 
| 921       if (result->IsFailure()) return result; | 1012       if (result->IsFailure()) return result; | 
| 922     } | 1013     } | 
| 923     ASSERT(current->IsJSObject()); | 1014     ASSERT(current->IsJSObject()); | 
| 924     current = JSObject::cast(current->GetPrototype()); | 1015     current = JSObject::cast(current->GetPrototype()); | 
| 925   } | 1016   } | 
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1040     __ nor(scratch, scratch, scratch); | 1131     __ nor(scratch, scratch, scratch); | 
| 1041     __ and_(hiword, hiword, scratch); | 1132     __ and_(hiword, hiword, scratch); | 
| 1042   } | 1133   } | 
| 1043 } | 1134 } | 
| 1044 | 1135 | 
| 1045 | 1136 | 
| 1046 #undef __ | 1137 #undef __ | 
| 1047 #define __ ACCESS_MASM(masm()) | 1138 #define __ ACCESS_MASM(masm()) | 
| 1048 | 1139 | 
| 1049 | 1140 | 
|  | 1141 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, | 
|  | 1142                                        Register object_reg, | 
|  | 1143                                        Handle<JSObject> holder, | 
|  | 1144                                        Register holder_reg, | 
|  | 1145                                        Register scratch1, | 
|  | 1146                                        Register scratch2, | 
|  | 1147                                        Handle<String> name, | 
|  | 1148                                        int save_at_depth, | 
|  | 1149                                        Label* miss) { | 
|  | 1150   // Make sure there's no overlap between holder and object registers. | 
|  | 1151   ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 
|  | 1152   ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 
|  | 1153          && !scratch2.is(scratch1)); | 
|  | 1154 | 
|  | 1155   // Keep track of the current object in register reg. | 
|  | 1156   Register reg = object_reg; | 
|  | 1157   int depth = 0; | 
|  | 1158 | 
|  | 1159   if (save_at_depth == depth) { | 
|  | 1160     __ sw(reg, MemOperand(sp)); | 
|  | 1161   } | 
|  | 1162 | 
|  | 1163   // Check the maps in the prototype chain. | 
|  | 1164   // Traverse the prototype chain from the object and do map checks. | 
|  | 1165   Handle<JSObject> current = object; | 
|  | 1166   while (!current.is_identical_to(holder)) { | 
|  | 1167     ++depth; | 
|  | 1168 | 
|  | 1169     // Only global objects and objects that do not require access | 
|  | 1170     // checks are allowed in stubs. | 
|  | 1171     ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 
|  | 1172 | 
|  | 1173     Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); | 
|  | 1174     if (!current->HasFastProperties() && | 
|  | 1175         !current->IsJSGlobalObject() && | 
|  | 1176         !current->IsJSGlobalProxy()) { | 
|  | 1177       if (!name->IsSymbol()) { | 
|  | 1178         name = factory()->LookupSymbol(name); | 
|  | 1179       } | 
|  | 1180       ASSERT(current->property_dictionary()->FindEntry(*name) == | 
|  | 1181              StringDictionary::kNotFound); | 
|  | 1182 | 
|  | 1183       GenerateDictionaryNegativeLookup(masm(), miss, reg, name, | 
|  | 1184                                        scratch1, scratch2); | 
|  | 1185 | 
|  | 1186       __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 
|  | 1187       reg = holder_reg;  // From now on the object will be in holder_reg. | 
|  | 1188       __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | 
|  | 1189     } else { | 
|  | 1190       Handle<Map> current_map(current->map()); | 
|  | 1191       __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 
|  | 1192       // Branch on the result of the map check. | 
|  | 1193       __ Branch(miss, ne, scratch1, Operand(current_map)); | 
|  | 1194       // Check access rights to the global object.  This has to happen after | 
|  | 1195       // the map check so that we know that the object is actually a global | 
|  | 1196       // object. | 
|  | 1197       if (current->IsJSGlobalProxy()) { | 
|  | 1198         __ CheckAccessGlobalProxy(reg, scratch2, miss); | 
|  | 1199       } | 
|  | 1200       reg = holder_reg;  // From now on the object will be in holder_reg. | 
|  | 1201 | 
|  | 1202       if (heap()->InNewSpace(*prototype)) { | 
|  | 1203         // The prototype is in new space; we cannot store a reference to it | 
|  | 1204         // in the code.  Load it from the map. | 
|  | 1205         __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | 
|  | 1206       } else { | 
|  | 1207         // The prototype is in old space; load it directly. | 
|  | 1208         __ li(reg, Operand(prototype)); | 
|  | 1209       } | 
|  | 1210     } | 
|  | 1211 | 
|  | 1212     if (save_at_depth == depth) { | 
|  | 1213       __ sw(reg, MemOperand(sp)); | 
|  | 1214     } | 
|  | 1215 | 
|  | 1216     // Go to the next object in the prototype chain. | 
|  | 1217     current = prototype; | 
|  | 1218   } | 
|  | 1219 | 
|  | 1220   // Log the check depth. | 
|  | 1221   LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); | 
|  | 1222 | 
|  | 1223   // Check the holder map. | 
|  | 1224   __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 
|  | 1225   __ Branch(miss, ne, scratch1, Operand(Handle<Map>(current->map()))); | 
|  | 1226 | 
|  | 1227   // Perform security check for access to the global object. | 
|  | 1228   ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 
|  | 1229   if (holder->IsJSGlobalProxy()) { | 
|  | 1230     __ CheckAccessGlobalProxy(reg, scratch1, miss); | 
|  | 1231   } | 
|  | 1232 | 
|  | 1233   // If we've skipped any global objects, it's not enough to verify that | 
|  | 1234   // their maps haven't changed.  We also need to check that the property | 
|  | 1235   // cell for the property is still empty. | 
|  | 1236   GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); | 
|  | 1237 | 
|  | 1238   // Return the register containing the holder. | 
|  | 1239   return reg; | 
|  | 1240 } | 
|  | 1241 | 
|  | 1242 | 
| 1050 Register StubCompiler::CheckPrototypes(JSObject* object, | 1243 Register StubCompiler::CheckPrototypes(JSObject* object, | 
| 1051                                        Register object_reg, | 1244                                        Register object_reg, | 
| 1052                                        JSObject* holder, | 1245                                        JSObject* holder, | 
| 1053                                        Register holder_reg, | 1246                                        Register holder_reg, | 
| 1054                                        Register scratch1, | 1247                                        Register scratch1, | 
| 1055                                        Register scratch2, | 1248                                        Register scratch2, | 
| 1056                                        String* name, | 1249                                        String* name, | 
| 1057                                        int save_at_depth, | 1250                                        int save_at_depth, | 
| 1058                                        Label* miss) { | 1251                                        Label* miss) { | 
| 1059   // Make sure there's no overlap between holder and object registers. | 1252   // Make sure there's no overlap between holder and object registers. | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 1089         Object* lookup_result = NULL;  // Initialization to please compiler. | 1282         Object* lookup_result = NULL;  // Initialization to please compiler. | 
| 1090         if (!maybe_lookup_result->ToObject(&lookup_result)) { | 1283         if (!maybe_lookup_result->ToObject(&lookup_result)) { | 
| 1091           set_failure(Failure::cast(maybe_lookup_result)); | 1284           set_failure(Failure::cast(maybe_lookup_result)); | 
| 1092           return reg; | 1285           return reg; | 
| 1093         } | 1286         } | 
| 1094         name = String::cast(lookup_result); | 1287         name = String::cast(lookup_result); | 
| 1095       } | 1288       } | 
| 1096       ASSERT(current->property_dictionary()->FindEntry(name) == | 1289       ASSERT(current->property_dictionary()->FindEntry(name) == | 
| 1097              StringDictionary::kNotFound); | 1290              StringDictionary::kNotFound); | 
| 1098 | 1291 | 
| 1099       MaybeObject* negative_lookup = GenerateDictionaryNegativeLookup(masm(), | 1292       MaybeObject* negative_lookup = | 
| 1100                                                                       miss, | 1293           TryGenerateDictionaryNegativeLookup(masm(), | 
| 1101                                                                       reg, | 1294                                               miss, | 
| 1102                                                                       name, | 1295                                               reg, | 
| 1103                                                                       scratch1, | 1296                                               name, | 
| 1104                                                                       scratch2); | 1297                                               scratch1, | 
|  | 1298                                               scratch2); | 
|  | 1299 | 
| 1105       if (negative_lookup->IsFailure()) { | 1300       if (negative_lookup->IsFailure()) { | 
| 1106         set_failure(Failure::cast(negative_lookup)); | 1301         set_failure(Failure::cast(negative_lookup)); | 
| 1107         return reg; | 1302         return reg; | 
| 1108       } | 1303       } | 
| 1109 | 1304 | 
| 1110       __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1305       __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 
| 1111       reg = holder_reg;  // From now the object is in holder_reg. | 1306       reg = holder_reg;  // From now the object is in holder_reg. | 
| 1112       __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | 1307       __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | 
| 1113     } else if (heap()->InNewSpace(prototype)) { | 1308     } else if (heap()->InNewSpace(prototype)) { | 
| 1114       // Get the map of the current object. | 1309       // Get the map of the current object. | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1159   // Check the holder map. | 1354   // Check the holder map. | 
| 1160   __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1355   __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 
| 1161   __ Branch(miss, ne, scratch1, Operand(Handle<Map>(current->map()))); | 1356   __ Branch(miss, ne, scratch1, Operand(Handle<Map>(current->map()))); | 
| 1162 | 1357 | 
| 1163   // Log the check depth. | 1358   // Log the check depth. | 
| 1164   LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); | 1359   LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); | 
| 1165   // Perform security check for access to the global object. | 1360   // Perform security check for access to the global object. | 
| 1166   ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 1361   ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 
| 1167   if (holder->IsJSGlobalProxy()) { | 1362   if (holder->IsJSGlobalProxy()) { | 
| 1168     __ CheckAccessGlobalProxy(reg, scratch1, miss); | 1363     __ CheckAccessGlobalProxy(reg, scratch1, miss); | 
| 1169   }; | 1364   } | 
| 1170 | 1365 | 
| 1171   // If we've skipped any global objects, it's not enough to verify | 1366   // If we've skipped any global objects, it's not enough to verify | 
| 1172   // that their maps haven't changed.  We also need to check that the | 1367   // that their maps haven't changed.  We also need to check that the | 
| 1173   // property cell for the property is still empty. | 1368   // property cell for the property is still empty. | 
| 1174 | 1369 | 
| 1175   MaybeObject* result = GenerateCheckPropertyCells(masm(), | 1370   MaybeObject* result = TryGenerateCheckPropertyCells(masm(), | 
| 1176                                                    object, | 1371                                                       object, | 
| 1177                                                    holder, | 1372                                                       holder, | 
| 1178                                                    name, | 1373                                                       name, | 
| 1179                                                    scratch1, | 1374                                                       scratch1, | 
| 1180                                                    miss); | 1375                                                       miss); | 
| 1181   if (result->IsFailure()) set_failure(Failure::cast(result)); | 1376   if (result->IsFailure()) set_failure(Failure::cast(result)); | 
| 1182 | 1377 | 
| 1183   // Return the register containing the holder. | 1378   // Return the register containing the holder. | 
| 1184   return reg; | 1379   return reg; | 
| 1185 } | 1380 } | 
| 1186 | 1381 | 
| 1187 | 1382 | 
| 1188 void StubCompiler::GenerateLoadField(JSObject* object, | 1383 void StubCompiler::GenerateLoadField(Handle<JSObject> object, | 
| 1189                                      JSObject* holder, | 1384                                      Handle<JSObject> holder, | 
| 1190                                      Register receiver, | 1385                                      Register receiver, | 
| 1191                                      Register scratch1, | 1386                                      Register scratch1, | 
| 1192                                      Register scratch2, | 1387                                      Register scratch2, | 
| 1193                                      Register scratch3, | 1388                                      Register scratch3, | 
| 1194                                      int index, | 1389                                      int index, | 
| 1195                                      String* name, | 1390                                      Handle<String> name, | 
| 1196                                      Label* miss) { | 1391                                      Label* miss) { | 
| 1197   // Check that the receiver isn't a smi. | 1392   // Check that the receiver isn't a smi. | 
| 1198   __ And(scratch1, receiver, Operand(kSmiTagMask)); | 1393   __ And(scratch1, receiver, Operand(kSmiTagMask)); | 
| 1199   __ Branch(miss, eq, scratch1, Operand(zero_reg)); | 1394   __ Branch(miss, eq, scratch1, Operand(zero_reg)); | 
| 1200 | 1395 | 
| 1201   // Check that the maps haven't changed. | 1396   // Check that the maps haven't changed. | 
| 1202   Register reg = | 1397   Register reg = CheckPrototypes( | 
| 1203       CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, | 1398       object, receiver, holder, scratch1, scratch2, scratch3, name, miss); | 
| 1204                       name, miss); |  | 
| 1205   GenerateFastPropertyLoad(masm(), v0, reg, holder, index); | 1399   GenerateFastPropertyLoad(masm(), v0, reg, holder, index); | 
| 1206   __ Ret(); | 1400   __ Ret(); | 
| 1207 } | 1401 } | 
| 1208 | 1402 | 
| 1209 | 1403 | 
| 1210 void StubCompiler::GenerateLoadConstant(JSObject* object, | 1404 void StubCompiler::GenerateLoadConstant(Handle<JSObject> object, | 
| 1211                                         JSObject* holder, | 1405                                         Handle<JSObject> holder, | 
| 1212                                         Register receiver, | 1406                                         Register receiver, | 
| 1213                                         Register scratch1, | 1407                                         Register scratch1, | 
| 1214                                         Register scratch2, | 1408                                         Register scratch2, | 
| 1215                                         Register scratch3, | 1409                                         Register scratch3, | 
| 1216                                         Object* value, | 1410                                         Handle<Object> value, | 
| 1217                                         String* name, | 1411                                         Handle<String> name, | 
| 1218                                         Label* miss) { | 1412                                         Label* miss) { | 
| 1219   // Check that the receiver isn't a smi. | 1413   // Check that the receiver isn't a smi. | 
| 1220   __ JumpIfSmi(receiver, miss, scratch1); | 1414   __ JumpIfSmi(receiver, miss, scratch1); | 
| 1221 | 1415 | 
| 1222   // Check that the maps haven't changed. | 1416   // Check that the maps haven't changed. | 
| 1223   Register reg = | 1417   Register reg = | 
| 1224       CheckPrototypes(object, receiver, holder, | 1418       CheckPrototypes(object, receiver, holder, | 
| 1225                       scratch1, scratch2, scratch3, name, miss); | 1419                       scratch1, scratch2, scratch3, name, miss); | 
| 1226 | 1420 | 
| 1227   // Return the constant value. | 1421   // Return the constant value. | 
| 1228   __ li(v0, Operand(Handle<Object>(value))); | 1422   __ li(v0, Operand(value)); | 
| 1229   __ Ret(); | 1423   __ Ret(); | 
| 1230 } | 1424 } | 
| 1231 | 1425 | 
| 1232 | 1426 | 
| 1233 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, | 1427 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, | 
| 1234                                                 JSObject* holder, | 1428                                                 JSObject* holder, | 
| 1235                                                 Register receiver, | 1429                                                 Register receiver, | 
| 1236                                                 Register name_reg, | 1430                                                 Register name_reg, | 
| 1237                                                 Register scratch1, | 1431                                                 Register scratch1, | 
| 1238                                                 Register scratch2, | 1432                                                 Register scratch2, | 
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1383                                    scratch2, | 1577                                    scratch2, | 
| 1384                                    scratch3, | 1578                                    scratch3, | 
| 1385                                    name, | 1579                                    name, | 
| 1386                                    miss); | 1580                                    miss); | 
| 1387     } | 1581     } | 
| 1388 | 1582 | 
| 1389     if (lookup->type() == FIELD) { | 1583     if (lookup->type() == FIELD) { | 
| 1390       // We found FIELD property in prototype chain of interceptor's holder. | 1584       // We found FIELD property in prototype chain of interceptor's holder. | 
| 1391       // Retrieve a field from field's holder. | 1585       // Retrieve a field from field's holder. | 
| 1392       GenerateFastPropertyLoad(masm(), v0, holder_reg, | 1586       GenerateFastPropertyLoad(masm(), v0, holder_reg, | 
| 1393                                lookup->holder(), lookup->GetFieldIndex()); | 1587                                Handle<JSObject>(lookup->holder()), | 
|  | 1588                                lookup->GetFieldIndex()); | 
| 1394       __ Ret(); | 1589       __ Ret(); | 
| 1395     } else { | 1590     } else { | 
| 1396       // We found CALLBACKS property in prototype chain of interceptor's | 1591       // We found CALLBACKS property in prototype chain of interceptor's | 
| 1397       // holder. | 1592       // holder. | 
| 1398       ASSERT(lookup->type() == CALLBACKS); | 1593       ASSERT(lookup->type() == CALLBACKS); | 
| 1399       ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); | 1594       ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); | 
| 1400       AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); | 1595       AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); | 
| 1401       ASSERT(callback != NULL); | 1596       ASSERT(callback != NULL); | 
| 1402       ASSERT(callback->getter() != NULL); | 1597       ASSERT(callback->getter() != NULL); | 
| 1403 | 1598 | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 1433     PushInterceptorArguments(masm(), receiver, holder_reg, | 1628     PushInterceptorArguments(masm(), receiver, holder_reg, | 
| 1434                              name_reg, interceptor_holder); | 1629                              name_reg, interceptor_holder); | 
| 1435 | 1630 | 
| 1436     ExternalReference ref = ExternalReference( | 1631     ExternalReference ref = ExternalReference( | 
| 1437         IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), masm()->isolate()); | 1632         IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), masm()->isolate()); | 
| 1438     __ TailCallExternalReference(ref, 5, 1); | 1633     __ TailCallExternalReference(ref, 5, 1); | 
| 1439   } | 1634   } | 
| 1440 } | 1635 } | 
| 1441 | 1636 | 
| 1442 | 1637 | 
| 1443 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { | 1638 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) { | 
| 1444   if (kind_ == Code::KEYED_CALL_IC) { | 1639   if (kind_ == Code::KEYED_CALL_IC) { | 
| 1445     __ Branch(miss, ne, a2, Operand(Handle<String>(name))); | 1640     __ Branch(miss, ne, a2, Operand(name)); | 
| 1446   } | 1641   } | 
| 1447 } | 1642 } | 
| 1448 | 1643 | 
| 1449 | 1644 | 
| 1450 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, | 1645 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, | 
| 1451                                                    JSObject* holder, | 1646                                                    JSObject* holder, | 
| 1452                                                    String* name, | 1647                                                    String* name, | 
| 1453                                                    Label* miss) { | 1648                                                    Label* miss) { | 
| 1454   ASSERT(holder->IsGlobalObject()); | 1649   ASSERT(holder->IsGlobalObject()); | 
| 1455 | 1650 | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1492     // Check the shared function info. Make sure it hasn't changed. | 1687     // Check the shared function info. Make sure it hasn't changed. | 
| 1493     __ li(a3, Handle<SharedFunctionInfo>(function->shared())); | 1688     __ li(a3, Handle<SharedFunctionInfo>(function->shared())); | 
| 1494     __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 1689     __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 
| 1495     __ Branch(miss, ne, t0, Operand(a3)); | 1690     __ Branch(miss, ne, t0, Operand(a3)); | 
| 1496   } else { | 1691   } else { | 
| 1497     __ Branch(miss, ne, a1, Operand(Handle<JSFunction>(function))); | 1692     __ Branch(miss, ne, a1, Operand(Handle<JSFunction>(function))); | 
| 1498   } | 1693   } | 
| 1499 } | 1694 } | 
| 1500 | 1695 | 
| 1501 | 1696 | 
| 1502 MaybeObject* CallStubCompiler::GenerateMissBranch() { | 1697 void CallStubCompiler::GenerateMissBranch() { | 
| 1503   MaybeObject* maybe_obj = | 1698   Handle<Code> code = | 
| 1504       isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), | 1699       isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), | 
| 1505                                                kind_, | 1700                                                kind_, | 
| 1506                                                extra_ic_state_); | 1701                                                extra_state_); | 
|  | 1702   __ Jump(code, RelocInfo::CODE_TARGET); | 
|  | 1703 } | 
|  | 1704 | 
|  | 1705 | 
|  | 1706 // TODO(kmillikin): Eliminate this function when the stub cache is fully | 
|  | 1707 // handlified. | 
|  | 1708 MaybeObject* CallStubCompiler::TryGenerateMissBranch() { | 
|  | 1709   MaybeObject* maybe_obj = | 
|  | 1710       isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(), | 
|  | 1711                                                   kind_, | 
|  | 1712                                                   extra_state_); | 
| 1507   Object* obj; | 1713   Object* obj; | 
| 1508   if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1714   if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 
| 1509   __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); | 1715   __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); | 
| 1510   return obj; | 1716   return obj; | 
| 1511 } | 1717 } | 
| 1512 | 1718 | 
| 1513 | 1719 | 
| 1514 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object, | 1720 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, | 
| 1515                                                 JSObject* holder, | 1721                                                 Handle<JSObject> holder, | 
| 1516                                                 int index, | 1722                                                 int index, | 
| 1517                                                 String* name) { | 1723                                                 Handle<String> name) { | 
| 1518   // ----------- S t a t e ------------- | 1724   // ----------- S t a t e ------------- | 
| 1519   //  -- a2    : name | 1725   //  -- a2    : name | 
| 1520   //  -- ra    : return address | 1726   //  -- ra    : return address | 
| 1521   // ----------------------------------- | 1727   // ----------------------------------- | 
| 1522   Label miss; | 1728   Label miss; | 
| 1523 | 1729 | 
| 1524   GenerateNameCheck(name, &miss); | 1730   GenerateNameCheck(name, &miss); | 
| 1525 | 1731 | 
| 1526   const int argc = arguments().immediate(); | 1732   const int argc = arguments().immediate(); | 
| 1527 | 1733 | 
| 1528   // Get the receiver of the function from the stack into a0. | 1734   // Get the receiver of the function from the stack into a0. | 
| 1529   __ lw(a0, MemOperand(sp, argc * kPointerSize)); | 1735   __ lw(a0, MemOperand(sp, argc * kPointerSize)); | 
| 1530   // Check that the receiver isn't a smi. | 1736   // Check that the receiver isn't a smi. | 
| 1531   __ JumpIfSmi(a0, &miss, t0); | 1737   __ JumpIfSmi(a0, &miss, t0); | 
| 1532 | 1738 | 
| 1533   // Do the right check and compute the holder register. | 1739   // Do the right check and compute the holder register. | 
| 1534   Register reg = CheckPrototypes(object, a0, holder, a1, a3, t0, name, &miss); | 1740   Register reg = CheckPrototypes(object, a0, holder, a1, a3, t0, name, &miss); | 
| 1535   GenerateFastPropertyLoad(masm(), a1, reg, holder, index); | 1741   GenerateFastPropertyLoad(masm(), a1, reg, holder, index); | 
| 1536 | 1742 | 
| 1537   GenerateCallFunction(masm(), object, arguments(), &miss, extra_ic_state_); | 1743   GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); | 
| 1538 | 1744 | 
| 1539   // Handle call cache miss. | 1745   // Handle call cache miss. | 
| 1540   __ bind(&miss); | 1746   __ bind(&miss); | 
| 1541   MaybeObject* maybe_result = GenerateMissBranch(); | 1747   GenerateMissBranch(); | 
| 1542   if (maybe_result->IsFailure()) return maybe_result; |  | 
| 1543 | 1748 | 
| 1544   // Return the generated code. | 1749   // Return the generated code. | 
| 1545   return GetCode(FIELD, name); | 1750   return GetCode(FIELD, name); | 
| 1546 } | 1751 } | 
| 1547 | 1752 | 
| 1548 | 1753 | 
| 1549 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, | 1754 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, | 
| 1550                                                     JSObject* holder, | 1755                                                     JSObject* holder, | 
| 1551                                                     JSGlobalPropertyCell* cell, | 1756                                                     JSGlobalPropertyCell* cell, | 
| 1552                                                     JSFunction* function, | 1757                                                     JSFunction* function, | 
| 1553                                                     String* name) { | 1758                                                     String* name) { | 
| 1554   // ----------- S t a t e ------------- | 1759   // ----------- S t a t e ------------- | 
| 1555   //  -- a2    : name | 1760   //  -- a2    : name | 
| 1556   //  -- ra    : return address | 1761   //  -- ra    : return address | 
| 1557   //  -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 1762   //  -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 
| 1558   //  -- ... | 1763   //  -- ... | 
| 1559   //  -- sp[argc * 4]           : receiver | 1764   //  -- sp[argc * 4]           : receiver | 
| 1560   // ----------------------------------- | 1765   // ----------------------------------- | 
| 1561 | 1766 | 
| 1562   // If object is not an array, bail out to regular call. | 1767   // If object is not an array, bail out to regular call. | 
| 1563   if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); | 1768   if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); | 
| 1564 | 1769 | 
| 1565   Label miss; | 1770   Label miss; | 
| 1566 | 1771 | 
| 1567   GenerateNameCheck(name, &miss); | 1772   GenerateNameCheck(Handle<String>(name), &miss); | 
| 1568 | 1773 | 
| 1569   Register receiver = a1; | 1774   Register receiver = a1; | 
| 1570 | 1775 | 
| 1571   // Get the receiver from the stack. | 1776   // Get the receiver from the stack. | 
| 1572   const int argc = arguments().immediate(); | 1777   const int argc = arguments().immediate(); | 
| 1573   __ lw(receiver, MemOperand(sp, argc * kPointerSize)); | 1778   __ lw(receiver, MemOperand(sp, argc * kPointerSize)); | 
| 1574 | 1779 | 
| 1575   // Check that the receiver isn't a smi. | 1780   // Check that the receiver isn't a smi. | 
| 1576   __ JumpIfSmi(receiver, &miss); | 1781   __ JumpIfSmi(receiver, &miss); | 
| 1577 | 1782 | 
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1633       __ Addu(end_elements, end_elements, kEndElementsOffset); | 1838       __ Addu(end_elements, end_elements, kEndElementsOffset); | 
| 1634       __ sw(t0, MemOperand(end_elements)); | 1839       __ sw(t0, MemOperand(end_elements)); | 
| 1635 | 1840 | 
| 1636       // Check for a smi. | 1841       // Check for a smi. | 
| 1637       __ Drop(argc + 1); | 1842       __ Drop(argc + 1); | 
| 1638       __ Ret(); | 1843       __ Ret(); | 
| 1639 | 1844 | 
| 1640       __ bind(&with_write_barrier); | 1845       __ bind(&with_write_barrier); | 
| 1641 | 1846 | 
| 1642       __ lw(t2, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 1847       __ lw(t2, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 
| 1643       __ CheckFastSmiOnlyElements(t2, t2, &call_builtin); | 1848       __ CheckFastObjectElements(t2, t2, &call_builtin); | 
| 1644 | 1849 | 
| 1645       // Save new length. | 1850       // Save new length. | 
| 1646       __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1851       __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 
| 1647 | 1852 | 
| 1648       // Push the element. | 1853       // Push the element. | 
| 1649       // We may need a register containing the address end_elements below, | 1854       // We may need a register containing the address end_elements below, | 
| 1650       // so write back the value in end_elements. | 1855       // so write back the value in end_elements. | 
| 1651       __ sll(end_elements, v0, kPointerSizeLog2 - kSmiTagSize); | 1856       __ sll(end_elements, v0, kPointerSizeLog2 - kSmiTagSize); | 
| 1652       __ Addu(end_elements, elements, end_elements); | 1857       __ Addu(end_elements, elements, end_elements); | 
| 1653       __ Addu(end_elements, end_elements, kEndElementsOffset); | 1858       __ Addu(end_elements, end_elements, kEndElementsOffset); | 
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1723     } | 1928     } | 
| 1724     __ bind(&call_builtin); | 1929     __ bind(&call_builtin); | 
| 1725     __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, | 1930     __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, | 
| 1726                                                    masm()->isolate()), | 1931                                                    masm()->isolate()), | 
| 1727                                  argc + 1, | 1932                                  argc + 1, | 
| 1728                                  1); | 1933                                  1); | 
| 1729   } | 1934   } | 
| 1730 | 1935 | 
| 1731   // Handle call cache miss. | 1936   // Handle call cache miss. | 
| 1732   __ bind(&miss); | 1937   __ bind(&miss); | 
| 1733   MaybeObject* maybe_result = GenerateMissBranch(); | 1938   MaybeObject* maybe_result = TryGenerateMissBranch(); | 
| 1734   if (maybe_result->IsFailure()) return maybe_result; | 1939   if (maybe_result->IsFailure()) return maybe_result; | 
| 1735 | 1940 | 
| 1736   // Return the generated code. | 1941   // Return the generated code. | 
| 1737   return GetCode(function); | 1942   return TryGetCode(function); | 
| 1738 } | 1943 } | 
| 1739 | 1944 | 
| 1740 | 1945 | 
| 1741 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, | 1946 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, | 
| 1742                                                    JSObject* holder, | 1947                                                    JSObject* holder, | 
| 1743                                                    JSGlobalPropertyCell* cell, | 1948                                                    JSGlobalPropertyCell* cell, | 
| 1744                                                    JSFunction* function, | 1949                                                    JSFunction* function, | 
| 1745                                                    String* name) { | 1950                                                    String* name) { | 
| 1746   // ----------- S t a t e ------------- | 1951   // ----------- S t a t e ------------- | 
| 1747   //  -- a2    : name | 1952   //  -- a2    : name | 
| 1748   //  -- ra    : return address | 1953   //  -- ra    : return address | 
| 1749   //  -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 1954   //  -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 
| 1750   //  -- ... | 1955   //  -- ... | 
| 1751   //  -- sp[argc * 4]           : receiver | 1956   //  -- sp[argc * 4]           : receiver | 
| 1752   // ----------------------------------- | 1957   // ----------------------------------- | 
| 1753 | 1958 | 
| 1754   // If object is not an array, bail out to regular call. | 1959   // If object is not an array, bail out to regular call. | 
| 1755   if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); | 1960   if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); | 
| 1756 | 1961 | 
| 1757   Label miss, return_undefined, call_builtin; | 1962   Label miss, return_undefined, call_builtin; | 
| 1758 | 1963 | 
| 1759   Register receiver = a1; | 1964   Register receiver = a1; | 
| 1760   Register elements = a3; | 1965   Register elements = a3; | 
| 1761 | 1966 | 
| 1762   GenerateNameCheck(name, &miss); | 1967   GenerateNameCheck(Handle<String>(name), &miss); | 
| 1763 | 1968 | 
| 1764   // Get the receiver from the stack. | 1969   // Get the receiver from the stack. | 
| 1765   const int argc = arguments().immediate(); | 1970   const int argc = arguments().immediate(); | 
| 1766   __ lw(receiver, MemOperand(sp, argc * kPointerSize)); | 1971   __ lw(receiver, MemOperand(sp, argc * kPointerSize)); | 
| 1767 | 1972 | 
| 1768   // Check that the receiver isn't a smi. | 1973   // Check that the receiver isn't a smi. | 
| 1769   __ JumpIfSmi(receiver, &miss); | 1974   __ JumpIfSmi(receiver, &miss); | 
| 1770 | 1975 | 
| 1771   // Check that the maps haven't changed. | 1976   // Check that the maps haven't changed. | 
| 1772   CheckPrototypes(JSObject::cast(object), | 1977   CheckPrototypes(JSObject::cast(object), | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1812   __ Ret(); | 2017   __ Ret(); | 
| 1813 | 2018 | 
| 1814   __ bind(&call_builtin); | 2019   __ bind(&call_builtin); | 
| 1815   __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop, | 2020   __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop, | 
| 1816                                                  masm()->isolate()), | 2021                                                  masm()->isolate()), | 
| 1817                                argc + 1, | 2022                                argc + 1, | 
| 1818                                1); | 2023                                1); | 
| 1819 | 2024 | 
| 1820   // Handle call cache miss. | 2025   // Handle call cache miss. | 
| 1821   __ bind(&miss); | 2026   __ bind(&miss); | 
| 1822   MaybeObject* maybe_result = GenerateMissBranch(); | 2027   MaybeObject* maybe_result = TryGenerateMissBranch(); | 
| 1823   if (maybe_result->IsFailure()) return maybe_result; | 2028   if (maybe_result->IsFailure()) return maybe_result; | 
| 1824 | 2029 | 
| 1825   // Return the generated code. | 2030   // Return the generated code. | 
| 1826   return GetCode(function); | 2031   return TryGetCode(function); | 
| 1827 } | 2032 } | 
| 1828 | 2033 | 
| 1829 | 2034 | 
| 1830 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( | 2035 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( | 
| 1831     Object* object, | 2036     Object* object, | 
| 1832     JSObject* holder, | 2037     JSObject* holder, | 
| 1833     JSGlobalPropertyCell* cell, | 2038     JSGlobalPropertyCell* cell, | 
| 1834     JSFunction* function, | 2039     JSFunction* function, | 
| 1835     String* name) { | 2040     String* name) { | 
| 1836   // ----------- S t a t e ------------- | 2041   // ----------- S t a t e ------------- | 
| 1837   //  -- a2                     : function name | 2042   //  -- a2                     : function name | 
| 1838   //  -- ra                     : return address | 2043   //  -- ra                     : return address | 
| 1839   //  -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2044   //  -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 
| 1840   //  -- ... | 2045   //  -- ... | 
| 1841   //  -- sp[argc * 4]           : receiver | 2046   //  -- sp[argc * 4]           : receiver | 
| 1842   // ----------------------------------- | 2047   // ----------------------------------- | 
| 1843 | 2048 | 
| 1844   // If object is not a string, bail out to regular call. | 2049   // If object is not a string, bail out to regular call. | 
| 1845   if (!object->IsString() || cell != NULL) return heap()->undefined_value(); | 2050   if (!object->IsString() || cell != NULL) return heap()->undefined_value(); | 
| 1846 | 2051 | 
| 1847   const int argc = arguments().immediate(); | 2052   const int argc = arguments().immediate(); | 
| 1848 | 2053 | 
| 1849   Label miss; | 2054   Label miss; | 
| 1850   Label name_miss; | 2055   Label name_miss; | 
| 1851   Label index_out_of_range; | 2056   Label index_out_of_range; | 
| 1852 | 2057 | 
| 1853   Label* index_out_of_range_label = &index_out_of_range; | 2058   Label* index_out_of_range_label = &index_out_of_range; | 
| 1854 | 2059 | 
| 1855   if (kind_ == Code::CALL_IC && | 2060   if (kind_ == Code::CALL_IC && | 
| 1856       (CallICBase::StringStubState::decode(extra_ic_state_) == | 2061       (CallICBase::StringStubState::decode(extra_state_) == | 
| 1857        DEFAULT_STRING_STUB)) { | 2062        DEFAULT_STRING_STUB)) { | 
| 1858     index_out_of_range_label = &miss; | 2063     index_out_of_range_label = &miss; | 
| 1859   } | 2064   } | 
| 1860 | 2065 | 
| 1861   GenerateNameCheck(name, &name_miss); | 2066   GenerateNameCheck(Handle<String>(name), &name_miss); | 
| 1862 | 2067 | 
| 1863   // Check that the maps starting from the prototype haven't changed. | 2068   // Check that the maps starting from the prototype haven't changed. | 
| 1864   GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2069   GenerateDirectLoadGlobalFunctionPrototype(masm(), | 
| 1865                                             Context::STRING_FUNCTION_INDEX, | 2070                                             Context::STRING_FUNCTION_INDEX, | 
| 1866                                             v0, | 2071                                             v0, | 
| 1867                                             &miss); | 2072                                             &miss); | 
| 1868   ASSERT(object != holder); | 2073   ASSERT(object != holder); | 
| 1869   CheckPrototypes(JSObject::cast(object->GetPrototype()), v0, holder, | 2074   CheckPrototypes(JSObject::cast(object->GetPrototype()), v0, holder, | 
| 1870                   a1, a3, t0, name, &miss); | 2075                   a1, a3, t0, name, &miss); | 
| 1871 | 2076 | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 1899     __ bind(&index_out_of_range); | 2104     __ bind(&index_out_of_range); | 
| 1900     __ LoadRoot(v0, Heap::kNanValueRootIndex); | 2105     __ LoadRoot(v0, Heap::kNanValueRootIndex); | 
| 1901     __ Drop(argc + 1); | 2106     __ Drop(argc + 1); | 
| 1902     __ Ret(); | 2107     __ Ret(); | 
| 1903   } | 2108   } | 
| 1904 | 2109 | 
| 1905   __ bind(&miss); | 2110   __ bind(&miss); | 
| 1906   // Restore function name in a2. | 2111   // Restore function name in a2. | 
| 1907   __ li(a2, Handle<String>(name)); | 2112   __ li(a2, Handle<String>(name)); | 
| 1908   __ bind(&name_miss); | 2113   __ bind(&name_miss); | 
| 1909   MaybeObject* maybe_result = GenerateMissBranch(); | 2114   MaybeObject* maybe_result = TryGenerateMissBranch(); | 
| 1910   if (maybe_result->IsFailure()) return maybe_result; | 2115   if (maybe_result->IsFailure()) return maybe_result; | 
| 1911 | 2116 | 
| 1912   // Return the generated code. | 2117   // Return the generated code. | 
| 1913   return GetCode(function); | 2118   return TryGetCode(function); | 
| 1914 } | 2119 } | 
| 1915 | 2120 | 
| 1916 | 2121 | 
| 1917 MaybeObject* CallStubCompiler::CompileStringCharAtCall( | 2122 MaybeObject* CallStubCompiler::CompileStringCharAtCall( | 
| 1918     Object* object, | 2123     Object* object, | 
| 1919     JSObject* holder, | 2124     JSObject* holder, | 
| 1920     JSGlobalPropertyCell* cell, | 2125     JSGlobalPropertyCell* cell, | 
| 1921     JSFunction* function, | 2126     JSFunction* function, | 
| 1922     String* name) { | 2127     String* name) { | 
| 1923   // ----------- S t a t e ------------- | 2128   // ----------- S t a t e ------------- | 
| 1924   //  -- a2                     : function name | 2129   //  -- a2                     : function name | 
| 1925   //  -- ra                     : return address | 2130   //  -- ra                     : return address | 
| 1926   //  -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2131   //  -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 
| 1927   //  -- ... | 2132   //  -- ... | 
| 1928   //  -- sp[argc * 4]           : receiver | 2133   //  -- sp[argc * 4]           : receiver | 
| 1929   // ----------------------------------- | 2134   // ----------------------------------- | 
| 1930 | 2135 | 
| 1931   // If object is not a string, bail out to regular call. | 2136   // If object is not a string, bail out to regular call. | 
| 1932   if (!object->IsString() || cell != NULL) return heap()->undefined_value(); | 2137   if (!object->IsString() || cell != NULL) return heap()->undefined_value(); | 
| 1933 | 2138 | 
| 1934   const int argc = arguments().immediate(); | 2139   const int argc = arguments().immediate(); | 
| 1935 | 2140 | 
| 1936   Label miss; | 2141   Label miss; | 
| 1937   Label name_miss; | 2142   Label name_miss; | 
| 1938   Label index_out_of_range; | 2143   Label index_out_of_range; | 
| 1939   Label* index_out_of_range_label = &index_out_of_range; | 2144   Label* index_out_of_range_label = &index_out_of_range; | 
| 1940 | 2145 | 
| 1941   if (kind_ == Code::CALL_IC && | 2146   if (kind_ == Code::CALL_IC && | 
| 1942       (CallICBase::StringStubState::decode(extra_ic_state_) == | 2147       (CallICBase::StringStubState::decode(extra_state_) == | 
| 1943        DEFAULT_STRING_STUB)) { | 2148        DEFAULT_STRING_STUB)) { | 
| 1944     index_out_of_range_label = &miss; | 2149     index_out_of_range_label = &miss; | 
| 1945   } | 2150   } | 
| 1946 | 2151 | 
| 1947   GenerateNameCheck(name, &name_miss); | 2152   GenerateNameCheck(Handle<String>(name), &name_miss); | 
| 1948 | 2153 | 
| 1949   // Check that the maps starting from the prototype haven't changed. | 2154   // Check that the maps starting from the prototype haven't changed. | 
| 1950   GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2155   GenerateDirectLoadGlobalFunctionPrototype(masm(), | 
| 1951                                             Context::STRING_FUNCTION_INDEX, | 2156                                             Context::STRING_FUNCTION_INDEX, | 
| 1952                                             v0, | 2157                                             v0, | 
| 1953                                             &miss); | 2158                                             &miss); | 
| 1954   ASSERT(object != holder); | 2159   ASSERT(object != holder); | 
| 1955   CheckPrototypes(JSObject::cast(object->GetPrototype()), v0, holder, | 2160   CheckPrototypes(JSObject::cast(object->GetPrototype()), v0, holder, | 
| 1956                   a1, a3, t0, name, &miss); | 2161                   a1, a3, t0, name, &miss); | 
| 1957 | 2162 | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 1987     __ bind(&index_out_of_range); | 2192     __ bind(&index_out_of_range); | 
| 1988     __ LoadRoot(v0, Heap::kEmptyStringRootIndex); | 2193     __ LoadRoot(v0, Heap::kEmptyStringRootIndex); | 
| 1989     __ Drop(argc + 1); | 2194     __ Drop(argc + 1); | 
| 1990     __ Ret(); | 2195     __ Ret(); | 
| 1991   } | 2196   } | 
| 1992 | 2197 | 
| 1993   __ bind(&miss); | 2198   __ bind(&miss); | 
| 1994   // Restore function name in a2. | 2199   // Restore function name in a2. | 
| 1995   __ li(a2, Handle<String>(name)); | 2200   __ li(a2, Handle<String>(name)); | 
| 1996   __ bind(&name_miss); | 2201   __ bind(&name_miss); | 
| 1997   MaybeObject* maybe_result = GenerateMissBranch(); | 2202   MaybeObject* maybe_result = TryGenerateMissBranch(); | 
| 1998   if (maybe_result->IsFailure()) return maybe_result; | 2203   if (maybe_result->IsFailure()) return maybe_result; | 
| 1999 | 2204 | 
| 2000   // Return the generated code. | 2205   // Return the generated code. | 
| 2001   return GetCode(function); | 2206   return TryGetCode(function); | 
| 2002 } | 2207 } | 
| 2003 | 2208 | 
| 2004 | 2209 | 
| 2005 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( | 2210 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( | 
| 2006     Object* object, | 2211     Object* object, | 
| 2007     JSObject* holder, | 2212     JSObject* holder, | 
| 2008     JSGlobalPropertyCell* cell, | 2213     JSGlobalPropertyCell* cell, | 
| 2009     JSFunction* function, | 2214     JSFunction* function, | 
| 2010     String* name) { | 2215     String* name) { | 
| 2011   // ----------- S t a t e ------------- | 2216   // ----------- S t a t e ------------- | 
| 2012   //  -- a2                     : function name | 2217   //  -- a2                     : function name | 
| 2013   //  -- ra                     : return address | 2218   //  -- ra                     : return address | 
| 2014   //  -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2219   //  -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 
| 2015   //  -- ... | 2220   //  -- ... | 
| 2016   //  -- sp[argc * 4]           : receiver | 2221   //  -- sp[argc * 4]           : receiver | 
| 2017   // ----------------------------------- | 2222   // ----------------------------------- | 
| 2018 | 2223 | 
| 2019   const int argc = arguments().immediate(); | 2224   const int argc = arguments().immediate(); | 
| 2020 | 2225 | 
| 2021   // If the object is not a JSObject or we got an unexpected number of | 2226   // If the object is not a JSObject or we got an unexpected number of | 
| 2022   // arguments, bail out to the regular call. | 2227   // arguments, bail out to the regular call. | 
| 2023   if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 2228   if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 
| 2024 | 2229 | 
| 2025   Label miss; | 2230   Label miss; | 
| 2026   GenerateNameCheck(name, &miss); | 2231   GenerateNameCheck(Handle<String>(name), &miss); | 
| 2027 | 2232 | 
| 2028   if (cell == NULL) { | 2233   if (cell == NULL) { | 
| 2029     __ lw(a1, MemOperand(sp, 1 * kPointerSize)); | 2234     __ lw(a1, MemOperand(sp, 1 * kPointerSize)); | 
| 2030 | 2235 | 
| 2031     STATIC_ASSERT(kSmiTag == 0); | 2236     STATIC_ASSERT(kSmiTag == 0); | 
| 2032     __ JumpIfSmi(a1, &miss); | 2237     __ JumpIfSmi(a1, &miss); | 
| 2033 | 2238 | 
| 2034     CheckPrototypes(JSObject::cast(object), a1, holder, v0, a3, t0, name, | 2239     CheckPrototypes(JSObject::cast(object), a1, holder, v0, a3, t0, name, | 
| 2035                     &miss); | 2240                     &miss); | 
| 2036   } else { | 2241   } else { | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 2059   StubRuntimeCallHelper call_helper; | 2264   StubRuntimeCallHelper call_helper; | 
| 2060   char_from_code_generator.GenerateSlow(masm(), call_helper); | 2265   char_from_code_generator.GenerateSlow(masm(), call_helper); | 
| 2061 | 2266 | 
| 2062   // Tail call the full function. We do not have to patch the receiver | 2267   // Tail call the full function. We do not have to patch the receiver | 
| 2063   // because the function makes no use of it. | 2268   // because the function makes no use of it. | 
| 2064   __ bind(&slow); | 2269   __ bind(&slow); | 
| 2065   __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); | 2270   __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); | 
| 2066 | 2271 | 
| 2067   __ bind(&miss); | 2272   __ bind(&miss); | 
| 2068   // a2: function name. | 2273   // a2: function name. | 
| 2069   MaybeObject* maybe_result = GenerateMissBranch(); | 2274   MaybeObject* maybe_result = TryGenerateMissBranch(); | 
| 2070   if (maybe_result->IsFailure()) return maybe_result; | 2275   if (maybe_result->IsFailure()) return maybe_result; | 
| 2071 | 2276 | 
| 2072   // Return the generated code. | 2277   // Return the generated code. | 
| 2073   return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2278   return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); | 
| 2074 } | 2279 } | 
| 2075 | 2280 | 
| 2076 | 2281 | 
| 2077 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, | 2282 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, | 
| 2078                                                     JSObject* holder, | 2283                                                     JSObject* holder, | 
| 2079                                                     JSGlobalPropertyCell* cell, | 2284                                                     JSGlobalPropertyCell* cell, | 
| 2080                                                     JSFunction* function, | 2285                                                     JSFunction* function, | 
| 2081                                                     String* name) { | 2286                                                     String* name) { | 
| 2082   // ----------- S t a t e ------------- | 2287   // ----------- S t a t e ------------- | 
| 2083   //  -- a2                     : function name | 2288   //  -- a2                     : function name | 
| 2084   //  -- ra                     : return address | 2289   //  -- ra                     : return address | 
| 2085   //  -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2290   //  -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 
| 2086   //  -- ... | 2291   //  -- ... | 
| 2087   //  -- sp[argc * 4]           : receiver | 2292   //  -- sp[argc * 4]           : receiver | 
| 2088   // ----------------------------------- | 2293   // ----------------------------------- | 
| 2089 | 2294 | 
| 2090   if (!CpuFeatures::IsSupported(FPU)) | 2295   if (!CpuFeatures::IsSupported(FPU)) | 
| 2091     return heap()->undefined_value(); | 2296     return heap()->undefined_value(); | 
| 2092   CpuFeatures::Scope scope_fpu(FPU); | 2297   CpuFeatures::Scope scope_fpu(FPU); | 
| 2093 | 2298 | 
| 2094   const int argc = arguments().immediate(); | 2299   const int argc = arguments().immediate(); | 
| 2095 | 2300 | 
| 2096   // If the object is not a JSObject or we got an unexpected number of | 2301   // If the object is not a JSObject or we got an unexpected number of | 
| 2097   // arguments, bail out to the regular call. | 2302   // arguments, bail out to the regular call. | 
| 2098   if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 2303   if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 
| 2099 | 2304 | 
| 2100   Label miss, slow; | 2305   Label miss, slow; | 
| 2101   GenerateNameCheck(name, &miss); | 2306   GenerateNameCheck(Handle<String>(name), &miss); | 
| 2102 | 2307 | 
| 2103   if (cell == NULL) { | 2308   if (cell == NULL) { | 
| 2104     __ lw(a1, MemOperand(sp, 1 * kPointerSize)); | 2309     __ lw(a1, MemOperand(sp, 1 * kPointerSize)); | 
| 2105 | 2310 | 
| 2106     STATIC_ASSERT(kSmiTag == 0); | 2311     STATIC_ASSERT(kSmiTag == 0); | 
| 2107     __ JumpIfSmi(a1, &miss); | 2312     __ JumpIfSmi(a1, &miss); | 
| 2108 | 2313 | 
| 2109     CheckPrototypes(JSObject::cast(object), a1, holder, a0, a3, t0, name, | 2314     CheckPrototypes(JSObject::cast(object), a1, holder, a0, a3, t0, name, | 
| 2110                     &miss); | 2315                     &miss); | 
| 2111   } else { | 2316   } else { | 
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2193   // Restore FCSR and fall to slow case. | 2398   // Restore FCSR and fall to slow case. | 
| 2194   __ ctc1(a3, FCSR); | 2399   __ ctc1(a3, FCSR); | 
| 2195 | 2400 | 
| 2196   __ bind(&slow); | 2401   __ bind(&slow); | 
| 2197   // Tail call the full function. We do not have to patch the receiver | 2402   // Tail call the full function. We do not have to patch the receiver | 
| 2198   // because the function makes no use of it. | 2403   // because the function makes no use of it. | 
| 2199   __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); | 2404   __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); | 
| 2200 | 2405 | 
| 2201   __ bind(&miss); | 2406   __ bind(&miss); | 
| 2202   // a2: function name. | 2407   // a2: function name. | 
| 2203   MaybeObject* obj = GenerateMissBranch(); | 2408   MaybeObject* obj = TryGenerateMissBranch(); | 
| 2204   if (obj->IsFailure()) return obj; | 2409   if (obj->IsFailure()) return obj; | 
| 2205 | 2410 | 
| 2206   // Return the generated code. | 2411   // Return the generated code. | 
| 2207   return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2412   return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); | 
| 2208 } | 2413 } | 
| 2209 | 2414 | 
| 2210 | 2415 | 
| 2211 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, | 2416 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, | 
| 2212                                                   JSObject* holder, | 2417                                                   JSObject* holder, | 
| 2213                                                   JSGlobalPropertyCell* cell, | 2418                                                   JSGlobalPropertyCell* cell, | 
| 2214                                                   JSFunction* function, | 2419                                                   JSFunction* function, | 
| 2215                                                   String* name) { | 2420                                                   String* name) { | 
| 2216   // ----------- S t a t e ------------- | 2421   // ----------- S t a t e ------------- | 
| 2217   //  -- a2                     : function name | 2422   //  -- a2                     : function name | 
| 2218   //  -- ra                     : return address | 2423   //  -- ra                     : return address | 
| 2219   //  -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2424   //  -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 
| 2220   //  -- ... | 2425   //  -- ... | 
| 2221   //  -- sp[argc * 4]           : receiver | 2426   //  -- sp[argc * 4]           : receiver | 
| 2222   // ----------------------------------- | 2427   // ----------------------------------- | 
| 2223 | 2428 | 
| 2224   const int argc = arguments().immediate(); | 2429   const int argc = arguments().immediate(); | 
| 2225 | 2430 | 
| 2226   // If the object is not a JSObject or we got an unexpected number of | 2431   // If the object is not a JSObject or we got an unexpected number of | 
| 2227   // arguments, bail out to the regular call. | 2432   // arguments, bail out to the regular call. | 
| 2228   if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 2433   if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); | 
| 2229 | 2434 | 
| 2230   Label miss; | 2435   Label miss; | 
| 2231   GenerateNameCheck(name, &miss); | 2436   GenerateNameCheck(Handle<String>(name), &miss); | 
| 2232 | 2437 | 
| 2233   if (cell == NULL) { | 2438   if (cell == NULL) { | 
| 2234     __ lw(a1, MemOperand(sp, 1 * kPointerSize)); | 2439     __ lw(a1, MemOperand(sp, 1 * kPointerSize)); | 
| 2235 | 2440 | 
| 2236     STATIC_ASSERT(kSmiTag == 0); | 2441     STATIC_ASSERT(kSmiTag == 0); | 
| 2237     __ JumpIfSmi(a1, &miss); | 2442     __ JumpIfSmi(a1, &miss); | 
| 2238 | 2443 | 
| 2239     CheckPrototypes(JSObject::cast(object), a1, holder, v0, a3, t0, name, | 2444     CheckPrototypes(JSObject::cast(object), a1, holder, v0, a3, t0, name, | 
| 2240                     &miss); | 2445                     &miss); | 
| 2241   } else { | 2446   } else { | 
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2295   __ Drop(argc + 1); | 2500   __ Drop(argc + 1); | 
| 2296   __ Ret(); | 2501   __ Ret(); | 
| 2297 | 2502 | 
| 2298   // Tail call the full function. We do not have to patch the receiver | 2503   // Tail call the full function. We do not have to patch the receiver | 
| 2299   // because the function makes no use of it. | 2504   // because the function makes no use of it. | 
| 2300   __ bind(&slow); | 2505   __ bind(&slow); | 
| 2301   __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); | 2506   __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD); | 
| 2302 | 2507 | 
| 2303   __ bind(&miss); | 2508   __ bind(&miss); | 
| 2304   // a2: function name. | 2509   // a2: function name. | 
| 2305   MaybeObject* maybe_result = GenerateMissBranch(); | 2510   MaybeObject* maybe_result = TryGenerateMissBranch(); | 
| 2306   if (maybe_result->IsFailure()) return maybe_result; | 2511   if (maybe_result->IsFailure()) return maybe_result; | 
| 2307 | 2512 | 
| 2308   // Return the generated code. | 2513   // Return the generated code. | 
| 2309   return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2514   return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); | 
| 2310 } | 2515 } | 
| 2311 | 2516 | 
| 2312 | 2517 | 
| 2313 MaybeObject* CallStubCompiler::CompileFastApiCall( | 2518 MaybeObject* CallStubCompiler::CompileFastApiCall( | 
| 2314     const CallOptimization& optimization, | 2519     const CallOptimization& optimization, | 
| 2315     Object* object, | 2520     Object* object, | 
| 2316     JSObject* holder, | 2521     JSObject* holder, | 
| 2317     JSGlobalPropertyCell* cell, | 2522     JSGlobalPropertyCell* cell, | 
| 2318     JSFunction* function, | 2523     JSFunction* function, | 
| 2319     String* name) { | 2524     String* name) { | 
| 2320 | 2525 | 
| 2321   Counters* counters = isolate()->counters(); | 2526   Counters* counters = isolate()->counters(); | 
| 2322 | 2527 | 
| 2323   ASSERT(optimization.is_simple_api_call()); | 2528   ASSERT(optimization.is_simple_api_call()); | 
| 2324   // Bail out if object is a global object as we don't want to | 2529   // Bail out if object is a global object as we don't want to | 
| 2325   // repatch it to global receiver. | 2530   // repatch it to global receiver. | 
| 2326   if (object->IsGlobalObject()) return heap()->undefined_value(); | 2531   if (object->IsGlobalObject()) return heap()->undefined_value(); | 
| 2327   if (cell != NULL) return heap()->undefined_value(); | 2532   if (cell != NULL) return heap()->undefined_value(); | 
| 2328   if (!object->IsJSObject()) return heap()->undefined_value(); | 2533   if (!object->IsJSObject()) return heap()->undefined_value(); | 
| 2329   int depth = optimization.GetPrototypeDepthOfExpectedType( | 2534   int depth = optimization.GetPrototypeDepthOfExpectedType( | 
| 2330             JSObject::cast(object), holder); | 2535             JSObject::cast(object), holder); | 
| 2331   if (depth == kInvalidProtoDepth) return heap()->undefined_value(); | 2536   if (depth == kInvalidProtoDepth) return heap()->undefined_value(); | 
| 2332 | 2537 | 
| 2333   Label miss, miss_before_stack_reserved; | 2538   Label miss, miss_before_stack_reserved; | 
| 2334 | 2539 | 
| 2335   GenerateNameCheck(name, &miss_before_stack_reserved); | 2540   GenerateNameCheck(Handle<String>(name), &miss_before_stack_reserved); | 
| 2336 | 2541 | 
| 2337   // Get the receiver from the stack. | 2542   // Get the receiver from the stack. | 
| 2338   const int argc = arguments().immediate(); | 2543   const int argc = arguments().immediate(); | 
| 2339   __ lw(a1, MemOperand(sp, argc * kPointerSize)); | 2544   __ lw(a1, MemOperand(sp, argc * kPointerSize)); | 
| 2340 | 2545 | 
| 2341   // Check that the receiver isn't a smi. | 2546   // Check that the receiver isn't a smi. | 
| 2342   __ JumpIfSmi(a1, &miss_before_stack_reserved); | 2547   __ JumpIfSmi(a1, &miss_before_stack_reserved); | 
| 2343 | 2548 | 
| 2344   __ IncrementCounter(counters->call_const(), 1, a0, a3); | 2549   __ IncrementCounter(counters->call_const(), 1, a0, a3); | 
| 2345   __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a3); | 2550   __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a3); | 
| 2346 | 2551 | 
| 2347   ReserveSpaceForFastApiCall(masm(), a0); | 2552   ReserveSpaceForFastApiCall(masm(), a0); | 
| 2348 | 2553 | 
| 2349   // Check that the maps haven't changed and find a Holder as a side effect. | 2554   // Check that the maps haven't changed and find a Holder as a side effect. | 
| 2350   CheckPrototypes(JSObject::cast(object), a1, holder, a0, a3, t0, name, | 2555   CheckPrototypes(JSObject::cast(object), a1, holder, a0, a3, t0, name, | 
| 2351                   depth, &miss); | 2556                   depth, &miss); | 
| 2352 | 2557 | 
| 2353   MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); | 2558   MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); | 
| 2354   if (result->IsFailure()) return result; | 2559   if (result->IsFailure()) return result; | 
| 2355 | 2560 | 
| 2356   __ bind(&miss); | 2561   __ bind(&miss); | 
| 2357   FreeSpaceForFastApiCall(masm()); | 2562   FreeSpaceForFastApiCall(masm()); | 
| 2358 | 2563 | 
| 2359   __ bind(&miss_before_stack_reserved); | 2564   __ bind(&miss_before_stack_reserved); | 
| 2360   MaybeObject* maybe_result = GenerateMissBranch(); | 2565   MaybeObject* maybe_result = TryGenerateMissBranch(); | 
| 2361   if (maybe_result->IsFailure()) return maybe_result; | 2566   if (maybe_result->IsFailure()) return maybe_result; | 
| 2362 | 2567 | 
| 2363   // Return the generated code. | 2568   // Return the generated code. | 
| 2364   return GetCode(function); | 2569   return TryGetCode(function); | 
| 2365 } | 2570 } | 
| 2366 | 2571 | 
| 2367 | 2572 | 
| 2368 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, | 2573 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, | 
| 2369                                                    JSObject* holder, | 2574                                                    JSObject* holder, | 
| 2370                                                    JSFunction* function, | 2575                                                    JSFunction* function, | 
| 2371                                                    String* name, | 2576                                                    String* name, | 
| 2372                                                    CheckType check) { | 2577                                                    CheckType check) { | 
| 2373   // ----------- S t a t e ------------- | 2578   // ----------- S t a t e ------------- | 
| 2374   //  -- a2    : name | 2579   //  -- a2    : name | 
| 2375   //  -- ra    : return address | 2580   //  -- ra    : return address | 
| 2376   // ----------------------------------- | 2581   // ----------------------------------- | 
| 2377   if (HasCustomCallGenerator(function)) { | 2582   if (HasCustomCallGenerator(function)) { | 
| 2378     MaybeObject* maybe_result = CompileCustomCall( | 2583     MaybeObject* maybe_result = CompileCustomCall( | 
| 2379         object, holder, NULL, function, name); | 2584         object, holder, NULL, function, name); | 
| 2380     Object* result; | 2585     Object* result; | 
| 2381     if (!maybe_result->ToObject(&result)) return maybe_result; | 2586     if (!maybe_result->ToObject(&result)) return maybe_result; | 
| 2382     // Undefined means bail out to regular compiler. | 2587     // Undefined means bail out to regular compiler. | 
| 2383     if (!result->IsUndefined()) return result; | 2588     if (!result->IsUndefined()) return result; | 
| 2384   } | 2589   } | 
| 2385 | 2590 | 
| 2386   Label miss; | 2591   Label miss; | 
| 2387 | 2592 | 
| 2388   GenerateNameCheck(name, &miss); | 2593   GenerateNameCheck(Handle<String>(name), &miss); | 
| 2389 | 2594 | 
| 2390   // Get the receiver from the stack. | 2595   // Get the receiver from the stack. | 
| 2391   const int argc = arguments().immediate(); | 2596   const int argc = arguments().immediate(); | 
| 2392   __ lw(a1, MemOperand(sp, argc * kPointerSize)); | 2597   __ lw(a1, MemOperand(sp, argc * kPointerSize)); | 
| 2393 | 2598 | 
| 2394   // Check that the receiver isn't a smi. | 2599   // Check that the receiver isn't a smi. | 
| 2395   if (check != NUMBER_CHECK) { | 2600   if (check != NUMBER_CHECK) { | 
| 2396     __ And(t1, a1, Operand(kSmiTagMask)); | 2601     __ And(t1, a1, Operand(kSmiTagMask)); | 
| 2397     __ Branch(&miss, eq, t1, Operand(zero_reg)); | 2602     __ Branch(&miss, eq, t1, Operand(zero_reg)); | 
| 2398   } | 2603   } | 
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2477         CheckPrototypes(JSObject::cast(object->GetPrototype()), a0, holder, a3, | 2682         CheckPrototypes(JSObject::cast(object->GetPrototype()), a0, holder, a3, | 
| 2478                         a1, t0, name, &miss); | 2683                         a1, t0, name, &miss); | 
| 2479       } | 2684       } | 
| 2480       break; | 2685       break; | 
| 2481     } | 2686     } | 
| 2482 | 2687 | 
| 2483     default: | 2688     default: | 
| 2484       UNREACHABLE(); | 2689       UNREACHABLE(); | 
| 2485   } | 2690   } | 
| 2486 | 2691 | 
| 2487   CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 2692   CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 
| 2488       ? CALL_AS_FUNCTION | 2693       ? CALL_AS_FUNCTION | 
| 2489       : CALL_AS_METHOD; | 2694       : CALL_AS_METHOD; | 
| 2490   __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind); | 2695   __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind); | 
| 2491 | 2696 | 
| 2492   // Handle call cache miss. | 2697   // Handle call cache miss. | 
| 2493   __ bind(&miss); | 2698   __ bind(&miss); | 
| 2494 | 2699 | 
| 2495   MaybeObject* maybe_result = GenerateMissBranch(); | 2700   MaybeObject* maybe_result = TryGenerateMissBranch(); | 
| 2496   if (maybe_result->IsFailure()) return maybe_result; | 2701   if (maybe_result->IsFailure()) return maybe_result; | 
| 2497 | 2702 | 
| 2498   // Return the generated code. | 2703   // Return the generated code. | 
| 2499   return GetCode(function); | 2704   return TryGetCode(function); | 
| 2500 } | 2705 } | 
| 2501 | 2706 | 
| 2502 | 2707 | 
| 2503 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, | 2708 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, | 
| 2504                                                       JSObject* holder, | 2709                                                       JSObject* holder, | 
| 2505                                                       String* name) { | 2710                                                       String* name) { | 
| 2506   // ----------- S t a t e ------------- | 2711   // ----------- S t a t e ------------- | 
| 2507   //  -- a2    : name | 2712   //  -- a2    : name | 
| 2508   //  -- ra    : return address | 2713   //  -- ra    : return address | 
| 2509   // ----------------------------------- | 2714   // ----------------------------------- | 
| 2510 | 2715 | 
| 2511   Label miss; | 2716   Label miss; | 
| 2512 | 2717 | 
| 2513   GenerateNameCheck(name, &miss); | 2718   GenerateNameCheck(Handle<String>(name), &miss); | 
| 2514 | 2719 | 
| 2515   // Get the number of arguments. | 2720   // Get the number of arguments. | 
| 2516   const int argc = arguments().immediate(); | 2721   const int argc = arguments().immediate(); | 
| 2517 | 2722 | 
| 2518   LookupResult lookup; | 2723   LookupResult lookup(isolate()); | 
| 2519   LookupPostInterceptor(holder, name, &lookup); | 2724   LookupPostInterceptor(holder, name, &lookup); | 
| 2520 | 2725 | 
| 2521   // Get the receiver from the stack. | 2726   // Get the receiver from the stack. | 
| 2522   __ lw(a1, MemOperand(sp, argc * kPointerSize)); | 2727   __ lw(a1, MemOperand(sp, argc * kPointerSize)); | 
| 2523 | 2728 | 
| 2524   CallInterceptorCompiler compiler(this, arguments(), a2, extra_ic_state_); | 2729   CallInterceptorCompiler compiler(this, arguments(), a2, extra_state_); | 
| 2525   MaybeObject* result = compiler.Compile(masm(), | 2730   MaybeObject* result = compiler.Compile(masm(), | 
| 2526                                          object, | 2731                                          object, | 
| 2527                                          holder, | 2732                                          holder, | 
| 2528                                          name, | 2733                                          name, | 
| 2529                                          &lookup, | 2734                                          &lookup, | 
| 2530                                          a1, | 2735                                          a1, | 
| 2531                                          a3, | 2736                                          a3, | 
| 2532                                          t0, | 2737                                          t0, | 
| 2533                                          a0, | 2738                                          a0, | 
| 2534                                          &miss); | 2739                                          &miss); | 
| 2535   if (result->IsFailure()) { | 2740   if (result->IsFailure()) { | 
| 2536     return result; | 2741     return result; | 
| 2537   } | 2742   } | 
| 2538 | 2743 | 
| 2539   // Move returned value, the function to call, to a1. | 2744   // Move returned value, the function to call, to a1. | 
| 2540   __ mov(a1, v0); | 2745   __ mov(a1, v0); | 
| 2541   // Restore receiver. | 2746   // Restore receiver. | 
| 2542   __ lw(a0, MemOperand(sp, argc * kPointerSize)); | 2747   __ lw(a0, MemOperand(sp, argc * kPointerSize)); | 
| 2543 | 2748 | 
| 2544   GenerateCallFunction(masm(), object, arguments(), &miss, extra_ic_state_); | 2749   GenerateCallFunction(masm(), Handle<Object>(object), arguments(), &miss, | 
|  | 2750                        extra_state_); | 
| 2545 | 2751 | 
| 2546   // Handle call cache miss. | 2752   // Handle call cache miss. | 
| 2547   __ bind(&miss); | 2753   __ bind(&miss); | 
| 2548   MaybeObject* maybe_result = GenerateMissBranch(); | 2754   MaybeObject* maybe_result = TryGenerateMissBranch(); | 
| 2549   if (maybe_result->IsFailure()) return maybe_result; | 2755   if (maybe_result->IsFailure()) return maybe_result; | 
| 2550 | 2756 | 
| 2551   // Return the generated code. | 2757   // Return the generated code. | 
| 2552   return GetCode(INTERCEPTOR, name); | 2758   return TryGetCode(INTERCEPTOR, name); | 
| 2553 } | 2759 } | 
| 2554 | 2760 | 
| 2555 | 2761 | 
| 2556 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, | 2762 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, | 
| 2557                                                  GlobalObject* holder, | 2763                                                  GlobalObject* holder, | 
| 2558                                                  JSGlobalPropertyCell* cell, | 2764                                                  JSGlobalPropertyCell* cell, | 
| 2559                                                  JSFunction* function, | 2765                                                  JSFunction* function, | 
| 2560                                                  String* name) { | 2766                                                  String* name) { | 
| 2561   // ----------- S t a t e ------------- | 2767   // ----------- S t a t e ------------- | 
| 2562   //  -- a2    : name | 2768   //  -- a2    : name | 
| 2563   //  -- ra    : return address | 2769   //  -- ra    : return address | 
| 2564   // ----------------------------------- | 2770   // ----------------------------------- | 
| 2565 | 2771 | 
| 2566   if (HasCustomCallGenerator(function)) { | 2772   if (HasCustomCallGenerator(function)) { | 
| 2567     MaybeObject* maybe_result = CompileCustomCall( | 2773     MaybeObject* maybe_result = CompileCustomCall( | 
| 2568         object, holder, cell, function, name); | 2774         object, holder, cell, function, name); | 
| 2569     Object* result; | 2775     Object* result; | 
| 2570     if (!maybe_result->ToObject(&result)) return maybe_result; | 2776     if (!maybe_result->ToObject(&result)) return maybe_result; | 
| 2571     // Undefined means bail out to regular compiler. | 2777     // Undefined means bail out to regular compiler. | 
| 2572     if (!result->IsUndefined()) return result; | 2778     if (!result->IsUndefined()) return result; | 
| 2573   } | 2779   } | 
| 2574 | 2780 | 
| 2575   Label miss; | 2781   Label miss; | 
| 2576 | 2782 | 
| 2577   GenerateNameCheck(name, &miss); | 2783   GenerateNameCheck(Handle<String>(name), &miss); | 
| 2578 | 2784 | 
| 2579   // Get the number of arguments. | 2785   // Get the number of arguments. | 
| 2580   const int argc = arguments().immediate(); | 2786   const int argc = arguments().immediate(); | 
| 2581 | 2787 | 
| 2582   GenerateGlobalReceiverCheck(object, holder, name, &miss); | 2788   GenerateGlobalReceiverCheck(object, holder, name, &miss); | 
| 2583   GenerateLoadFunctionFromCell(cell, function, &miss); | 2789   GenerateLoadFunctionFromCell(cell, function, &miss); | 
| 2584 | 2790 | 
| 2585   // Patch the receiver on the stack with the global proxy if | 2791   // Patch the receiver on the stack with the global proxy if | 
| 2586   // necessary. | 2792   // necessary. | 
| 2587   if (object->IsGlobalObject()) { | 2793   if (object->IsGlobalObject()) { | 
| 2588     __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset)); | 2794     __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset)); | 
| 2589     __ sw(a3, MemOperand(sp, argc * kPointerSize)); | 2795     __ sw(a3, MemOperand(sp, argc * kPointerSize)); | 
| 2590   } | 2796   } | 
| 2591 | 2797 | 
| 2592   // Setup the context (function already in r1). | 2798   // Setup the context (function already in r1). | 
| 2593   __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 2799   __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 
| 2594 | 2800 | 
| 2595   // Jump to the cached code (tail call). | 2801   // Jump to the cached code (tail call). | 
| 2596   Counters* counters = masm()->isolate()->counters(); | 2802   Counters* counters = masm()->isolate()->counters(); | 
| 2597   __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); | 2803   __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); | 
| 2598   ASSERT(function->is_compiled()); |  | 
| 2599   Handle<Code> code(function->code()); | 2804   Handle<Code> code(function->code()); | 
| 2600   ParameterCount expected(function->shared()->formal_parameter_count()); | 2805   ParameterCount expected(function->shared()->formal_parameter_count()); | 
| 2601   CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 2806   CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 
| 2602       ? CALL_AS_FUNCTION | 2807       ? CALL_AS_FUNCTION | 
| 2603       : CALL_AS_METHOD; | 2808       : CALL_AS_METHOD; | 
| 2604   if (V8::UseCrankshaft()) { | 2809   // We call indirectly through the code field in the function to | 
| 2605     // TODO(kasperl): For now, we always call indirectly through the | 2810   // allow recompilation to take effect without changing any of the | 
| 2606     // code field in the function to allow recompilation to take effect | 2811   // call sites. | 
| 2607     // without changing any of the call sites. | 2812   __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 
| 2608     __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 2813   __ InvokeCode(a3, expected, arguments(), JUMP_FUNCTION, | 
| 2609     __ InvokeCode(a3, expected, arguments(), JUMP_FUNCTION, | 2814                 NullCallWrapper(), call_kind); | 
| 2610                   NullCallWrapper(), call_kind); |  | 
| 2611   } else { |  | 
| 2612     __ InvokeCode(code, expected, arguments(), RelocInfo::CODE_TARGET, |  | 
| 2613                   JUMP_FUNCTION, call_kind); |  | 
| 2614   } |  | 
| 2615 | 2815 | 
| 2616   // Handle call cache miss. | 2816   // Handle call cache miss. | 
| 2617   __ bind(&miss); | 2817   __ bind(&miss); | 
| 2618   __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3); | 2818   __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3); | 
| 2619   MaybeObject* maybe_result = GenerateMissBranch(); | 2819   MaybeObject* maybe_result = TryGenerateMissBranch(); | 
| 2620   if (maybe_result->IsFailure()) return maybe_result; | 2820   if (maybe_result->IsFailure()) return maybe_result; | 
| 2621 | 2821 | 
| 2622   // Return the generated code. | 2822   // Return the generated code. | 
| 2623   return GetCode(NORMAL, name); | 2823   return TryGetCode(NORMAL, name); | 
| 2624 } | 2824 } | 
| 2625 | 2825 | 
| 2626 | 2826 | 
| 2627 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, | 2827 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, | 
| 2628                                                   int index, | 2828                                                   int index, | 
| 2629                                                   Map* transition, | 2829                                                   Map* transition, | 
| 2630                                                   String* name) { | 2830                                                   String* name) { | 
| 2631   // ----------- S t a t e ------------- | 2831   // ----------- S t a t e ------------- | 
| 2632   //  -- a0    : value | 2832   //  -- a0    : value | 
| 2633   //  -- a1    : receiver | 2833   //  -- a1    : receiver | 
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2792   __ bind(&miss); | 2992   __ bind(&miss); | 
| 2793   __ IncrementCounter(counters->named_store_global_inline_miss(), 1, a1, a3); | 2993   __ IncrementCounter(counters->named_store_global_inline_miss(), 1, a1, a3); | 
| 2794   Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); | 2994   Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); | 
| 2795   __ Jump(ic, RelocInfo::CODE_TARGET); | 2995   __ Jump(ic, RelocInfo::CODE_TARGET); | 
| 2796 | 2996 | 
| 2797   // Return the generated code. | 2997   // Return the generated code. | 
| 2798   return GetCode(NORMAL, name); | 2998   return GetCode(NORMAL, name); | 
| 2799 } | 2999 } | 
| 2800 | 3000 | 
| 2801 | 3001 | 
| 2802 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, | 3002 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<String> name, | 
| 2803                                                       JSObject* object, | 3003                                                       Handle<JSObject> object, | 
| 2804                                                       JSObject* last) { | 3004                                                       Handle<JSObject> last) { | 
| 2805   // ----------- S t a t e ------------- | 3005   // ----------- S t a t e ------------- | 
| 2806   //  -- a0    : receiver | 3006   //  -- a0    : receiver | 
| 2807   //  -- ra    : return address | 3007   //  -- ra    : return address | 
| 2808   // ----------------------------------- | 3008   // ----------------------------------- | 
| 2809   Label miss; | 3009   Label miss; | 
| 2810 | 3010 | 
| 2811   // Check that the receiver is not a smi. | 3011   // Check that the receiver is not a smi. | 
| 2812   __ JumpIfSmi(a0, &miss); | 3012   __ JumpIfSmi(a0, &miss); | 
| 2813 | 3013 | 
| 2814   // Check the maps of the full prototype chain. | 3014   // Check the maps of the full prototype chain. | 
| 2815   CheckPrototypes(object, a0, last, a3, a1, t0, name, &miss); | 3015   CheckPrototypes(object, a0, last, a3, a1, t0, name, &miss); | 
| 2816 | 3016 | 
| 2817   // If the last object in the prototype chain is a global object, | 3017   // If the last object in the prototype chain is a global object, | 
| 2818   // check that the global property cell is empty. | 3018   // check that the global property cell is empty. | 
| 2819   if (last->IsGlobalObject()) { | 3019   if (last->IsGlobalObject()) { | 
| 2820     MaybeObject* cell = GenerateCheckPropertyCell(masm(), | 3020     GenerateCheckPropertyCell( | 
| 2821                                                   GlobalObject::cast(last), | 3021         masm(), Handle<GlobalObject>::cast(last), name, a1, &miss); | 
| 2822                                                   name, |  | 
| 2823                                                   a1, |  | 
| 2824                                                   &miss); |  | 
| 2825     if (cell->IsFailure()) { |  | 
| 2826       miss.Unuse(); |  | 
| 2827       return cell; |  | 
| 2828     } |  | 
| 2829   } | 3022   } | 
| 2830 | 3023 | 
| 2831   // Return undefined if maps of the full prototype chain is still the same. | 3024   // Return undefined if maps of the full prototype chain is still the same. | 
| 2832   __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); | 3025   __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); | 
| 2833   __ Ret(); | 3026   __ Ret(); | 
| 2834 | 3027 | 
| 2835   __ bind(&miss); | 3028   __ bind(&miss); | 
| 2836   GenerateLoadMiss(masm(), Code::LOAD_IC); | 3029   GenerateLoadMiss(masm(), Code::LOAD_IC); | 
| 2837 | 3030 | 
| 2838   // Return the generated code. | 3031   // Return the generated code. | 
| 2839   return GetCode(NONEXISTENT, heap()->empty_string()); | 3032   return GetCode(NONEXISTENT, factory()->empty_string()); | 
| 2840 } | 3033 } | 
| 2841 | 3034 | 
| 2842 | 3035 | 
| 2843 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object, | 3036 Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object, | 
| 2844                                                 JSObject* holder, | 3037                                                 Handle<JSObject> holder, | 
| 2845                                                 int index, | 3038                                                 int index, | 
| 2846                                                 String* name) { | 3039                                                 Handle<String> name) { | 
| 2847   // ----------- S t a t e ------------- | 3040   // ----------- S t a t e ------------- | 
| 2848   //  -- a0    : receiver | 3041   //  -- a0    : receiver | 
| 2849   //  -- a2    : name | 3042   //  -- a2    : name | 
| 2850   //  -- ra    : return address | 3043   //  -- ra    : return address | 
| 2851   // ----------------------------------- | 3044   // ----------------------------------- | 
| 2852   Label miss; | 3045   Label miss; | 
| 2853 | 3046 | 
| 2854   __ mov(v0, a0); | 3047   __ mov(v0, a0); | 
| 2855 | 3048 | 
| 2856   GenerateLoadField(object, holder, v0, a3, a1, t0, index, name, &miss); | 3049   GenerateLoadField(object, holder, v0, a3, a1, t0, index, name, &miss); | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 2877                                              callback, name, &miss); | 3070                                              callback, name, &miss); | 
| 2878   if (result->IsFailure()) { | 3071   if (result->IsFailure()) { | 
| 2879     miss.Unuse(); | 3072     miss.Unuse(); | 
| 2880     return result; | 3073     return result; | 
| 2881   } | 3074   } | 
| 2882 | 3075 | 
| 2883   __ bind(&miss); | 3076   __ bind(&miss); | 
| 2884   GenerateLoadMiss(masm(), Code::LOAD_IC); | 3077   GenerateLoadMiss(masm(), Code::LOAD_IC); | 
| 2885 | 3078 | 
| 2886   // Return the generated code. | 3079   // Return the generated code. | 
| 2887   return GetCode(CALLBACKS, name); | 3080   return TryGetCode(CALLBACKS, name); | 
| 2888 } | 3081 } | 
| 2889 | 3082 | 
| 2890 | 3083 | 
| 2891 MaybeObject* LoadStubCompiler::CompileLoadConstant(JSObject* object, | 3084 Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object, | 
| 2892                                                    JSObject* holder, | 3085                                                    Handle<JSObject> holder, | 
| 2893                                                    Object* value, | 3086                                                    Handle<Object> value, | 
| 2894                                                    String* name) { | 3087                                                    Handle<String> name) { | 
| 2895   // ----------- S t a t e ------------- | 3088   // ----------- S t a t e ------------- | 
| 2896   //  -- a0    : receiver | 3089   //  -- a0    : receiver | 
| 2897   //  -- a2    : name | 3090   //  -- a2    : name | 
| 2898   //  -- ra    : return address | 3091   //  -- ra    : return address | 
| 2899   // ----------------------------------- | 3092   // ----------------------------------- | 
| 2900   Label miss; | 3093   Label miss; | 
| 2901 | 3094 | 
| 2902   GenerateLoadConstant(object, holder, a0, a3, a1, t0, value, name, &miss); | 3095   GenerateLoadConstant(object, holder, a0, a3, a1, t0, value, name, &miss); | 
| 2903   __ bind(&miss); | 3096   __ bind(&miss); | 
| 2904   GenerateLoadMiss(masm(), Code::LOAD_IC); | 3097   GenerateLoadMiss(masm(), Code::LOAD_IC); | 
| 2905 | 3098 | 
| 2906   // Return the generated code. | 3099   // Return the generated code. | 
| 2907   return GetCode(CONSTANT_FUNCTION, name); | 3100   return GetCode(CONSTANT_FUNCTION, name); | 
| 2908 } | 3101 } | 
| 2909 | 3102 | 
| 2910 | 3103 | 
| 2911 MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* object, | 3104 MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* object, | 
| 2912                                                       JSObject* holder, | 3105                                                       JSObject* holder, | 
| 2913                                                       String* name) { | 3106                                                       String* name) { | 
| 2914   // ----------- S t a t e ------------- | 3107   // ----------- S t a t e ------------- | 
| 2915   //  -- a0    : receiver | 3108   //  -- a0    : receiver | 
| 2916   //  -- a2    : name | 3109   //  -- a2    : name | 
| 2917   //  -- ra    : return address | 3110   //  -- ra    : return address | 
| 2918   //  -- [sp]  : receiver | 3111   //  -- [sp]  : receiver | 
| 2919   // ----------------------------------- | 3112   // ----------------------------------- | 
| 2920   Label miss; | 3113   Label miss; | 
| 2921 | 3114 | 
| 2922   LookupResult lookup; | 3115   LookupResult lookup(isolate()); | 
| 2923   LookupPostInterceptor(holder, name, &lookup); | 3116   LookupPostInterceptor(holder, name, &lookup); | 
| 2924   GenerateLoadInterceptor(object, | 3117   GenerateLoadInterceptor(object, | 
| 2925                           holder, | 3118                           holder, | 
| 2926                           &lookup, | 3119                           &lookup, | 
| 2927                           a0, | 3120                           a0, | 
| 2928                           a2, | 3121                           a2, | 
| 2929                           a3, | 3122                           a3, | 
| 2930                           a1, | 3123                           a1, | 
| 2931                           t0, | 3124                           t0, | 
| 2932                           name, | 3125                           name, | 
| 2933                           &miss); | 3126                           &miss); | 
| 2934   __ bind(&miss); | 3127   __ bind(&miss); | 
| 2935   GenerateLoadMiss(masm(), Code::LOAD_IC); | 3128   GenerateLoadMiss(masm(), Code::LOAD_IC); | 
| 2936 | 3129 | 
| 2937   // Return the generated code. | 3130   // Return the generated code. | 
| 2938   return GetCode(INTERCEPTOR, name); | 3131   return TryGetCode(INTERCEPTOR, name); | 
| 2939 } | 3132 } | 
| 2940 | 3133 | 
| 2941 | 3134 | 
| 2942 MaybeObject* LoadStubCompiler::CompileLoadGlobal(JSObject* object, | 3135 MaybeObject* LoadStubCompiler::CompileLoadGlobal(JSObject* object, | 
| 2943                                                  GlobalObject* holder, | 3136                                                  GlobalObject* holder, | 
| 2944                                                  JSGlobalPropertyCell* cell, | 3137                                                  JSGlobalPropertyCell* cell, | 
| 2945                                                  String* name, | 3138                                                  String* name, | 
| 2946                                                  bool is_dont_delete) { | 3139                                                  bool is_dont_delete) { | 
| 2947   // ----------- S t a t e ------------- | 3140   // ----------- S t a t e ------------- | 
| 2948   //  -- a0    : receiver | 3141   //  -- a0    : receiver | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
| 2975   __ mov(v0, t0); | 3168   __ mov(v0, t0); | 
| 2976   Counters* counters = masm()->isolate()->counters(); | 3169   Counters* counters = masm()->isolate()->counters(); | 
| 2977   __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); | 3170   __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); | 
| 2978   __ Ret(); | 3171   __ Ret(); | 
| 2979 | 3172 | 
| 2980   __ bind(&miss); | 3173   __ bind(&miss); | 
| 2981   __ IncrementCounter(counters->named_load_global_stub_miss(), 1, a1, a3); | 3174   __ IncrementCounter(counters->named_load_global_stub_miss(), 1, a1, a3); | 
| 2982   GenerateLoadMiss(masm(), Code::LOAD_IC); | 3175   GenerateLoadMiss(masm(), Code::LOAD_IC); | 
| 2983 | 3176 | 
| 2984   // Return the generated code. | 3177   // Return the generated code. | 
| 2985   return GetCode(NORMAL, name); | 3178   return TryGetCode(NORMAL, name); | 
| 2986 } | 3179 } | 
| 2987 | 3180 | 
| 2988 | 3181 | 
| 2989 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, | 3182 Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name, | 
| 2990                                                      JSObject* receiver, | 3183                                                      Handle<JSObject> receiver, | 
| 2991                                                      JSObject* holder, | 3184                                                      Handle<JSObject> holder, | 
| 2992                                                      int index) { | 3185                                                      int index) { | 
| 2993   // ----------- S t a t e ------------- | 3186   // ----------- S t a t e ------------- | 
| 2994   //  -- ra    : return address | 3187   //  -- ra    : return address | 
| 2995   //  -- a0    : key | 3188   //  -- a0    : key | 
| 2996   //  -- a1    : receiver | 3189   //  -- a1    : receiver | 
| 2997   // ----------------------------------- | 3190   // ----------------------------------- | 
| 2998   Label miss; | 3191   Label miss; | 
| 2999 | 3192 | 
| 3000   // Check the key is the cached one. | 3193   // Check the key is the cached one. | 
| 3001   __ Branch(&miss, ne, a0, Operand(Handle<String>(name))); | 3194   __ Branch(&miss, ne, a0, Operand(name)); | 
| 3002 | 3195 | 
| 3003   GenerateLoadField(receiver, holder, a1, a2, a3, t0, index, name, &miss); | 3196   GenerateLoadField(receiver, holder, a1, a2, a3, t0, index, name, &miss); | 
| 3004   __ bind(&miss); | 3197   __ bind(&miss); | 
| 3005   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3198   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| 3006 | 3199 | 
| 3007   return GetCode(FIELD, name); | 3200   return GetCode(FIELD, name); | 
| 3008 } | 3201 } | 
| 3009 | 3202 | 
| 3010 | 3203 | 
| 3011 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback( | 3204 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback( | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 3026   MaybeObject* result = GenerateLoadCallback(receiver, holder, a1, a0, a2, a3, | 3219   MaybeObject* result = GenerateLoadCallback(receiver, holder, a1, a0, a2, a3, | 
| 3027                                              t0, callback, name, &miss); | 3220                                              t0, callback, name, &miss); | 
| 3028   if (result->IsFailure()) { | 3221   if (result->IsFailure()) { | 
| 3029     miss.Unuse(); | 3222     miss.Unuse(); | 
| 3030     return result; | 3223     return result; | 
| 3031   } | 3224   } | 
| 3032 | 3225 | 
| 3033   __ bind(&miss); | 3226   __ bind(&miss); | 
| 3034   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3227   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| 3035 | 3228 | 
| 3036   return GetCode(CALLBACKS, name); | 3229   return TryGetCode(CALLBACKS, name); | 
| 3037 } | 3230 } | 
| 3038 | 3231 | 
| 3039 | 3232 | 
| 3040 MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name, | 3233 Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant( | 
| 3041                                                         JSObject* receiver, | 3234     Handle<String> name, | 
| 3042                                                         JSObject* holder, | 3235     Handle<JSObject> receiver, | 
| 3043                                                         Object* value) { | 3236     Handle<JSObject> holder, | 
|  | 3237     Handle<Object> value) { | 
| 3044   // ----------- S t a t e ------------- | 3238   // ----------- S t a t e ------------- | 
| 3045   //  -- ra    : return address | 3239   //  -- ra    : return address | 
| 3046   //  -- a0    : key | 3240   //  -- a0    : key | 
| 3047   //  -- a1    : receiver | 3241   //  -- a1    : receiver | 
| 3048   // ----------------------------------- | 3242   // ----------------------------------- | 
| 3049   Label miss; | 3243   Label miss; | 
| 3050 | 3244 | 
| 3051   // Check the key is the cached one. | 3245   // Check the key is the cached one. | 
| 3052   __ Branch(&miss, ne, a0, Operand(Handle<String>(name))); | 3246   __ Branch(&miss, ne, a0, Operand(name)); | 
| 3053 | 3247 | 
| 3054   GenerateLoadConstant(receiver, holder, a1, a2, a3, t0, value, name, &miss); | 3248   GenerateLoadConstant(receiver, holder, a1, a2, a3, t0, value, name, &miss); | 
| 3055   __ bind(&miss); | 3249   __ bind(&miss); | 
| 3056   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3250   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| 3057 | 3251 | 
| 3058   // Return the generated code. | 3252   // Return the generated code. | 
| 3059   return GetCode(CONSTANT_FUNCTION, name); | 3253   return GetCode(CONSTANT_FUNCTION, name); | 
| 3060 } | 3254 } | 
| 3061 | 3255 | 
| 3062 | 3256 | 
| 3063 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 3257 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 
| 3064                                                            JSObject* holder, | 3258                                                            JSObject* holder, | 
| 3065                                                            String* name) { | 3259                                                            String* name) { | 
| 3066   // ----------- S t a t e ------------- | 3260   // ----------- S t a t e ------------- | 
| 3067   //  -- ra    : return address | 3261   //  -- ra    : return address | 
| 3068   //  -- a0    : key | 3262   //  -- a0    : key | 
| 3069   //  -- a1    : receiver | 3263   //  -- a1    : receiver | 
| 3070   // ----------------------------------- | 3264   // ----------------------------------- | 
| 3071   Label miss; | 3265   Label miss; | 
| 3072 | 3266 | 
| 3073   // Check the key is the cached one. | 3267   // Check the key is the cached one. | 
| 3074   __ Branch(&miss, ne, a0, Operand(Handle<String>(name))); | 3268   __ Branch(&miss, ne, a0, Operand(Handle<String>(name))); | 
| 3075 | 3269 | 
| 3076   LookupResult lookup; | 3270   LookupResult lookup(isolate()); | 
| 3077   LookupPostInterceptor(holder, name, &lookup); | 3271   LookupPostInterceptor(holder, name, &lookup); | 
| 3078   GenerateLoadInterceptor(receiver, | 3272   GenerateLoadInterceptor(receiver, | 
| 3079                           holder, | 3273                           holder, | 
| 3080                           &lookup, | 3274                           &lookup, | 
| 3081                           a1, | 3275                           a1, | 
| 3082                           a0, | 3276                           a0, | 
| 3083                           a2, | 3277                           a2, | 
| 3084                           a3, | 3278                           a3, | 
| 3085                           t0, | 3279                           t0, | 
| 3086                           name, | 3280                           name, | 
| 3087                           &miss); | 3281                           &miss); | 
| 3088   __ bind(&miss); | 3282   __ bind(&miss); | 
| 3089   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3283   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| 3090 | 3284 | 
| 3091   return GetCode(INTERCEPTOR, name); | 3285   return TryGetCode(INTERCEPTOR, name); | 
| 3092 } | 3286 } | 
| 3093 | 3287 | 
| 3094 | 3288 | 
| 3095 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { | 3289 Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength( | 
|  | 3290     Handle<String> name) { | 
| 3096   // ----------- S t a t e ------------- | 3291   // ----------- S t a t e ------------- | 
| 3097   //  -- ra    : return address | 3292   //  -- ra    : return address | 
| 3098   //  -- a0    : key | 3293   //  -- a0    : key | 
| 3099   //  -- a1    : receiver | 3294   //  -- a1    : receiver | 
| 3100   // ----------------------------------- | 3295   // ----------------------------------- | 
| 3101   Label miss; | 3296   Label miss; | 
| 3102 | 3297 | 
| 3103   // Check the key is the cached one. | 3298   // Check the key is the cached one. | 
| 3104   __ Branch(&miss, ne, a0, Operand(Handle<String>(name))); | 3299   __ Branch(&miss, ne, a0, Operand(name)); | 
| 3105 | 3300 | 
| 3106   GenerateLoadArrayLength(masm(), a1, a2, &miss); | 3301   GenerateLoadArrayLength(masm(), a1, a2, &miss); | 
| 3107   __ bind(&miss); | 3302   __ bind(&miss); | 
| 3108   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3303   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| 3109 | 3304 | 
| 3110   return GetCode(CALLBACKS, name); | 3305   return GetCode(CALLBACKS, name); | 
| 3111 } | 3306 } | 
| 3112 | 3307 | 
| 3113 | 3308 | 
| 3114 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { | 3309 Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength( | 
|  | 3310     Handle<String> name) { | 
| 3115   // ----------- S t a t e ------------- | 3311   // ----------- S t a t e ------------- | 
| 3116   //  -- ra    : return address | 3312   //  -- ra    : return address | 
| 3117   //  -- a0    : key | 3313   //  -- a0    : key | 
| 3118   //  -- a1    : receiver | 3314   //  -- a1    : receiver | 
| 3119   // ----------------------------------- | 3315   // ----------------------------------- | 
| 3120   Label miss; | 3316   Label miss; | 
| 3121 | 3317 | 
| 3122   Counters* counters = masm()->isolate()->counters(); | 3318   Counters* counters = masm()->isolate()->counters(); | 
| 3123   __ IncrementCounter(counters->keyed_load_string_length(), 1, a2, a3); | 3319   __ IncrementCounter(counters->keyed_load_string_length(), 1, a2, a3); | 
| 3124 | 3320 | 
| 3125   // Check the key is the cached one. | 3321   // Check the key is the cached one. | 
| 3126   __ Branch(&miss, ne, a0, Operand(Handle<String>(name))); | 3322   __ Branch(&miss, ne, a0, Operand(name)); | 
| 3127 | 3323 | 
| 3128   GenerateLoadStringLength(masm(), a1, a2, a3, &miss, true); | 3324   GenerateLoadStringLength(masm(), a1, a2, a3, &miss, true); | 
| 3129   __ bind(&miss); | 3325   __ bind(&miss); | 
| 3130   __ DecrementCounter(counters->keyed_load_string_length(), 1, a2, a3); | 3326   __ DecrementCounter(counters->keyed_load_string_length(), 1, a2, a3); | 
| 3131 | 3327 | 
| 3132   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3328   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| 3133 | 3329 | 
| 3134   return GetCode(CALLBACKS, name); | 3330   return GetCode(CALLBACKS, name); | 
| 3135 } | 3331 } | 
| 3136 | 3332 | 
| 3137 | 3333 | 
| 3138 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { | 3334 Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype( | 
|  | 3335     Handle<String> name) { | 
| 3139   // ----------- S t a t e ------------- | 3336   // ----------- S t a t e ------------- | 
| 3140   //  -- ra    : return address | 3337   //  -- ra    : return address | 
| 3141   //  -- a0    : key | 3338   //  -- a0    : key | 
| 3142   //  -- a1    : receiver | 3339   //  -- a1    : receiver | 
| 3143   // ----------------------------------- | 3340   // ----------------------------------- | 
| 3144   Label miss; | 3341   Label miss; | 
| 3145 | 3342 | 
| 3146   Counters* counters = masm()->isolate()->counters(); | 3343   Counters* counters = masm()->isolate()->counters(); | 
| 3147   __ IncrementCounter(counters->keyed_load_function_prototype(), 1, a2, a3); | 3344   __ IncrementCounter(counters->keyed_load_function_prototype(), 1, a2, a3); | 
| 3148 | 3345 | 
| 3149   // Check the name hasn't changed. | 3346   // Check the name hasn't changed. | 
| 3150   __ Branch(&miss, ne, a0, Operand(Handle<String>(name))); | 3347   __ Branch(&miss, ne, a0, Operand(name)); | 
| 3151 | 3348 | 
| 3152   GenerateLoadFunctionPrototype(masm(), a1, a2, a3, &miss); | 3349   GenerateLoadFunctionPrototype(masm(), a1, a2, a3, &miss); | 
| 3153   __ bind(&miss); | 3350   __ bind(&miss); | 
| 3154   __ DecrementCounter(counters->keyed_load_function_prototype(), 1, a2, a3); | 3351   __ DecrementCounter(counters->keyed_load_function_prototype(), 1, a2, a3); | 
| 3155   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3352   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| 3156 | 3353 | 
| 3157   return GetCode(CALLBACKS, name); | 3354   return GetCode(CALLBACKS, name); | 
| 3158 } | 3355 } | 
| 3159 | 3356 | 
| 3160 | 3357 | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 3171   __ DispatchMap(a1, | 3368   __ DispatchMap(a1, | 
| 3172                  a2, | 3369                  a2, | 
| 3173                  Handle<Map>(receiver_map), | 3370                  Handle<Map>(receiver_map), | 
| 3174                  Handle<Code>(stub), | 3371                  Handle<Code>(stub), | 
| 3175                  DO_SMI_CHECK); | 3372                  DO_SMI_CHECK); | 
| 3176 | 3373 | 
| 3177   Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); | 3374   Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); | 
| 3178   __ Jump(ic, RelocInfo::CODE_TARGET); | 3375   __ Jump(ic, RelocInfo::CODE_TARGET); | 
| 3179 | 3376 | 
| 3180   // Return the generated code. | 3377   // Return the generated code. | 
| 3181   return GetCode(NORMAL, NULL); | 3378   return TryGetCode(NORMAL, NULL); | 
| 3182 } | 3379 } | 
| 3183 | 3380 | 
| 3184 | 3381 | 
| 3185 MaybeObject* KeyedLoadStubCompiler::CompileLoadPolymorphic( | 3382 MaybeObject* KeyedLoadStubCompiler::CompileLoadPolymorphic( | 
| 3186     MapList* receiver_maps, | 3383     MapList* receiver_maps, | 
| 3187     CodeList* handler_ics) { | 3384     CodeList* handler_ics) { | 
| 3188   // ----------- S t a t e ------------- | 3385   // ----------- S t a t e ------------- | 
| 3189   //  -- ra    : return address | 3386   //  -- ra    : return address | 
| 3190   //  -- a0    : key | 3387   //  -- a0    : key | 
| 3191   //  -- a1    : receiver | 3388   //  -- a1    : receiver | 
| 3192   // ----------------------------------- | 3389   // ----------------------------------- | 
| 3193   Label miss; | 3390   Label miss; | 
| 3194   __ JumpIfSmi(a1, &miss); | 3391   __ JumpIfSmi(a1, &miss); | 
| 3195 | 3392 | 
| 3196   int receiver_count = receiver_maps->length(); | 3393   int receiver_count = receiver_maps->length(); | 
| 3197   __ lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset)); | 3394   __ lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset)); | 
| 3198   for (int current = 0; current < receiver_count; ++current) { | 3395   for (int current = 0; current < receiver_count; ++current) { | 
| 3199     Handle<Map> map(receiver_maps->at(current)); | 3396     Handle<Map> map(receiver_maps->at(current)); | 
| 3200     Handle<Code> code(handler_ics->at(current)); | 3397     Handle<Code> code(handler_ics->at(current)); | 
| 3201     __ Jump(code, RelocInfo::CODE_TARGET, eq, a2, Operand(map)); | 3398     __ Jump(code, RelocInfo::CODE_TARGET, eq, a2, Operand(map)); | 
| 3202   } | 3399   } | 
| 3203 | 3400 | 
| 3204   __ bind(&miss); | 3401   __ bind(&miss); | 
| 3205   Handle<Code> miss_ic = isolate()->builtins()->KeyedLoadIC_Miss(); | 3402   Handle<Code> miss_ic = isolate()->builtins()->KeyedLoadIC_Miss(); | 
| 3206   __ Jump(miss_ic, RelocInfo::CODE_TARGET); | 3403   __ Jump(miss_ic, RelocInfo::CODE_TARGET); | 
| 3207 | 3404 | 
| 3208   // Return the generated code. | 3405   // Return the generated code. | 
| 3209   return GetCode(NORMAL, NULL, MEGAMORPHIC); | 3406   return TryGetCode(NORMAL, NULL, MEGAMORPHIC); | 
| 3210 } | 3407 } | 
| 3211 | 3408 | 
| 3212 | 3409 | 
| 3213 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, | 3410 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, | 
| 3214                                                        int index, | 3411                                                        int index, | 
| 3215                                                        Map* transition, | 3412                                                        Map* transition, | 
| 3216                                                        String* name) { | 3413                                                        String* name) { | 
| 3217   // ----------- S t a t e ------------- | 3414   // ----------- S t a t e ------------- | 
| 3218   //  -- a0    : value | 3415   //  -- a0    : value | 
| 3219   //  -- a1    : key | 3416   //  -- a1    : key | 
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3292 | 3489 | 
| 3293   int receiver_count = receiver_maps->length(); | 3490   int receiver_count = receiver_maps->length(); | 
| 3294   __ lw(a3, FieldMemOperand(a2, HeapObject::kMapOffset)); | 3491   __ lw(a3, FieldMemOperand(a2, HeapObject::kMapOffset)); | 
| 3295   for (int i = 0; i < receiver_count; ++i) { | 3492   for (int i = 0; i < receiver_count; ++i) { | 
| 3296     Handle<Map> map(receiver_maps->at(i)); | 3493     Handle<Map> map(receiver_maps->at(i)); | 
| 3297     Handle<Code> code(handler_stubs->at(i)); | 3494     Handle<Code> code(handler_stubs->at(i)); | 
| 3298     if (transitioned_maps->at(i) == NULL) { | 3495     if (transitioned_maps->at(i) == NULL) { | 
| 3299       __ Jump(code, RelocInfo::CODE_TARGET, eq, a3, Operand(map)); | 3496       __ Jump(code, RelocInfo::CODE_TARGET, eq, a3, Operand(map)); | 
| 3300     } else { | 3497     } else { | 
| 3301       Label next_map; | 3498       Label next_map; | 
| 3302       __ Branch(&next_map, eq, a3, Operand(map)); | 3499       __ Branch(&next_map, ne, a3, Operand(map)); | 
| 3303       __ li(t0, Operand(Handle<Map>(transitioned_maps->at(i)))); | 3500       __ li(a3, Operand(Handle<Map>(transitioned_maps->at(i)))); | 
| 3304       __ Jump(code, RelocInfo::CODE_TARGET); | 3501       __ Jump(code, RelocInfo::CODE_TARGET); | 
| 3305       __ bind(&next_map); | 3502       __ bind(&next_map); | 
| 3306     } | 3503     } | 
| 3307   } | 3504   } | 
| 3308 | 3505 | 
| 3309   __ bind(&miss); | 3506   __ bind(&miss); | 
| 3310   Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 3507   Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 
| 3311   __ Jump(miss_ic, RelocInfo::CODE_TARGET); | 3508   __ Jump(miss_ic, RelocInfo::CODE_TARGET); | 
| 3312 | 3509 | 
| 3313   // Return the generated code. | 3510   // Return the generated code. | 
| (...skipping 1216 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4530   Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 4727   Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 
| 4531   __ Jump(ic_miss, RelocInfo::CODE_TARGET); | 4728   __ Jump(ic_miss, RelocInfo::CODE_TARGET); | 
| 4532 } | 4729 } | 
| 4533 | 4730 | 
| 4534 | 4731 | 
| 4535 #undef __ | 4732 #undef __ | 
| 4536 | 4733 | 
| 4537 } }  // namespace v8::internal | 4734 } }  // namespace v8::internal | 
| 4538 | 4735 | 
| 4539 #endif  // V8_TARGET_ARCH_MIPS | 4736 #endif  // V8_TARGET_ARCH_MIPS | 
| OLD | NEW | 
|---|