| 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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 100     __ pop(offset); | 100     __ pop(offset); | 
| 101   } | 101   } | 
| 102 } | 102 } | 
| 103 | 103 | 
| 104 | 104 | 
| 105 // Helper function used to check that the dictionary doesn't contain | 105 // Helper function used to check that the dictionary doesn't contain | 
| 106 // the property. This function may return false negatives, so miss_label | 106 // the property. This function may return false negatives, so miss_label | 
| 107 // must always call a backup property check that is complete. | 107 // must always call a backup property check that is complete. | 
| 108 // This function is safe to call if the receiver has fast properties. | 108 // This function is safe to call if the receiver has fast properties. | 
| 109 // Name must be a symbol and receiver must be a heap object. | 109 // Name must be a symbol and receiver must be a heap object. | 
| 110 static MaybeObject* GenerateDictionaryNegativeLookup(MacroAssembler* masm, | 110 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, | 
| 111                                                      Label* miss_label, | 111                                              Label* miss_label, | 
| 112                                                      Register receiver, | 112                                              Register receiver, | 
| 113                                                      String* name, | 113                                              Handle<String> name, | 
| 114                                                      Register r0, | 114                                              Register r0, | 
| 115                                                      Register r1) { | 115                                              Register r1) { | 
| 116   ASSERT(name->IsSymbol()); | 116   ASSERT(name->IsSymbol()); | 
| 117   Counters* counters = masm->isolate()->counters(); | 117   Counters* counters = masm->isolate()->counters(); | 
| 118   __ IncrementCounter(counters->negative_lookups(), 1); | 118   __ IncrementCounter(counters->negative_lookups(), 1); | 
| 119   __ IncrementCounter(counters->negative_lookups_miss(), 1); | 119   __ IncrementCounter(counters->negative_lookups_miss(), 1); | 
| 120 | 120 | 
| 121   __ mov(r0, FieldOperand(receiver, HeapObject::kMapOffset)); | 121   __ mov(r0, FieldOperand(receiver, HeapObject::kMapOffset)); | 
| 122 | 122 | 
| 123   const int kInterceptorOrAccessCheckNeededMask = | 123   const int kInterceptorOrAccessCheckNeededMask = | 
| 124       (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 124       (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 
| 125 | 125 | 
| 126   // Bail out if the receiver has a named interceptor or requires access checks. | 126   // Bail out if the receiver has a named interceptor or requires access checks. | 
| 127   __ test_b(FieldOperand(r0, Map::kBitFieldOffset), | 127   __ test_b(FieldOperand(r0, Map::kBitFieldOffset), | 
| 128             kInterceptorOrAccessCheckNeededMask); | 128             kInterceptorOrAccessCheckNeededMask); | 
| 129   __ j(not_zero, miss_label); | 129   __ j(not_zero, miss_label); | 
| 130 | 130 | 
| 131   // Check that receiver is a JSObject. | 131   // Check that receiver is a JSObject. | 
| 132   __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE); | 132   __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE); | 
| 133   __ j(below, miss_label); | 133   __ j(below, miss_label); | 
| 134 | 134 | 
| 135   // Load properties array. | 135   // Load properties array. | 
| 136   Register properties = r0; | 136   Register properties = r0; | 
| 137   __ mov(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 137   __ mov(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 
| 138 | 138 | 
| 139   // Check that the properties array is a dictionary. | 139   // Check that the properties array is a dictionary. | 
| 140   __ cmp(FieldOperand(properties, HeapObject::kMapOffset), | 140   __ cmp(FieldOperand(properties, HeapObject::kMapOffset), | 
| 141          Immediate(masm->isolate()->factory()->hash_table_map())); | 141          Immediate(masm->isolate()->factory()->hash_table_map())); | 
| 142   __ j(not_equal, miss_label); | 142   __ j(not_equal, miss_label); | 
| 143 | 143 | 
| 144   Label done; | 144   Label done; | 
|  | 145   StringDictionaryLookupStub::GenerateNegativeLookup(masm, | 
|  | 146                                                      miss_label, | 
|  | 147                                                      &done, | 
|  | 148                                                      properties, | 
|  | 149                                                      name, | 
|  | 150                                                      r1); | 
|  | 151   __ bind(&done); | 
|  | 152   __ DecrementCounter(counters->negative_lookups_miss(), 1); | 
|  | 153 } | 
|  | 154 | 
|  | 155 | 
|  | 156 // TODO(kmillikin): Eliminate this function when the stub cache is fully | 
|  | 157 // handlified. | 
|  | 158 static MaybeObject* TryGenerateDictionaryNegativeLookup(MacroAssembler* masm, | 
|  | 159                                                         Label* miss_label, | 
|  | 160                                                         Register receiver, | 
|  | 161                                                         String* name, | 
|  | 162                                                         Register r0, | 
|  | 163                                                         Register r1) { | 
|  | 164   ASSERT(name->IsSymbol()); | 
|  | 165   Counters* counters = masm->isolate()->counters(); | 
|  | 166   __ IncrementCounter(counters->negative_lookups(), 1); | 
|  | 167   __ IncrementCounter(counters->negative_lookups_miss(), 1); | 
|  | 168 | 
|  | 169   __ mov(r0, FieldOperand(receiver, HeapObject::kMapOffset)); | 
|  | 170 | 
|  | 171   const int kInterceptorOrAccessCheckNeededMask = | 
|  | 172       (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 
|  | 173 | 
|  | 174   // Bail out if the receiver has a named interceptor or requires access checks. | 
|  | 175   __ test_b(FieldOperand(r0, Map::kBitFieldOffset), | 
|  | 176             kInterceptorOrAccessCheckNeededMask); | 
|  | 177   __ j(not_zero, miss_label); | 
|  | 178 | 
|  | 179   // Check that receiver is a JSObject. | 
|  | 180   __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE); | 
|  | 181   __ j(below, miss_label); | 
|  | 182 | 
|  | 183   // Load properties array. | 
|  | 184   Register properties = r0; | 
|  | 185   __ mov(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 
|  | 186 | 
|  | 187   // Check that the properties array is a dictionary. | 
|  | 188   __ cmp(FieldOperand(properties, HeapObject::kMapOffset), | 
|  | 189          Immediate(masm->isolate()->factory()->hash_table_map())); | 
|  | 190   __ j(not_equal, miss_label); | 
|  | 191 | 
|  | 192   Label done; | 
| 145   MaybeObject* result = | 193   MaybeObject* result = | 
| 146       StringDictionaryLookupStub::GenerateNegativeLookup(masm, | 194       StringDictionaryLookupStub::TryGenerateNegativeLookup(masm, | 
| 147                                                          miss_label, | 195                                                             miss_label, | 
| 148                                                          &done, | 196                                                             &done, | 
| 149                                                          properties, | 197                                                             properties, | 
| 150                                                          name, | 198                                                             name, | 
| 151                                                          r1); | 199                                                             r1); | 
| 152   if (result->IsFailure()) return result; | 200   if (result->IsFailure()) return result; | 
| 153 | 201 | 
| 154   __ bind(&done); | 202   __ bind(&done); | 
| 155   __ DecrementCounter(counters->negative_lookups_miss(), 1); | 203   __ DecrementCounter(counters->negative_lookups_miss(), 1); | 
| 156 | 204 | 
| 157   return result; | 205   return result; | 
| 158 } | 206 } | 
| 159 | 207 | 
| 160 | 208 | 
| 161 void StubCache::GenerateProbe(MacroAssembler* masm, | 209 void StubCache::GenerateProbe(MacroAssembler* masm, | 
| 162                               Code::Flags flags, | 210                               Code::Flags flags, | 
| 163                               Register receiver, | 211                               Register receiver, | 
| 164                               Register name, | 212                               Register name, | 
| 165                               Register scratch, | 213                               Register scratch, | 
| 166                               Register extra, | 214                               Register extra, | 
| 167                               Register extra2) { | 215                               Register extra2) { | 
| 168   Isolate* isolate = Isolate::Current(); |  | 
| 169   Label miss; | 216   Label miss; | 
| 170   USE(extra2);  // The register extra2 is not used on the ia32 platform. |  | 
| 171 | 217 | 
| 172   // Make sure that code is valid. The shifting code relies on the | 218   // Assert that code is valid.  The shifting code relies on the entry size | 
| 173   // entry size being 8. | 219   // being 8. | 
| 174   ASSERT(sizeof(Entry) == 8); | 220   ASSERT(sizeof(Entry) == 8); | 
| 175 | 221 | 
| 176   // Make sure the flags does not name a specific type. | 222   // Assert the flags do not name a specific type. | 
| 177   ASSERT(Code::ExtractTypeFromFlags(flags) == 0); | 223   ASSERT(Code::ExtractTypeFromFlags(flags) == 0); | 
| 178 | 224 | 
| 179   // Make sure that there are no register conflicts. | 225   // Assert that there are no register conflicts. | 
| 180   ASSERT(!scratch.is(receiver)); | 226   ASSERT(!scratch.is(receiver)); | 
| 181   ASSERT(!scratch.is(name)); | 227   ASSERT(!scratch.is(name)); | 
| 182   ASSERT(!extra.is(receiver)); | 228   ASSERT(!extra.is(receiver)); | 
| 183   ASSERT(!extra.is(name)); | 229   ASSERT(!extra.is(name)); | 
| 184   ASSERT(!extra.is(scratch)); | 230   ASSERT(!extra.is(scratch)); | 
| 185 | 231 | 
| 186   // Check scratch and extra registers are valid, and extra2 is unused. | 232   // Assert scratch and extra registers are valid, and extra2 is unused. | 
| 187   ASSERT(!scratch.is(no_reg)); | 233   ASSERT(!scratch.is(no_reg)); | 
| 188   ASSERT(extra2.is(no_reg)); | 234   ASSERT(extra2.is(no_reg)); | 
| 189 | 235 | 
| 190   // Check that the receiver isn't a smi. | 236   // Check that the receiver isn't a smi. | 
| 191   __ JumpIfSmi(receiver, &miss); | 237   __ JumpIfSmi(receiver, &miss); | 
| 192 | 238 | 
| 193   // Get the map of the receiver and compute the hash. | 239   // Get the map of the receiver and compute the hash. | 
| 194   __ mov(scratch, FieldOperand(name, String::kHashFieldOffset)); | 240   __ mov(scratch, FieldOperand(name, String::kHashFieldOffset)); | 
| 195   __ add(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | 241   __ add(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | 
| 196   __ xor_(scratch, flags); | 242   __ xor_(scratch, flags); | 
| 197   __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize); | 243   __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize); | 
| 198 | 244 | 
| 199   // Probe the primary table. | 245   // Probe the primary table. | 
| 200   ProbeTable(isolate, masm, flags, kPrimary, name, scratch, extra); | 246   ProbeTable(isolate(), masm, flags, kPrimary, name, scratch, extra); | 
| 201 | 247 | 
| 202   // Primary miss: Compute hash for secondary probe. | 248   // Primary miss: Compute hash for secondary probe. | 
| 203   __ mov(scratch, FieldOperand(name, String::kHashFieldOffset)); | 249   __ mov(scratch, FieldOperand(name, String::kHashFieldOffset)); | 
| 204   __ add(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | 250   __ add(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | 
| 205   __ xor_(scratch, flags); | 251   __ xor_(scratch, flags); | 
| 206   __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize); | 252   __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize); | 
| 207   __ sub(scratch, name); | 253   __ sub(scratch, name); | 
| 208   __ add(scratch, Immediate(flags)); | 254   __ add(scratch, Immediate(flags)); | 
| 209   __ and_(scratch, (kSecondaryTableSize - 1) << kHeapObjectTagSize); | 255   __ and_(scratch, (kSecondaryTableSize - 1) << kHeapObjectTagSize); | 
| 210 | 256 | 
| 211   // Probe the secondary table. | 257   // Probe the secondary table. | 
| 212   ProbeTable(isolate, masm, flags, kSecondary, name, scratch, extra); | 258   ProbeTable(isolate(), masm, flags, kSecondary, name, scratch, extra); | 
| 213 | 259 | 
| 214   // Cache miss: Fall-through and let caller handle the miss by | 260   // Cache miss: Fall-through and let caller handle the miss by | 
| 215   // entering the runtime system. | 261   // entering the runtime system. | 
| 216   __ bind(&miss); | 262   __ bind(&miss); | 
| 217 } | 263 } | 
| 218 | 264 | 
| 219 | 265 | 
| 220 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, | 266 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, | 
| 221                                                        int index, | 267                                                        int index, | 
| 222                                                        Register prototype) { | 268                                                        Register prototype) { | 
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 320   __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); | 366   __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); | 
| 321   __ mov(eax, scratch1); | 367   __ mov(eax, scratch1); | 
| 322   __ ret(0); | 368   __ ret(0); | 
| 323 } | 369 } | 
| 324 | 370 | 
| 325 | 371 | 
| 326 // Load a fast property out of a holder object (src). In-object properties | 372 // Load a fast property out of a holder object (src). In-object properties | 
| 327 // are loaded directly otherwise the property is loaded from the properties | 373 // are loaded directly otherwise the property is loaded from the properties | 
| 328 // fixed array. | 374 // fixed array. | 
| 329 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, | 375 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, | 
| 330                                             Register dst, Register src, | 376                                             Register dst, | 
| 331                                             JSObject* holder, int index) { | 377                                             Register src, | 
|  | 378                                             Handle<JSObject> holder, | 
|  | 379                                             int index) { | 
| 332   // Adjust for the number of properties stored in the holder. | 380   // Adjust for the number of properties stored in the holder. | 
| 333   index -= holder->map()->inobject_properties(); | 381   index -= holder->map()->inobject_properties(); | 
| 334   if (index < 0) { | 382   if (index < 0) { | 
| 335     // Get the property straight out of the holder. | 383     // Get the property straight out of the holder. | 
| 336     int offset = holder->map()->instance_size() + (index * kPointerSize); | 384     int offset = holder->map()->instance_size() + (index * kPointerSize); | 
| 337     __ mov(dst, FieldOperand(src, offset)); | 385     __ mov(dst, FieldOperand(src, offset)); | 
| 338   } else { | 386   } else { | 
| 339     // Calculate the offset into the properties array. | 387     // Calculate the offset into the properties array. | 
| 340     int offset = index * kPointerSize + FixedArray::kHeaderSize; | 388     int offset = index * kPointerSize + FixedArray::kHeaderSize; | 
| 341     __ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset)); | 389     __ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset)); | 
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 479   return masm->TryCallApiFunctionAndReturn(&fun, | 527   return masm->TryCallApiFunctionAndReturn(&fun, | 
| 480                                            argc + kFastApiCallArguments + 1); | 528                                            argc + kFastApiCallArguments + 1); | 
| 481 } | 529 } | 
| 482 | 530 | 
| 483 | 531 | 
| 484 class CallInterceptorCompiler BASE_EMBEDDED { | 532 class CallInterceptorCompiler BASE_EMBEDDED { | 
| 485  public: | 533  public: | 
| 486   CallInterceptorCompiler(StubCompiler* stub_compiler, | 534   CallInterceptorCompiler(StubCompiler* stub_compiler, | 
| 487                           const ParameterCount& arguments, | 535                           const ParameterCount& arguments, | 
| 488                           Register name, | 536                           Register name, | 
| 489                           Code::ExtraICState extra_ic_state) | 537                           Code::ExtraICState extra_state) | 
| 490       : stub_compiler_(stub_compiler), | 538       : stub_compiler_(stub_compiler), | 
| 491         arguments_(arguments), | 539         arguments_(arguments), | 
| 492         name_(name), | 540         name_(name), | 
| 493         extra_ic_state_(extra_ic_state) {} | 541         extra_state_(extra_state) {} | 
| 494 | 542 | 
| 495   MaybeObject* Compile(MacroAssembler* masm, | 543   MaybeObject* Compile(MacroAssembler* masm, | 
| 496                        JSObject* object, | 544                        JSObject* object, | 
| 497                        JSObject* holder, | 545                        JSObject* holder, | 
| 498                        String* name, | 546                        String* name, | 
| 499                        LookupResult* lookup, | 547                        LookupResult* lookup, | 
| 500                        Register receiver, | 548                        Register receiver, | 
| 501                        Register scratch1, | 549                        Register scratch1, | 
| 502                        Register scratch2, | 550                        Register scratch2, | 
| 503                        Register scratch3, | 551                        Register scratch3, | 
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 607       // by the previous CheckPrototypes. | 655       // by the previous CheckPrototypes. | 
| 608       ASSERT(depth2 == kInvalidProtoDepth); | 656       ASSERT(depth2 == kInvalidProtoDepth); | 
| 609     } | 657     } | 
| 610 | 658 | 
| 611     // Invoke function. | 659     // Invoke function. | 
| 612     if (can_do_fast_api_call) { | 660     if (can_do_fast_api_call) { | 
| 613       MaybeObject* result = | 661       MaybeObject* result = | 
| 614           GenerateFastApiCall(masm, optimization, arguments_.immediate()); | 662           GenerateFastApiCall(masm, optimization, arguments_.immediate()); | 
| 615       if (result->IsFailure()) return result; | 663       if (result->IsFailure()) return result; | 
| 616     } else { | 664     } else { | 
| 617       CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 665       CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 
| 618           ? CALL_AS_FUNCTION | 666           ? CALL_AS_FUNCTION | 
| 619           : CALL_AS_METHOD; | 667           : CALL_AS_METHOD; | 
| 620       __ InvokeFunction(optimization.constant_function(), arguments_, | 668       __ InvokeFunction(optimization.constant_function(), arguments_, | 
| 621                         JUMP_FUNCTION, NullCallWrapper(), call_kind); | 669                         JUMP_FUNCTION, NullCallWrapper(), call_kind); | 
| 622     } | 670     } | 
| 623 | 671 | 
| 624     // Deferred code for fast API call case---clean preallocated space. | 672     // Deferred code for fast API call case---clean preallocated space. | 
| 625     if (can_do_fast_api_call) { | 673     if (can_do_fast_api_call) { | 
| 626       __ bind(&miss_cleanup); | 674       __ bind(&miss_cleanup); | 
| 627       FreeSpaceForFastApiCall(masm, scratch1); | 675       FreeSpaceForFastApiCall(masm, scratch1); | 
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 693       // Leave the internal frame. | 741       // Leave the internal frame. | 
| 694     } | 742     } | 
| 695 | 743 | 
| 696     __ cmp(eax, masm->isolate()->factory()->no_interceptor_result_sentinel()); | 744     __ cmp(eax, masm->isolate()->factory()->no_interceptor_result_sentinel()); | 
| 697     __ j(not_equal, interceptor_succeeded); | 745     __ j(not_equal, interceptor_succeeded); | 
| 698   } | 746   } | 
| 699 | 747 | 
| 700   StubCompiler* stub_compiler_; | 748   StubCompiler* stub_compiler_; | 
| 701   const ParameterCount& arguments_; | 749   const ParameterCount& arguments_; | 
| 702   Register name_; | 750   Register name_; | 
| 703   Code::ExtraICState extra_ic_state_; | 751   Code::ExtraICState extra_state_; | 
| 704 }; | 752 }; | 
| 705 | 753 | 
| 706 | 754 | 
| 707 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { | 755 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { | 
| 708   ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); | 756   ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); | 
| 709   Code* code = NULL; | 757   Handle<Code> code = (kind == Code::LOAD_IC) | 
| 710   if (kind == Code::LOAD_IC) { | 758       ? masm->isolate()->builtins()->LoadIC_Miss() | 
| 711     code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss); | 759       : masm->isolate()->builtins()->KeyedLoadIC_Miss(); | 
| 712   } else { | 760   __ jmp(code, RelocInfo::CODE_TARGET); | 
| 713     code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss); |  | 
| 714   } |  | 
| 715 |  | 
| 716   Handle<Code> ic(code); |  | 
| 717   __ jmp(ic, RelocInfo::CODE_TARGET); |  | 
| 718 } | 761 } | 
| 719 | 762 | 
| 720 | 763 | 
| 721 void StubCompiler::GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm) { | 764 void StubCompiler::GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm) { | 
| 722   Code* code = masm->isolate()->builtins()->builtin( | 765   Code* code = masm->isolate()->builtins()->builtin( | 
| 723       Builtins::kKeyedLoadIC_MissForceGeneric); | 766       Builtins::kKeyedLoadIC_MissForceGeneric); | 
| 724   Handle<Code> ic(code); | 767   Handle<Code> ic(code); | 
| 725   __ jmp(ic, RelocInfo::CODE_TARGET); | 768   __ jmp(ic, RelocInfo::CODE_TARGET); | 
| 726 } | 769 } | 
| 727 | 770 | 
| 728 | 771 | 
| 729 // Both name_reg and receiver_reg are preserved on jumps to miss_label, | 772 // Both name_reg and receiver_reg are preserved on jumps to miss_label, | 
| 730 // but may be destroyed if store is successful. | 773 // but may be destroyed if store is successful. | 
| 731 void StubCompiler::GenerateStoreField(MacroAssembler* masm, | 774 void StubCompiler::GenerateStoreField(MacroAssembler* masm, | 
| 732                                       JSObject* object, | 775                                       Handle<JSObject> object, | 
| 733                                       int index, | 776                                       int index, | 
| 734                                       Map* transition, | 777                                       Handle<Map> transition, | 
| 735                                       Register receiver_reg, | 778                                       Register receiver_reg, | 
| 736                                       Register name_reg, | 779                                       Register name_reg, | 
| 737                                       Register scratch, | 780                                       Register scratch, | 
| 738                                       Label* miss_label) { | 781                                       Label* miss_label) { | 
| 739   // Check that the object isn't a smi. | 782   // Check that the object isn't a smi. | 
| 740   __ JumpIfSmi(receiver_reg, miss_label); | 783   __ JumpIfSmi(receiver_reg, miss_label); | 
| 741 | 784 | 
| 742   // Check that the map of the object hasn't changed. | 785   // Check that the map of the object hasn't changed. | 
| 743   __ cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset), | 786   __ cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset), | 
| 744          Immediate(Handle<Map>(object->map()))); | 787          Immediate(Handle<Map>(object->map()))); | 
| 745   __ j(not_equal, miss_label); | 788   __ j(not_equal, miss_label); | 
| 746 | 789 | 
| 747   // Perform global security token check if needed. | 790   // Perform global security token check if needed. | 
| 748   if (object->IsJSGlobalProxy()) { | 791   if (object->IsJSGlobalProxy()) { | 
| 749     __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); | 792     __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); | 
| 750   } | 793   } | 
| 751 | 794 | 
| 752   // Stub never generated for non-global objects that require access | 795   // Stub never generated for non-global objects that require access | 
| 753   // checks. | 796   // checks. | 
| 754   ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 797   ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 
| 755 | 798 | 
| 756   // Perform map transition for the receiver if necessary. | 799   // Perform map transition for the receiver if necessary. | 
| 757   if ((transition != NULL) && (object->map()->unused_property_fields() == 0)) { | 800   if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) { | 
| 758     // The properties must be extended before we can store the value. | 801     // The properties must be extended before we can store the value. | 
| 759     // We jump to a runtime call that extends the properties array. | 802     // We jump to a runtime call that extends the properties array. | 
| 760     __ pop(scratch);  // Return address. | 803     __ pop(scratch);  // Return address. | 
| 761     __ push(receiver_reg); | 804     __ push(receiver_reg); | 
| 762     __ push(Immediate(Handle<Map>(transition))); | 805     __ push(Immediate(transition)); | 
| 763     __ push(eax); | 806     __ push(eax); | 
| 764     __ push(scratch); | 807     __ push(scratch); | 
| 765     __ TailCallExternalReference( | 808     __ TailCallExternalReference( | 
| 766         ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), | 809         ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), | 
| 767                           masm->isolate()), | 810                           masm->isolate()), | 
| 768         3, | 811         3, | 
| 769         1); | 812         1); | 
| 770     return; | 813     return; | 
| 771   } | 814   } | 
| 772 | 815 | 
| 773   if (transition != NULL) { | 816   if (!transition.is_null()) { | 
| 774     // Update the map of the object; no write barrier updating is | 817     // Update the map of the object; no write barrier updating is | 
| 775     // needed because the map is never in new space. | 818     // needed because the map is never in new space. | 
| 776     __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), | 819     __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), | 
| 777            Immediate(Handle<Map>(transition))); | 820            Immediate(transition)); | 
| 778   } | 821   } | 
| 779 | 822 | 
| 780   // Adjust for the number of properties stored in the object. Even in the | 823   // Adjust for the number of properties stored in the object. Even in the | 
| 781   // face of a transition we can use the old map here because the size of the | 824   // face of a transition we can use the old map here because the size of the | 
| 782   // object and the number of in-object properties is not going to change. | 825   // object and the number of in-object properties is not going to change. | 
| 783   index -= object->map()->inobject_properties(); | 826   index -= object->map()->inobject_properties(); | 
| 784 | 827 | 
| 785   if (index < 0) { | 828   if (index < 0) { | 
| 786     // Set the property straight into the object. | 829     // Set the property straight into the object. | 
| 787     int offset = object->map()->instance_size() + (index * kPointerSize); | 830     int offset = object->map()->instance_size() + (index * kPointerSize); | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 813   } | 856   } | 
| 814 | 857 | 
| 815   // Return the value (register eax). | 858   // Return the value (register eax). | 
| 816   __ ret(0); | 859   __ ret(0); | 
| 817 } | 860 } | 
| 818 | 861 | 
| 819 | 862 | 
| 820 // Generate code to check that a global property cell is empty. Create | 863 // Generate code to check that a global property cell is empty. Create | 
| 821 // the property cell at compilation time if no cell exists for the | 864 // the property cell at compilation time if no cell exists for the | 
| 822 // property. | 865 // property. | 
| 823 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCell( | 866 static void GenerateCheckPropertyCell(MacroAssembler* masm, | 
|  | 867                                       Handle<GlobalObject> global, | 
|  | 868                                       Handle<String> name, | 
|  | 869                                       Register scratch, | 
|  | 870                                       Label* miss) { | 
|  | 871   Handle<JSGlobalPropertyCell> cell = | 
|  | 872       GlobalObject::EnsurePropertyCell(global, name); | 
|  | 873   ASSERT(cell->value()->IsTheHole()); | 
|  | 874   Handle<Oddball> the_hole = masm->isolate()->factory()->the_hole_value(); | 
|  | 875   if (Serializer::enabled()) { | 
|  | 876     __ mov(scratch, Immediate(cell)); | 
|  | 877     __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), | 
|  | 878            Immediate(the_hole)); | 
|  | 879   } else { | 
|  | 880     __ cmp(Operand::Cell(cell), Immediate(the_hole)); | 
|  | 881   } | 
|  | 882   __ j(not_equal, miss); | 
|  | 883 } | 
|  | 884 | 
|  | 885 | 
|  | 886 // TODO(kmillikin): Eliminate this function when the stub cache is fully | 
|  | 887 // handlified. | 
|  | 888 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCell( | 
| 824     MacroAssembler* masm, | 889     MacroAssembler* masm, | 
| 825     GlobalObject* global, | 890     GlobalObject* global, | 
| 826     String* name, | 891     String* name, | 
| 827     Register scratch, | 892     Register scratch, | 
| 828     Label* miss) { | 893     Label* miss) { | 
| 829   Object* probe; | 894   Object* probe; | 
| 830   { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); | 895   { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); | 
| 831     if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 896     if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 
| 832   } | 897   } | 
| 833   JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); | 898   JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); | 
| 834   ASSERT(cell->value()->IsTheHole()); | 899   ASSERT(cell->value()->IsTheHole()); | 
| 835   if (Serializer::enabled()) { | 900   if (Serializer::enabled()) { | 
| 836     __ mov(scratch, Immediate(Handle<Object>(cell))); | 901     __ mov(scratch, Immediate(Handle<Object>(cell))); | 
| 837     __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), | 902     __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset), | 
| 838            Immediate(masm->isolate()->factory()->the_hole_value())); | 903            Immediate(masm->isolate()->factory()->the_hole_value())); | 
| 839   } else { | 904   } else { | 
| 840     __ cmp(Operand::Cell(Handle<JSGlobalPropertyCell>(cell)), | 905     __ cmp(Operand::Cell(Handle<JSGlobalPropertyCell>(cell)), | 
| 841            Immediate(masm->isolate()->factory()->the_hole_value())); | 906            Immediate(masm->isolate()->factory()->the_hole_value())); | 
| 842   } | 907   } | 
| 843   __ j(not_equal, miss); | 908   __ j(not_equal, miss); | 
| 844   return cell; | 909   return cell; | 
| 845 } | 910 } | 
| 846 | 911 | 
| 847 | 912 | 
| 848 // Calls GenerateCheckPropertyCell for each global object in the prototype chain | 913 // Calls GenerateCheckPropertyCell for each global object in the prototype chain | 
| 849 // from object to (but not including) holder. | 914 // from object to (but not including) holder. | 
| 850 MUST_USE_RESULT static MaybeObject* GenerateCheckPropertyCells( | 915 static void GenerateCheckPropertyCells(MacroAssembler* masm, | 
|  | 916                                        Handle<JSObject> object, | 
|  | 917                                        Handle<JSObject> holder, | 
|  | 918                                        Handle<String> name, | 
|  | 919                                        Register scratch, | 
|  | 920                                        Label* miss) { | 
|  | 921   Handle<JSObject> current = object; | 
|  | 922   while (!current.is_identical_to(holder)) { | 
|  | 923     if (current->IsGlobalObject()) { | 
|  | 924       GenerateCheckPropertyCell(masm, | 
|  | 925                                 Handle<GlobalObject>::cast(current), | 
|  | 926                                 name, | 
|  | 927                                 scratch, | 
|  | 928                                 miss); | 
|  | 929     } | 
|  | 930     current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); | 
|  | 931   } | 
|  | 932 } | 
|  | 933 | 
|  | 934 | 
|  | 935 // TODO(kmillikin): Eliminate this function when the stub cache is fully | 
|  | 936 // handlified. | 
|  | 937 MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCells( | 
| 851     MacroAssembler* masm, | 938     MacroAssembler* masm, | 
| 852     JSObject* object, | 939     JSObject* object, | 
| 853     JSObject* holder, | 940     JSObject* holder, | 
| 854     String* name, | 941     String* name, | 
| 855     Register scratch, | 942     Register scratch, | 
| 856     Label* miss) { | 943     Label* miss) { | 
| 857   JSObject* current = object; | 944   JSObject* current = object; | 
| 858   while (current != holder) { | 945   while (current != holder) { | 
| 859     if (current->IsGlobalObject()) { | 946     if (current->IsGlobalObject()) { | 
| 860       // Returns a cell or a failure. | 947       // Returns a cell or a failure. | 
| 861       MaybeObject* result = GenerateCheckPropertyCell( | 948       MaybeObject* result = TryGenerateCheckPropertyCell( | 
| 862           masm, | 949           masm, | 
| 863           GlobalObject::cast(current), | 950           GlobalObject::cast(current), | 
| 864           name, | 951           name, | 
| 865           scratch, | 952           scratch, | 
| 866           miss); | 953           miss); | 
| 867       if (result->IsFailure()) return result; | 954       if (result->IsFailure()) return result; | 
| 868     } | 955     } | 
| 869     ASSERT(current->IsJSObject()); | 956     ASSERT(current->IsJSObject()); | 
| 870     current = JSObject::cast(current->GetPrototype()); | 957     current = JSObject::cast(current->GetPrototype()); | 
| 871   } | 958   } | 
| 872   return NULL; | 959   return NULL; | 
| 873 } | 960 } | 
| 874 | 961 | 
| 875 | 962 | 
| 876 #undef __ | 963 #undef __ | 
| 877 #define __ ACCESS_MASM(masm()) | 964 #define __ ACCESS_MASM(masm()) | 
| 878 | 965 | 
| 879 | 966 | 
|  | 967 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, | 
|  | 968                                        Register object_reg, | 
|  | 969                                        Handle<JSObject> holder, | 
|  | 970                                        Register holder_reg, | 
|  | 971                                        Register scratch1, | 
|  | 972                                        Register scratch2, | 
|  | 973                                        Handle<String> name, | 
|  | 974                                        int save_at_depth, | 
|  | 975                                        Label* miss) { | 
|  | 976   // Make sure there's no overlap between holder and object registers. | 
|  | 977   ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 
|  | 978   ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 
|  | 979          && !scratch2.is(scratch1)); | 
|  | 980 | 
|  | 981   // Keep track of the current object in register reg. | 
|  | 982   Register reg = object_reg; | 
|  | 983   Handle<JSObject> current = object; | 
|  | 984   int depth = 0; | 
|  | 985 | 
|  | 986   if (save_at_depth == depth) { | 
|  | 987     __ mov(Operand(esp, kPointerSize), reg); | 
|  | 988   } | 
|  | 989 | 
|  | 990   // Traverse the prototype chain and check the maps in the prototype chain for | 
|  | 991   // fast and global objects or do negative lookup for normal objects. | 
|  | 992   while (!current.is_identical_to(holder)) { | 
|  | 993     ++depth; | 
|  | 994 | 
|  | 995     // Only global objects and objects that do not require access | 
|  | 996     // checks are allowed in stubs. | 
|  | 997     ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 
|  | 998 | 
|  | 999     Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); | 
|  | 1000     if (!current->HasFastProperties() && | 
|  | 1001         !current->IsJSGlobalObject() && | 
|  | 1002         !current->IsJSGlobalProxy()) { | 
|  | 1003       if (!name->IsSymbol()) { | 
|  | 1004         name = factory()->LookupSymbol(name); | 
|  | 1005       } | 
|  | 1006       ASSERT(current->property_dictionary()->FindEntry(*name) == | 
|  | 1007              StringDictionary::kNotFound); | 
|  | 1008 | 
|  | 1009       GenerateDictionaryNegativeLookup(masm(), miss, reg, name, | 
|  | 1010                                        scratch1, scratch2); | 
|  | 1011 | 
|  | 1012       __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 
|  | 1013       reg = holder_reg;  // From now on the object will be in holder_reg. | 
|  | 1014       __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); | 
|  | 1015     } else { | 
|  | 1016       bool in_new_space = heap()->InNewSpace(*prototype); | 
|  | 1017       Handle<Map> current_map(current->map()); | 
|  | 1018       if (in_new_space) { | 
|  | 1019         // Save the map in scratch1 for later. | 
|  | 1020         __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 
|  | 1021         __ cmp(scratch1, Immediate(current_map)); | 
|  | 1022       } else { | 
|  | 1023         __ cmp(FieldOperand(reg, HeapObject::kMapOffset), | 
|  | 1024                Immediate(current_map)); | 
|  | 1025       } | 
|  | 1026       // Branch on the result of the map check. | 
|  | 1027       __ j(not_equal, miss); | 
|  | 1028       // Check access rights to the global object.  This has to happen after | 
|  | 1029       // the map check so that we know that the object is actually a global | 
|  | 1030       // object. | 
|  | 1031       if (current->IsJSGlobalProxy()) { | 
|  | 1032         __ CheckAccessGlobalProxy(reg, scratch2, miss); | 
|  | 1033       } | 
|  | 1034       reg = holder_reg;  // From now on the object will be in holder_reg. | 
|  | 1035 | 
|  | 1036       if (in_new_space) { | 
|  | 1037         // The prototype is in new space; we cannot store a reference to it | 
|  | 1038         // in the code.  Load it from the map. | 
|  | 1039         __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); | 
|  | 1040       } else { | 
|  | 1041         // The prototype is in old space; load it directly. | 
|  | 1042         __ mov(reg, prototype); | 
|  | 1043       } | 
|  | 1044     } | 
|  | 1045 | 
|  | 1046     if (save_at_depth == depth) { | 
|  | 1047       __ mov(Operand(esp, kPointerSize), reg); | 
|  | 1048     } | 
|  | 1049 | 
|  | 1050     // Go to the next object in the prototype chain. | 
|  | 1051     current = prototype; | 
|  | 1052   } | 
|  | 1053   ASSERT(current.is_identical_to(holder)); | 
|  | 1054 | 
|  | 1055   // Log the check depth. | 
|  | 1056   LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); | 
|  | 1057 | 
|  | 1058   // Check the holder map. | 
|  | 1059   __ cmp(FieldOperand(reg, HeapObject::kMapOffset), | 
|  | 1060          Immediate(Handle<Map>(holder->map()))); | 
|  | 1061   __ j(not_equal, miss); | 
|  | 1062 | 
|  | 1063   // Perform security check for access to the global object. | 
|  | 1064   ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 
|  | 1065   if (holder->IsJSGlobalProxy()) { | 
|  | 1066     __ CheckAccessGlobalProxy(reg, scratch1, miss); | 
|  | 1067   } | 
|  | 1068 | 
|  | 1069   // If we've skipped any global objects, it's not enough to verify that | 
|  | 1070   // their maps haven't changed.  We also need to check that the property | 
|  | 1071   // cell for the property is still empty. | 
|  | 1072   GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); | 
|  | 1073 | 
|  | 1074   // Return the register containing the holder. | 
|  | 1075   return reg; | 
|  | 1076 } | 
|  | 1077 | 
|  | 1078 | 
|  | 1079 // TODO(kmillikin): Eliminate this function when the stub cache is fully | 
|  | 1080 // handlified. | 
| 880 Register StubCompiler::CheckPrototypes(JSObject* object, | 1081 Register StubCompiler::CheckPrototypes(JSObject* object, | 
| 881                                        Register object_reg, | 1082                                        Register object_reg, | 
| 882                                        JSObject* holder, | 1083                                        JSObject* holder, | 
| 883                                        Register holder_reg, | 1084                                        Register holder_reg, | 
| 884                                        Register scratch1, | 1085                                        Register scratch1, | 
| 885                                        Register scratch2, | 1086                                        Register scratch2, | 
| 886                                        String* name, | 1087                                        String* name, | 
| 887                                        int save_at_depth, | 1088                                        int save_at_depth, | 
| 888                                        Label* miss) { | 1089                                        Label* miss) { | 
| 889   // Make sure there's no overlap between holder and object registers. | 1090   // Make sure there's no overlap between holder and object registers. | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 919         Object* lookup_result = NULL;  // Initialization to please compiler. | 1120         Object* lookup_result = NULL;  // Initialization to please compiler. | 
| 920         if (!maybe_lookup_result->ToObject(&lookup_result)) { | 1121         if (!maybe_lookup_result->ToObject(&lookup_result)) { | 
| 921           set_failure(Failure::cast(maybe_lookup_result)); | 1122           set_failure(Failure::cast(maybe_lookup_result)); | 
| 922           return reg; | 1123           return reg; | 
| 923         } | 1124         } | 
| 924         name = String::cast(lookup_result); | 1125         name = String::cast(lookup_result); | 
| 925       } | 1126       } | 
| 926       ASSERT(current->property_dictionary()->FindEntry(name) == | 1127       ASSERT(current->property_dictionary()->FindEntry(name) == | 
| 927              StringDictionary::kNotFound); | 1128              StringDictionary::kNotFound); | 
| 928 | 1129 | 
| 929       MaybeObject* negative_lookup = GenerateDictionaryNegativeLookup(masm(), | 1130       MaybeObject* negative_lookup = | 
| 930                                                                       miss, | 1131           TryGenerateDictionaryNegativeLookup(masm(), miss, reg, name, | 
| 931                                                                       reg, | 1132                                               scratch1, scratch2); | 
| 932                                                                       name, |  | 
| 933                                                                       scratch1, |  | 
| 934                                                                       scratch2); |  | 
| 935       if (negative_lookup->IsFailure()) { | 1133       if (negative_lookup->IsFailure()) { | 
| 936         set_failure(Failure::cast(negative_lookup)); | 1134         set_failure(Failure::cast(negative_lookup)); | 
| 937         return reg; | 1135         return reg; | 
| 938       } | 1136       } | 
| 939 | 1137 | 
| 940       __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 1138       __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); | 
| 941       reg = holder_reg;  // from now the object is in holder_reg | 1139       reg = holder_reg;  // from now the object is in holder_reg | 
| 942       __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); | 1140       __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); | 
| 943     } else if (heap()->InNewSpace(prototype)) { | 1141     } else if (heap()->InNewSpace(prototype)) { | 
| 944       // Get the map of the current object. | 1142       // Get the map of the current object. | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 991 | 1189 | 
| 992   // Check the holder map. | 1190   // Check the holder map. | 
| 993   __ cmp(FieldOperand(reg, HeapObject::kMapOffset), | 1191   __ cmp(FieldOperand(reg, HeapObject::kMapOffset), | 
| 994          Immediate(Handle<Map>(holder->map()))); | 1192          Immediate(Handle<Map>(holder->map()))); | 
| 995   __ j(not_equal, miss); | 1193   __ j(not_equal, miss); | 
| 996 | 1194 | 
| 997   // Perform security check for access to the global object. | 1195   // Perform security check for access to the global object. | 
| 998   ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 1196   ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 
| 999   if (holder->IsJSGlobalProxy()) { | 1197   if (holder->IsJSGlobalProxy()) { | 
| 1000     __ CheckAccessGlobalProxy(reg, scratch1, miss); | 1198     __ CheckAccessGlobalProxy(reg, scratch1, miss); | 
| 1001   }; | 1199   } | 
| 1002 | 1200 | 
| 1003   // If we've skipped any global objects, it's not enough to verify | 1201   // If we've skipped any global objects, it's not enough to verify | 
| 1004   // that their maps haven't changed.  We also need to check that the | 1202   // that their maps haven't changed.  We also need to check that the | 
| 1005   // property cell for the property is still empty. | 1203   // property cell for the property is still empty. | 
| 1006   MaybeObject* result = GenerateCheckPropertyCells(masm(), | 1204   MaybeObject* result = TryGenerateCheckPropertyCells(masm(), | 
| 1007                                                    object, | 1205                                                       object, | 
| 1008                                                    holder, | 1206                                                       holder, | 
| 1009                                                    name, | 1207                                                       name, | 
| 1010                                                    scratch1, | 1208                                                       scratch1, | 
| 1011                                                    miss); | 1209                                                       miss); | 
| 1012   if (result->IsFailure()) set_failure(Failure::cast(result)); | 1210   if (result->IsFailure()) set_failure(Failure::cast(result)); | 
| 1013 | 1211 | 
| 1014   // Return the register containing the holder. | 1212   // Return the register containing the holder. | 
| 1015   return reg; | 1213   return reg; | 
| 1016 } | 1214 } | 
| 1017 | 1215 | 
| 1018 | 1216 | 
| 1019 void StubCompiler::GenerateLoadField(JSObject* object, | 1217 void StubCompiler::GenerateLoadField(Handle<JSObject> object, | 
| 1020                                      JSObject* holder, | 1218                                      Handle<JSObject> holder, | 
| 1021                                      Register receiver, | 1219                                      Register receiver, | 
| 1022                                      Register scratch1, | 1220                                      Register scratch1, | 
| 1023                                      Register scratch2, | 1221                                      Register scratch2, | 
| 1024                                      Register scratch3, | 1222                                      Register scratch3, | 
| 1025                                      int index, | 1223                                      int index, | 
| 1026                                      String* name, | 1224                                      Handle<String> name, | 
| 1027                                      Label* miss) { | 1225                                      Label* miss) { | 
| 1028   // Check that the receiver isn't a smi. | 1226   // Check that the receiver isn't a smi. | 
| 1029   __ JumpIfSmi(receiver, miss); | 1227   __ JumpIfSmi(receiver, miss); | 
| 1030 | 1228 | 
| 1031   // Check the prototype chain. | 1229   // Check the prototype chain. | 
| 1032   Register reg = | 1230   Register reg = CheckPrototypes( | 
| 1033       CheckPrototypes(object, receiver, holder, | 1231       object, receiver, holder, scratch1, scratch2, scratch3, name, miss); | 
| 1034                       scratch1, scratch2, scratch3, name, miss); |  | 
| 1035 | 1232 | 
| 1036   // Get the value from the properties. | 1233   // Get the value from the properties. | 
| 1037   GenerateFastPropertyLoad(masm(), eax, reg, holder, index); | 1234   GenerateFastPropertyLoad(masm(), eax, reg, holder, index); | 
| 1038   __ ret(0); | 1235   __ ret(0); | 
| 1039 } | 1236 } | 
| 1040 | 1237 | 
| 1041 | 1238 | 
| 1042 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, | 1239 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, | 
| 1043                                                 JSObject* holder, | 1240                                                 JSObject* holder, | 
| 1044                                                 Register receiver, | 1241                                                 Register receiver, | 
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1099   __ mov(ApiParameterOperand(1), ebx);  // arguments pointer. | 1296   __ mov(ApiParameterOperand(1), ebx);  // arguments pointer. | 
| 1100 | 1297 | 
| 1101   // Emitting a stub call may try to allocate (if the code is not | 1298   // Emitting a stub call may try to allocate (if the code is not | 
| 1102   // already generated).  Do not allow the assembler to perform a | 1299   // already generated).  Do not allow the assembler to perform a | 
| 1103   // garbage collection but instead return the allocation failure | 1300   // garbage collection but instead return the allocation failure | 
| 1104   // object. | 1301   // object. | 
| 1105   return masm()->TryCallApiFunctionAndReturn(&fun, kStackSpace); | 1302   return masm()->TryCallApiFunctionAndReturn(&fun, kStackSpace); | 
| 1106 } | 1303 } | 
| 1107 | 1304 | 
| 1108 | 1305 | 
| 1109 void StubCompiler::GenerateLoadConstant(JSObject* object, | 1306 void StubCompiler::GenerateLoadConstant(Handle<JSObject> object, | 
| 1110                                         JSObject* holder, | 1307                                         Handle<JSObject> holder, | 
| 1111                                         Register receiver, | 1308                                         Register receiver, | 
| 1112                                         Register scratch1, | 1309                                         Register scratch1, | 
| 1113                                         Register scratch2, | 1310                                         Register scratch2, | 
| 1114                                         Register scratch3, | 1311                                         Register scratch3, | 
| 1115                                         Object* value, | 1312                                         Handle<Object> value, | 
| 1116                                         String* name, | 1313                                         Handle<String> name, | 
| 1117                                         Label* miss) { | 1314                                         Label* miss) { | 
| 1118   // Check that the receiver isn't a smi. | 1315   // Check that the receiver isn't a smi. | 
| 1119   __ JumpIfSmi(receiver, miss); | 1316   __ JumpIfSmi(receiver, miss); | 
| 1120 | 1317 | 
| 1121   // Check that the maps haven't changed. | 1318   // Check that the maps haven't changed. | 
| 1122   CheckPrototypes(object, receiver, holder, | 1319   CheckPrototypes( | 
| 1123                   scratch1, scratch2, scratch3, name, miss); | 1320       object, receiver, holder, scratch1, scratch2, scratch3, name, miss); | 
| 1124 | 1321 | 
| 1125   // Return the constant value. | 1322   // Return the constant value. | 
| 1126   __ mov(eax, Handle<Object>(value)); | 1323   __ mov(eax, value); | 
| 1127   __ ret(0); | 1324   __ ret(0); | 
| 1128 } | 1325 } | 
| 1129 | 1326 | 
| 1130 | 1327 | 
| 1131 void StubCompiler::GenerateLoadInterceptor(JSObject* object, | 1328 void StubCompiler::GenerateLoadInterceptor(JSObject* object, | 
| 1132                                            JSObject* interceptor_holder, | 1329                                            JSObject* interceptor_holder, | 
| 1133                                            LookupResult* lookup, | 1330                                            LookupResult* lookup, | 
| 1134                                            Register receiver, | 1331                                            Register receiver, | 
| 1135                                            Register name_reg, | 1332                                            Register name_reg, | 
| 1136                                            Register scratch1, | 1333                                            Register scratch1, | 
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1216                                    scratch2, | 1413                                    scratch2, | 
| 1217                                    scratch3, | 1414                                    scratch3, | 
| 1218                                    name, | 1415                                    name, | 
| 1219                                    miss); | 1416                                    miss); | 
| 1220     } | 1417     } | 
| 1221 | 1418 | 
| 1222     if (lookup->type() == FIELD) { | 1419     if (lookup->type() == FIELD) { | 
| 1223       // We found FIELD property in prototype chain of interceptor's holder. | 1420       // We found FIELD property in prototype chain of interceptor's holder. | 
| 1224       // Retrieve a field from field's holder. | 1421       // Retrieve a field from field's holder. | 
| 1225       GenerateFastPropertyLoad(masm(), eax, holder_reg, | 1422       GenerateFastPropertyLoad(masm(), eax, holder_reg, | 
| 1226                                lookup->holder(), lookup->GetFieldIndex()); | 1423                                Handle<JSObject>(lookup->holder()), | 
|  | 1424                                lookup->GetFieldIndex()); | 
| 1227       __ ret(0); | 1425       __ ret(0); | 
| 1228     } else { | 1426     } else { | 
| 1229       // We found CALLBACKS property in prototype chain of interceptor's | 1427       // We found CALLBACKS property in prototype chain of interceptor's | 
| 1230       // holder. | 1428       // holder. | 
| 1231       ASSERT(lookup->type() == CALLBACKS); | 1429       ASSERT(lookup->type() == CALLBACKS); | 
| 1232       ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); | 1430       ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); | 
| 1233       AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); | 1431       AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); | 
| 1234       ASSERT(callback != NULL); | 1432       ASSERT(callback != NULL); | 
| 1235       ASSERT(callback->getter() != NULL); | 1433       ASSERT(callback->getter() != NULL); | 
| 1236 | 1434 | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
| 1263     __ push(scratch2);  // restore old return address | 1461     __ push(scratch2);  // restore old return address | 
| 1264 | 1462 | 
| 1265     ExternalReference ref = | 1463     ExternalReference ref = | 
| 1266         ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), | 1464         ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), | 
| 1267                           isolate()); | 1465                           isolate()); | 
| 1268     __ TailCallExternalReference(ref, 5, 1); | 1466     __ TailCallExternalReference(ref, 5, 1); | 
| 1269   } | 1467   } | 
| 1270 } | 1468 } | 
| 1271 | 1469 | 
| 1272 | 1470 | 
| 1273 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { | 1471 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) { | 
| 1274   if (kind_ == Code::KEYED_CALL_IC) { | 1472   if (kind_ == Code::KEYED_CALL_IC) { | 
| 1275     __ cmp(ecx, Immediate(Handle<String>(name))); | 1473     __ cmp(ecx, Immediate(name)); | 
| 1276     __ j(not_equal, miss); | 1474     __ j(not_equal, miss); | 
| 1277   } | 1475   } | 
| 1278 } | 1476 } | 
| 1279 | 1477 | 
| 1280 | 1478 | 
| 1281 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, | 1479 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, | 
| 1282                                                    JSObject* holder, | 1480                                                    JSObject* holder, | 
| 1283                                                    String* name, | 1481                                                    String* name, | 
| 1284                                                    Label* miss) { | 1482                                                    Label* miss) { | 
| 1285   ASSERT(holder->IsGlobalObject()); | 1483   ASSERT(holder->IsGlobalObject()); | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1328     __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset), | 1526     __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset), | 
| 1329            Immediate(Handle<SharedFunctionInfo>(function->shared()))); | 1527            Immediate(Handle<SharedFunctionInfo>(function->shared()))); | 
| 1330     __ j(not_equal, miss); | 1528     __ j(not_equal, miss); | 
| 1331   } else { | 1529   } else { | 
| 1332     __ cmp(edi, Immediate(Handle<JSFunction>(function))); | 1530     __ cmp(edi, Immediate(Handle<JSFunction>(function))); | 
| 1333     __ j(not_equal, miss); | 1531     __ j(not_equal, miss); | 
| 1334   } | 1532   } | 
| 1335 } | 1533 } | 
| 1336 | 1534 | 
| 1337 | 1535 | 
| 1338 MaybeObject* CallStubCompiler::GenerateMissBranch() { | 1536 void CallStubCompiler::GenerateMissBranch() { | 
| 1339   MaybeObject* maybe_obj = | 1537   Handle<Code> code = | 
| 1340       isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), | 1538       isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), | 
| 1341                                                kind_, | 1539                                                kind_, | 
| 1342                                                extra_ic_state_); | 1540                                                extra_state_); | 
|  | 1541   __ jmp(code, RelocInfo::CODE_TARGET); | 
|  | 1542 } | 
|  | 1543 | 
|  | 1544 | 
|  | 1545 // TODO(kmillikin): Eliminate this function when the stub cache is fully | 
|  | 1546 // handlified. | 
|  | 1547 MaybeObject* CallStubCompiler::TryGenerateMissBranch() { | 
|  | 1548   MaybeObject* maybe_obj = | 
|  | 1549       isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(), | 
|  | 1550                                                   kind_, | 
|  | 1551                                                   extra_state_); | 
| 1343   Object* obj; | 1552   Object* obj; | 
| 1344   if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1553   if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 
| 1345   __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); | 1554   __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); | 
| 1346   return obj; | 1555   return obj; | 
| 1347 } | 1556 } | 
| 1348 | 1557 | 
| 1349 | 1558 | 
| 1350 MUST_USE_RESULT MaybeObject* CallStubCompiler::CompileCallField( | 1559 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, | 
| 1351     JSObject* object, | 1560                                                 Handle<JSObject> holder, | 
| 1352     JSObject* holder, | 1561                                                 int index, | 
| 1353     int index, | 1562                                                 Handle<String> name) { | 
| 1354     String* name) { |  | 
| 1355   // ----------- S t a t e ------------- | 1563   // ----------- S t a t e ------------- | 
| 1356   //  -- ecx                 : name | 1564   //  -- ecx                 : name | 
| 1357   //  -- esp[0]              : return address | 1565   //  -- esp[0]              : return address | 
| 1358   //  -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1566   //  -- esp[(argc - n) * 4] : arg[n] (zero-based) | 
| 1359   //  -- ... | 1567   //  -- ... | 
| 1360   //  -- esp[(argc + 1) * 4] : receiver | 1568   //  -- esp[(argc + 1) * 4] : receiver | 
| 1361   // ----------------------------------- | 1569   // ----------------------------------- | 
| 1362   Label miss; | 1570   Label miss; | 
| 1363 | 1571 | 
| 1364   GenerateNameCheck(name, &miss); | 1572   GenerateNameCheck(name, &miss); | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 1382   __ j(not_equal, &miss); | 1590   __ j(not_equal, &miss); | 
| 1383 | 1591 | 
| 1384   // Patch the receiver on the stack with the global proxy if | 1592   // Patch the receiver on the stack with the global proxy if | 
| 1385   // necessary. | 1593   // necessary. | 
| 1386   if (object->IsGlobalObject()) { | 1594   if (object->IsGlobalObject()) { | 
| 1387     __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 1595     __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 
| 1388     __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 1596     __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 
| 1389   } | 1597   } | 
| 1390 | 1598 | 
| 1391   // Invoke the function. | 1599   // Invoke the function. | 
| 1392   CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 1600   CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 
| 1393       ? CALL_AS_FUNCTION | 1601       ? CALL_AS_FUNCTION | 
| 1394       : CALL_AS_METHOD; | 1602       : CALL_AS_METHOD; | 
| 1395   __ InvokeFunction(edi, arguments(), JUMP_FUNCTION, | 1603   __ InvokeFunction(edi, arguments(), JUMP_FUNCTION, | 
| 1396                     NullCallWrapper(), call_kind); | 1604                     NullCallWrapper(), call_kind); | 
| 1397 | 1605 | 
| 1398   // Handle call cache miss. | 1606   // Handle call cache miss. | 
| 1399   __ bind(&miss); | 1607   __ bind(&miss); | 
| 1400   MaybeObject* maybe_result = GenerateMissBranch(); | 1608   GenerateMissBranch(); | 
| 1401   if (maybe_result->IsFailure()) return maybe_result; |  | 
| 1402 | 1609 | 
| 1403   // Return the generated code. | 1610   // Return the generated code. | 
| 1404   return GetCode(FIELD, name); | 1611   return GetCode(FIELD, name); | 
| 1405 } | 1612 } | 
| 1406 | 1613 | 
| 1407 | 1614 | 
| 1408 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, | 1615 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, | 
| 1409                                                     JSObject* holder, | 1616                                                     JSObject* holder, | 
| 1410                                                     JSGlobalPropertyCell* cell, | 1617                                                     JSGlobalPropertyCell* cell, | 
| 1411                                                     JSFunction* function, | 1618                                                     JSFunction* function, | 
| 1412                                                     String* name) { | 1619                                                     String* name) { | 
| 1413   // ----------- S t a t e ------------- | 1620   // ----------- S t a t e ------------- | 
| 1414   //  -- ecx                 : name | 1621   //  -- ecx                 : name | 
| 1415   //  -- esp[0]              : return address | 1622   //  -- esp[0]              : return address | 
| 1416   //  -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1623   //  -- esp[(argc - n) * 4] : arg[n] (zero-based) | 
| 1417   //  -- ... | 1624   //  -- ... | 
| 1418   //  -- esp[(argc + 1) * 4] : receiver | 1625   //  -- esp[(argc + 1) * 4] : receiver | 
| 1419   // ----------------------------------- | 1626   // ----------------------------------- | 
| 1420 | 1627 | 
| 1421   // If object is not an array, bail out to regular call. | 1628   // If object is not an array, bail out to regular call. | 
| 1422   if (!object->IsJSArray() || cell != NULL) { | 1629   if (!object->IsJSArray() || cell != NULL) { | 
| 1423     return isolate()->heap()->undefined_value(); | 1630     return isolate()->heap()->undefined_value(); | 
| 1424   } | 1631   } | 
| 1425 | 1632 | 
| 1426   Label miss; | 1633   Label miss; | 
| 1427 | 1634 | 
| 1428   GenerateNameCheck(name, &miss); | 1635   GenerateNameCheck(Handle<String>(name), &miss); | 
| 1429 | 1636 | 
| 1430   // Get the receiver from the stack. | 1637   // Get the receiver from the stack. | 
| 1431   const int argc = arguments().immediate(); | 1638   const int argc = arguments().immediate(); | 
| 1432   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1639   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 
| 1433 | 1640 | 
| 1434   // Check that the receiver isn't a smi. | 1641   // Check that the receiver isn't a smi. | 
| 1435   __ JumpIfSmi(edx, &miss); | 1642   __ JumpIfSmi(edx, &miss); | 
| 1436 | 1643 | 
| 1437   CheckPrototypes(JSObject::cast(object), edx, | 1644   CheckPrototypes(JSObject::cast(object), edx, | 
| 1438                   holder, ebx, | 1645                   holder, ebx, | 
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1506       __ bind(&attempt_to_grow_elements); | 1713       __ bind(&attempt_to_grow_elements); | 
| 1507       if (!FLAG_inline_new) { | 1714       if (!FLAG_inline_new) { | 
| 1508         __ jmp(&call_builtin); | 1715         __ jmp(&call_builtin); | 
| 1509       } | 1716       } | 
| 1510 | 1717 | 
| 1511       __ mov(edi, Operand(esp, argc * kPointerSize)); | 1718       __ mov(edi, Operand(esp, argc * kPointerSize)); | 
| 1512       // Growing elements that are SMI-only requires special handling in case | 1719       // Growing elements that are SMI-only requires special handling in case | 
| 1513       // the new element is non-Smi. For now, delegate to the builtin. | 1720       // the new element is non-Smi. For now, delegate to the builtin. | 
| 1514       Label no_fast_elements_check; | 1721       Label no_fast_elements_check; | 
| 1515       __ JumpIfSmi(edi, &no_fast_elements_check); | 1722       __ JumpIfSmi(edi, &no_fast_elements_check); | 
| 1516       __ mov(esi, FieldOperand(edx, HeapObject::kMapOffset)); | 1723       __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); | 
| 1517       __ CheckFastObjectElements(esi, &call_builtin, Label::kFar); | 1724       __ CheckFastObjectElements(ecx, &call_builtin, Label::kFar); | 
| 1518       __ bind(&no_fast_elements_check); | 1725       __ bind(&no_fast_elements_check); | 
| 1519 | 1726 | 
| 1520       // We could be lucky and the elements array could be at the top of | 1727       // We could be lucky and the elements array could be at the top of | 
| 1521       // new-space.  In this case we can just grow it in place by moving the | 1728       // new-space.  In this case we can just grow it in place by moving the | 
| 1522       // allocation pointer up. | 1729       // allocation pointer up. | 
| 1523 | 1730 | 
| 1524       ExternalReference new_space_allocation_top = | 1731       ExternalReference new_space_allocation_top = | 
| 1525           ExternalReference::new_space_allocation_top_address(isolate()); | 1732           ExternalReference::new_space_allocation_top_address(isolate()); | 
| 1526       ExternalReference new_space_allocation_limit = | 1733       ExternalReference new_space_allocation_limit = | 
| 1527           ExternalReference::new_space_allocation_limit_address(isolate()); | 1734           ExternalReference::new_space_allocation_limit_address(isolate()); | 
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1575     } | 1782     } | 
| 1576 | 1783 | 
| 1577     __ bind(&call_builtin); | 1784     __ bind(&call_builtin); | 
| 1578     __ TailCallExternalReference( | 1785     __ TailCallExternalReference( | 
| 1579         ExternalReference(Builtins::c_ArrayPush, isolate()), | 1786         ExternalReference(Builtins::c_ArrayPush, isolate()), | 
| 1580         argc + 1, | 1787         argc + 1, | 
| 1581         1); | 1788         1); | 
| 1582   } | 1789   } | 
| 1583 | 1790 | 
| 1584   __ bind(&miss); | 1791   __ bind(&miss); | 
| 1585   MaybeObject* maybe_result = GenerateMissBranch(); | 1792   MaybeObject* maybe_result = TryGenerateMissBranch(); | 
| 1586   if (maybe_result->IsFailure()) return maybe_result; | 1793   if (maybe_result->IsFailure()) return maybe_result; | 
| 1587 | 1794 | 
| 1588   // Return the generated code. | 1795   // Return the generated code. | 
| 1589   return GetCode(function); | 1796   return TryGetCode(function); | 
| 1590 } | 1797 } | 
| 1591 | 1798 | 
| 1592 | 1799 | 
| 1593 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, | 1800 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, | 
| 1594                                                    JSObject* holder, | 1801                                                    JSObject* holder, | 
| 1595                                                    JSGlobalPropertyCell* cell, | 1802                                                    JSGlobalPropertyCell* cell, | 
| 1596                                                    JSFunction* function, | 1803                                                    JSFunction* function, | 
| 1597                                                    String* name) { | 1804                                                    String* name) { | 
| 1598   // ----------- S t a t e ------------- | 1805   // ----------- S t a t e ------------- | 
| 1599   //  -- ecx                 : name | 1806   //  -- ecx                 : name | 
| 1600   //  -- esp[0]              : return address | 1807   //  -- esp[0]              : return address | 
| 1601   //  -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1808   //  -- esp[(argc - n) * 4] : arg[n] (zero-based) | 
| 1602   //  -- ... | 1809   //  -- ... | 
| 1603   //  -- esp[(argc + 1) * 4] : receiver | 1810   //  -- esp[(argc + 1) * 4] : receiver | 
| 1604   // ----------------------------------- | 1811   // ----------------------------------- | 
| 1605 | 1812 | 
| 1606   // If object is not an array, bail out to regular call. | 1813   // If object is not an array, bail out to regular call. | 
| 1607   if (!object->IsJSArray() || cell != NULL) { | 1814   if (!object->IsJSArray() || cell != NULL) { | 
| 1608     return heap()->undefined_value(); | 1815     return heap()->undefined_value(); | 
| 1609   } | 1816   } | 
| 1610 | 1817 | 
| 1611   Label miss, return_undefined, call_builtin; | 1818   Label miss, return_undefined, call_builtin; | 
| 1612 | 1819 | 
| 1613   GenerateNameCheck(name, &miss); | 1820   GenerateNameCheck(Handle<String>(name), &miss); | 
| 1614 | 1821 | 
| 1615   // Get the receiver from the stack. | 1822   // Get the receiver from the stack. | 
| 1616   const int argc = arguments().immediate(); | 1823   const int argc = arguments().immediate(); | 
| 1617   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1824   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 
| 1618 | 1825 | 
| 1619   // Check that the receiver isn't a smi. | 1826   // Check that the receiver isn't a smi. | 
| 1620   __ JumpIfSmi(edx, &miss); | 1827   __ JumpIfSmi(edx, &miss); | 
| 1621   CheckPrototypes(JSObject::cast(object), edx, | 1828   CheckPrototypes(JSObject::cast(object), edx, | 
| 1622                   holder, ebx, | 1829                   holder, ebx, | 
| 1623                   eax, edi, name, &miss); | 1830                   eax, edi, name, &miss); | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1658   __ mov(eax, Immediate(factory()->undefined_value())); | 1865   __ mov(eax, Immediate(factory()->undefined_value())); | 
| 1659   __ ret((argc + 1) * kPointerSize); | 1866   __ ret((argc + 1) * kPointerSize); | 
| 1660 | 1867 | 
| 1661   __ bind(&call_builtin); | 1868   __ bind(&call_builtin); | 
| 1662   __ TailCallExternalReference( | 1869   __ TailCallExternalReference( | 
| 1663       ExternalReference(Builtins::c_ArrayPop, isolate()), | 1870       ExternalReference(Builtins::c_ArrayPop, isolate()), | 
| 1664       argc + 1, | 1871       argc + 1, | 
| 1665       1); | 1872       1); | 
| 1666 | 1873 | 
| 1667   __ bind(&miss); | 1874   __ bind(&miss); | 
| 1668   MaybeObject* maybe_result = GenerateMissBranch(); | 1875   MaybeObject* maybe_result = TryGenerateMissBranch(); | 
| 1669   if (maybe_result->IsFailure()) return maybe_result; | 1876   if (maybe_result->IsFailure()) return maybe_result; | 
| 1670 | 1877 | 
| 1671   // Return the generated code. | 1878   // Return the generated code. | 
| 1672   return GetCode(function); | 1879   return TryGetCode(function); | 
| 1673 } | 1880 } | 
| 1674 | 1881 | 
| 1675 | 1882 | 
| 1676 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( | 1883 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( | 
| 1677     Object* object, | 1884     Object* object, | 
| 1678     JSObject* holder, | 1885     JSObject* holder, | 
| 1679     JSGlobalPropertyCell* cell, | 1886     JSGlobalPropertyCell* cell, | 
| 1680     JSFunction* function, | 1887     JSFunction* function, | 
| 1681     String* name) { | 1888     String* name) { | 
| 1682   // ----------- S t a t e ------------- | 1889   // ----------- S t a t e ------------- | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 1693   } | 1900   } | 
| 1694 | 1901 | 
| 1695   const int argc = arguments().immediate(); | 1902   const int argc = arguments().immediate(); | 
| 1696 | 1903 | 
| 1697   Label miss; | 1904   Label miss; | 
| 1698   Label name_miss; | 1905   Label name_miss; | 
| 1699   Label index_out_of_range; | 1906   Label index_out_of_range; | 
| 1700   Label* index_out_of_range_label = &index_out_of_range; | 1907   Label* index_out_of_range_label = &index_out_of_range; | 
| 1701 | 1908 | 
| 1702   if (kind_ == Code::CALL_IC && | 1909   if (kind_ == Code::CALL_IC && | 
| 1703       (CallICBase::StringStubState::decode(extra_ic_state_) == | 1910       (CallICBase::StringStubState::decode(extra_state_) == | 
| 1704        DEFAULT_STRING_STUB)) { | 1911        DEFAULT_STRING_STUB)) { | 
| 1705     index_out_of_range_label = &miss; | 1912     index_out_of_range_label = &miss; | 
| 1706   } | 1913   } | 
| 1707 | 1914 | 
| 1708   GenerateNameCheck(name, &name_miss); | 1915   GenerateNameCheck(Handle<String>(name), &name_miss); | 
| 1709 | 1916 | 
| 1710   // Check that the maps starting from the prototype haven't changed. | 1917   // Check that the maps starting from the prototype haven't changed. | 
| 1711   GenerateDirectLoadGlobalFunctionPrototype(masm(), | 1918   GenerateDirectLoadGlobalFunctionPrototype(masm(), | 
| 1712                                             Context::STRING_FUNCTION_INDEX, | 1919                                             Context::STRING_FUNCTION_INDEX, | 
| 1713                                             eax, | 1920                                             eax, | 
| 1714                                             &miss); | 1921                                             &miss); | 
| 1715   ASSERT(object != holder); | 1922   ASSERT(object != holder); | 
| 1716   CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, | 1923   CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, | 
| 1717                   ebx, edx, edi, name, &miss); | 1924                   ebx, edx, edi, name, &miss); | 
| 1718 | 1925 | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 1744   if (index_out_of_range.is_linked()) { | 1951   if (index_out_of_range.is_linked()) { | 
| 1745     __ bind(&index_out_of_range); | 1952     __ bind(&index_out_of_range); | 
| 1746     __ Set(eax, Immediate(factory()->nan_value())); | 1953     __ Set(eax, Immediate(factory()->nan_value())); | 
| 1747     __ ret((argc + 1) * kPointerSize); | 1954     __ ret((argc + 1) * kPointerSize); | 
| 1748   } | 1955   } | 
| 1749 | 1956 | 
| 1750   __ bind(&miss); | 1957   __ bind(&miss); | 
| 1751   // Restore function name in ecx. | 1958   // Restore function name in ecx. | 
| 1752   __ Set(ecx, Immediate(Handle<String>(name))); | 1959   __ Set(ecx, Immediate(Handle<String>(name))); | 
| 1753   __ bind(&name_miss); | 1960   __ bind(&name_miss); | 
| 1754   MaybeObject* maybe_result = GenerateMissBranch(); | 1961   MaybeObject* maybe_result = TryGenerateMissBranch(); | 
| 1755   if (maybe_result->IsFailure()) return maybe_result; | 1962   if (maybe_result->IsFailure()) return maybe_result; | 
| 1756 | 1963 | 
| 1757   // Return the generated code. | 1964   // Return the generated code. | 
| 1758   return GetCode(function); | 1965   return TryGetCode(function); | 
| 1759 } | 1966 } | 
| 1760 | 1967 | 
| 1761 | 1968 | 
| 1762 MaybeObject* CallStubCompiler::CompileStringCharAtCall( | 1969 MaybeObject* CallStubCompiler::CompileStringCharAtCall( | 
| 1763     Object* object, | 1970     Object* object, | 
| 1764     JSObject* holder, | 1971     JSObject* holder, | 
| 1765     JSGlobalPropertyCell* cell, | 1972     JSGlobalPropertyCell* cell, | 
| 1766     JSFunction* function, | 1973     JSFunction* function, | 
| 1767     String* name) { | 1974     String* name) { | 
| 1768   // ----------- S t a t e ------------- | 1975   // ----------- S t a t e ------------- | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 1779   } | 1986   } | 
| 1780 | 1987 | 
| 1781   const int argc = arguments().immediate(); | 1988   const int argc = arguments().immediate(); | 
| 1782 | 1989 | 
| 1783   Label miss; | 1990   Label miss; | 
| 1784   Label name_miss; | 1991   Label name_miss; | 
| 1785   Label index_out_of_range; | 1992   Label index_out_of_range; | 
| 1786   Label* index_out_of_range_label = &index_out_of_range; | 1993   Label* index_out_of_range_label = &index_out_of_range; | 
| 1787 | 1994 | 
| 1788   if (kind_ == Code::CALL_IC && | 1995   if (kind_ == Code::CALL_IC && | 
| 1789       (CallICBase::StringStubState::decode(extra_ic_state_) == | 1996       (CallICBase::StringStubState::decode(extra_state_) == | 
| 1790        DEFAULT_STRING_STUB)) { | 1997        DEFAULT_STRING_STUB)) { | 
| 1791     index_out_of_range_label = &miss; | 1998     index_out_of_range_label = &miss; | 
| 1792   } | 1999   } | 
| 1793 | 2000 | 
| 1794   GenerateNameCheck(name, &name_miss); | 2001   GenerateNameCheck(Handle<String>(name), &name_miss); | 
| 1795 | 2002 | 
| 1796   // Check that the maps starting from the prototype haven't changed. | 2003   // Check that the maps starting from the prototype haven't changed. | 
| 1797   GenerateDirectLoadGlobalFunctionPrototype(masm(), | 2004   GenerateDirectLoadGlobalFunctionPrototype(masm(), | 
| 1798                                             Context::STRING_FUNCTION_INDEX, | 2005                                             Context::STRING_FUNCTION_INDEX, | 
| 1799                                             eax, | 2006                                             eax, | 
| 1800                                             &miss); | 2007                                             &miss); | 
| 1801   ASSERT(object != holder); | 2008   ASSERT(object != holder); | 
| 1802   CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, | 2009   CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, | 
| 1803                   ebx, edx, edi, name, &miss); | 2010                   ebx, edx, edi, name, &miss); | 
| 1804 | 2011 | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 1832   if (index_out_of_range.is_linked()) { | 2039   if (index_out_of_range.is_linked()) { | 
| 1833     __ bind(&index_out_of_range); | 2040     __ bind(&index_out_of_range); | 
| 1834     __ Set(eax, Immediate(factory()->empty_string())); | 2041     __ Set(eax, Immediate(factory()->empty_string())); | 
| 1835     __ ret((argc + 1) * kPointerSize); | 2042     __ ret((argc + 1) * kPointerSize); | 
| 1836   } | 2043   } | 
| 1837 | 2044 | 
| 1838   __ bind(&miss); | 2045   __ bind(&miss); | 
| 1839   // Restore function name in ecx. | 2046   // Restore function name in ecx. | 
| 1840   __ Set(ecx, Immediate(Handle<String>(name))); | 2047   __ Set(ecx, Immediate(Handle<String>(name))); | 
| 1841   __ bind(&name_miss); | 2048   __ bind(&name_miss); | 
| 1842   MaybeObject* maybe_result = GenerateMissBranch(); | 2049   MaybeObject* maybe_result = TryGenerateMissBranch(); | 
| 1843   if (maybe_result->IsFailure()) return maybe_result; | 2050   if (maybe_result->IsFailure()) return maybe_result; | 
| 1844 | 2051 | 
| 1845   // Return the generated code. | 2052   // Return the generated code. | 
| 1846   return GetCode(function); | 2053   return TryGetCode(function); | 
| 1847 } | 2054 } | 
| 1848 | 2055 | 
| 1849 | 2056 | 
| 1850 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( | 2057 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( | 
| 1851     Object* object, | 2058     Object* object, | 
| 1852     JSObject* holder, | 2059     JSObject* holder, | 
| 1853     JSGlobalPropertyCell* cell, | 2060     JSGlobalPropertyCell* cell, | 
| 1854     JSFunction* function, | 2061     JSFunction* function, | 
| 1855     String* name) { | 2062     String* name) { | 
| 1856   // ----------- S t a t e ------------- | 2063   // ----------- S t a t e ------------- | 
| 1857   //  -- ecx                 : function name | 2064   //  -- ecx                 : function name | 
| 1858   //  -- esp[0]              : return address | 2065   //  -- esp[0]              : return address | 
| 1859   //  -- esp[(argc - n) * 4] : arg[n] (zero-based) | 2066   //  -- esp[(argc - n) * 4] : arg[n] (zero-based) | 
| 1860   //  -- ... | 2067   //  -- ... | 
| 1861   //  -- esp[(argc + 1) * 4] : receiver | 2068   //  -- esp[(argc + 1) * 4] : receiver | 
| 1862   // ----------------------------------- | 2069   // ----------------------------------- | 
| 1863 | 2070 | 
| 1864   const int argc = arguments().immediate(); | 2071   const int argc = arguments().immediate(); | 
| 1865 | 2072 | 
| 1866   // If the object is not a JSObject or we got an unexpected number of | 2073   // If the object is not a JSObject or we got an unexpected number of | 
| 1867   // arguments, bail out to the regular call. | 2074   // arguments, bail out to the regular call. | 
| 1868   if (!object->IsJSObject() || argc != 1) { | 2075   if (!object->IsJSObject() || argc != 1) { | 
| 1869     return isolate()->heap()->undefined_value(); | 2076     return isolate()->heap()->undefined_value(); | 
| 1870   } | 2077   } | 
| 1871 | 2078 | 
| 1872   Label miss; | 2079   Label miss; | 
| 1873   GenerateNameCheck(name, &miss); | 2080   GenerateNameCheck(Handle<String>(name), &miss); | 
| 1874 | 2081 | 
| 1875   if (cell == NULL) { | 2082   if (cell == NULL) { | 
| 1876     __ mov(edx, Operand(esp, 2 * kPointerSize)); | 2083     __ mov(edx, Operand(esp, 2 * kPointerSize)); | 
| 1877 | 2084 | 
| 1878     STATIC_ASSERT(kSmiTag == 0); | 2085     STATIC_ASSERT(kSmiTag == 0); | 
| 1879     __ JumpIfSmi(edx, &miss); | 2086     __ JumpIfSmi(edx, &miss); | 
| 1880 | 2087 | 
| 1881     CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name, | 2088     CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name, | 
| 1882                     &miss); | 2089                     &miss); | 
| 1883   } else { | 2090   } else { | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 1901   StringCharFromCodeGenerator char_from_code_generator(code, eax); | 2108   StringCharFromCodeGenerator char_from_code_generator(code, eax); | 
| 1902   char_from_code_generator.GenerateFast(masm()); | 2109   char_from_code_generator.GenerateFast(masm()); | 
| 1903   __ ret(2 * kPointerSize); | 2110   __ ret(2 * kPointerSize); | 
| 1904 | 2111 | 
| 1905   StubRuntimeCallHelper call_helper; | 2112   StubRuntimeCallHelper call_helper; | 
| 1906   char_from_code_generator.GenerateSlow(masm(), call_helper); | 2113   char_from_code_generator.GenerateSlow(masm(), call_helper); | 
| 1907 | 2114 | 
| 1908   // Tail call the full function. We do not have to patch the receiver | 2115   // Tail call the full function. We do not have to patch the receiver | 
| 1909   // because the function makes no use of it. | 2116   // because the function makes no use of it. | 
| 1910   __ bind(&slow); | 2117   __ bind(&slow); | 
| 1911   CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 2118   CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 
| 1912       ? CALL_AS_FUNCTION | 2119       ? CALL_AS_FUNCTION | 
| 1913       : CALL_AS_METHOD; | 2120       : CALL_AS_METHOD; | 
| 1914   __ InvokeFunction(function, arguments(), JUMP_FUNCTION, | 2121   __ InvokeFunction(function, arguments(), JUMP_FUNCTION, | 
| 1915                     NullCallWrapper(), call_kind); | 2122                     NullCallWrapper(), call_kind); | 
| 1916 | 2123 | 
| 1917   __ bind(&miss); | 2124   __ bind(&miss); | 
| 1918   // ecx: function name. | 2125   // ecx: function name. | 
| 1919   MaybeObject* maybe_result = GenerateMissBranch(); | 2126   MaybeObject* maybe_result = TryGenerateMissBranch(); | 
| 1920   if (maybe_result->IsFailure()) return maybe_result; | 2127   if (maybe_result->IsFailure()) return maybe_result; | 
| 1921 | 2128 | 
| 1922   // Return the generated code. | 2129   // Return the generated code. | 
| 1923   return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2130   return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); | 
| 1924 } | 2131 } | 
| 1925 | 2132 | 
| 1926 | 2133 | 
| 1927 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, | 2134 MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, | 
| 1928                                                     JSObject* holder, | 2135                                                     JSObject* holder, | 
| 1929                                                     JSGlobalPropertyCell* cell, | 2136                                                     JSGlobalPropertyCell* cell, | 
| 1930                                                     JSFunction* function, | 2137                                                     JSFunction* function, | 
| 1931                                                     String* name) { | 2138                                                     String* name) { | 
| 1932   // ----------- S t a t e ------------- | 2139   // ----------- S t a t e ------------- | 
| 1933   //  -- ecx                 : name | 2140   //  -- ecx                 : name | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 1945 | 2152 | 
| 1946   const int argc = arguments().immediate(); | 2153   const int argc = arguments().immediate(); | 
| 1947 | 2154 | 
| 1948   // If the object is not a JSObject or we got an unexpected number of | 2155   // If the object is not a JSObject or we got an unexpected number of | 
| 1949   // arguments, bail out to the regular call. | 2156   // arguments, bail out to the regular call. | 
| 1950   if (!object->IsJSObject() || argc != 1) { | 2157   if (!object->IsJSObject() || argc != 1) { | 
| 1951     return isolate()->heap()->undefined_value(); | 2158     return isolate()->heap()->undefined_value(); | 
| 1952   } | 2159   } | 
| 1953 | 2160 | 
| 1954   Label miss; | 2161   Label miss; | 
| 1955   GenerateNameCheck(name, &miss); | 2162   GenerateNameCheck(Handle<String>(name), &miss); | 
| 1956 | 2163 | 
| 1957   if (cell == NULL) { | 2164   if (cell == NULL) { | 
| 1958     __ mov(edx, Operand(esp, 2 * kPointerSize)); | 2165     __ mov(edx, Operand(esp, 2 * kPointerSize)); | 
| 1959 | 2166 | 
| 1960     STATIC_ASSERT(kSmiTag == 0); | 2167     STATIC_ASSERT(kSmiTag == 0); | 
| 1961     __ JumpIfSmi(edx, &miss); | 2168     __ JumpIfSmi(edx, &miss); | 
| 1962 | 2169 | 
| 1963     CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name, | 2170     CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name, | 
| 1964                     &miss); | 2171                     &miss); | 
| 1965   } else { | 2172   } else { | 
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2038   __ ret(2 * kPointerSize); | 2245   __ ret(2 * kPointerSize); | 
| 2039 | 2246 | 
| 2040   // Tail call the full function. We do not have to patch the receiver | 2247   // Tail call the full function. We do not have to patch the receiver | 
| 2041   // because the function makes no use of it. | 2248   // because the function makes no use of it. | 
| 2042   __ bind(&slow); | 2249   __ bind(&slow); | 
| 2043   __ InvokeFunction(function, arguments(), JUMP_FUNCTION, | 2250   __ InvokeFunction(function, arguments(), JUMP_FUNCTION, | 
| 2044                     NullCallWrapper(), CALL_AS_METHOD); | 2251                     NullCallWrapper(), CALL_AS_METHOD); | 
| 2045 | 2252 | 
| 2046   __ bind(&miss); | 2253   __ bind(&miss); | 
| 2047   // ecx: function name. | 2254   // ecx: function name. | 
| 2048   MaybeObject* maybe_result = GenerateMissBranch(); | 2255   MaybeObject* maybe_result = TryGenerateMissBranch(); | 
| 2049   if (maybe_result->IsFailure()) return maybe_result; | 2256   if (maybe_result->IsFailure()) return maybe_result; | 
| 2050 | 2257 | 
| 2051   // Return the generated code. | 2258   // Return the generated code. | 
| 2052   return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2259   return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); | 
| 2053 } | 2260 } | 
| 2054 | 2261 | 
| 2055 | 2262 | 
| 2056 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, | 2263 MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, | 
| 2057                                                   JSObject* holder, | 2264                                                   JSObject* holder, | 
| 2058                                                   JSGlobalPropertyCell* cell, | 2265                                                   JSGlobalPropertyCell* cell, | 
| 2059                                                   JSFunction* function, | 2266                                                   JSFunction* function, | 
| 2060                                                   String* name) { | 2267                                                   String* name) { | 
| 2061   // ----------- S t a t e ------------- | 2268   // ----------- S t a t e ------------- | 
| 2062   //  -- ecx                 : name | 2269   //  -- ecx                 : name | 
| 2063   //  -- esp[0]              : return address | 2270   //  -- esp[0]              : return address | 
| 2064   //  -- esp[(argc - n) * 4] : arg[n] (zero-based) | 2271   //  -- esp[(argc - n) * 4] : arg[n] (zero-based) | 
| 2065   //  -- ... | 2272   //  -- ... | 
| 2066   //  -- esp[(argc + 1) * 4] : receiver | 2273   //  -- esp[(argc + 1) * 4] : receiver | 
| 2067   // ----------------------------------- | 2274   // ----------------------------------- | 
| 2068 | 2275 | 
| 2069   const int argc = arguments().immediate(); | 2276   const int argc = arguments().immediate(); | 
| 2070 | 2277 | 
| 2071   // If the object is not a JSObject or we got an unexpected number of | 2278   // If the object is not a JSObject or we got an unexpected number of | 
| 2072   // arguments, bail out to the regular call. | 2279   // arguments, bail out to the regular call. | 
| 2073   if (!object->IsJSObject() || argc != 1) { | 2280   if (!object->IsJSObject() || argc != 1) { | 
| 2074     return isolate()->heap()->undefined_value(); | 2281     return isolate()->heap()->undefined_value(); | 
| 2075   } | 2282   } | 
| 2076 | 2283 | 
| 2077   Label miss; | 2284   Label miss; | 
| 2078   GenerateNameCheck(name, &miss); | 2285   GenerateNameCheck(Handle<String>(name), &miss); | 
| 2079 | 2286 | 
| 2080   if (cell == NULL) { | 2287   if (cell == NULL) { | 
| 2081     __ mov(edx, Operand(esp, 2 * kPointerSize)); | 2288     __ mov(edx, Operand(esp, 2 * kPointerSize)); | 
| 2082 | 2289 | 
| 2083     STATIC_ASSERT(kSmiTag == 0); | 2290     STATIC_ASSERT(kSmiTag == 0); | 
| 2084     __ JumpIfSmi(edx, &miss); | 2291     __ JumpIfSmi(edx, &miss); | 
| 2085 | 2292 | 
| 2086     CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name, | 2293     CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name, | 
| 2087                     &miss); | 2294                     &miss); | 
| 2088   } else { | 2295   } else { | 
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2142   __ ret(2 * kPointerSize); | 2349   __ ret(2 * kPointerSize); | 
| 2143 | 2350 | 
| 2144   // Tail call the full function. We do not have to patch the receiver | 2351   // Tail call the full function. We do not have to patch the receiver | 
| 2145   // because the function makes no use of it. | 2352   // because the function makes no use of it. | 
| 2146   __ bind(&slow); | 2353   __ bind(&slow); | 
| 2147   __ InvokeFunction(function, arguments(), JUMP_FUNCTION, | 2354   __ InvokeFunction(function, arguments(), JUMP_FUNCTION, | 
| 2148                     NullCallWrapper(), CALL_AS_METHOD); | 2355                     NullCallWrapper(), CALL_AS_METHOD); | 
| 2149 | 2356 | 
| 2150   __ bind(&miss); | 2357   __ bind(&miss); | 
| 2151   // ecx: function name. | 2358   // ecx: function name. | 
| 2152   MaybeObject* maybe_result = GenerateMissBranch(); | 2359   MaybeObject* maybe_result = TryGenerateMissBranch(); | 
| 2153   if (maybe_result->IsFailure()) return maybe_result; | 2360   if (maybe_result->IsFailure()) return maybe_result; | 
| 2154 | 2361 | 
| 2155   // Return the generated code. | 2362   // Return the generated code. | 
| 2156   return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2363   return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); | 
| 2157 } | 2364 } | 
| 2158 | 2365 | 
| 2159 | 2366 | 
| 2160 MaybeObject* CallStubCompiler::CompileFastApiCall( | 2367 MaybeObject* CallStubCompiler::CompileFastApiCall( | 
| 2161     const CallOptimization& optimization, | 2368     const CallOptimization& optimization, | 
| 2162     Object* object, | 2369     Object* object, | 
| 2163     JSObject* holder, | 2370     JSObject* holder, | 
| 2164     JSGlobalPropertyCell* cell, | 2371     JSGlobalPropertyCell* cell, | 
| 2165     JSFunction* function, | 2372     JSFunction* function, | 
| 2166     String* name) { | 2373     String* name) { | 
| 2167   ASSERT(optimization.is_simple_api_call()); | 2374   ASSERT(optimization.is_simple_api_call()); | 
| 2168   // Bail out if object is a global object as we don't want to | 2375   // Bail out if object is a global object as we don't want to | 
| 2169   // repatch it to global receiver. | 2376   // repatch it to global receiver. | 
| 2170   if (object->IsGlobalObject()) return heap()->undefined_value(); | 2377   if (object->IsGlobalObject()) return heap()->undefined_value(); | 
| 2171   if (cell != NULL) return heap()->undefined_value(); | 2378   if (cell != NULL) return heap()->undefined_value(); | 
| 2172   if (!object->IsJSObject()) return heap()->undefined_value(); | 2379   if (!object->IsJSObject()) return heap()->undefined_value(); | 
| 2173   int depth = optimization.GetPrototypeDepthOfExpectedType( | 2380   int depth = optimization.GetPrototypeDepthOfExpectedType( | 
| 2174             JSObject::cast(object), holder); | 2381             JSObject::cast(object), holder); | 
| 2175   if (depth == kInvalidProtoDepth) return heap()->undefined_value(); | 2382   if (depth == kInvalidProtoDepth) return heap()->undefined_value(); | 
| 2176 | 2383 | 
| 2177   Label miss, miss_before_stack_reserved; | 2384   Label miss, miss_before_stack_reserved; | 
| 2178 | 2385 | 
| 2179   GenerateNameCheck(name, &miss_before_stack_reserved); | 2386   GenerateNameCheck(Handle<String>(name), &miss_before_stack_reserved); | 
| 2180 | 2387 | 
| 2181   // Get the receiver from the stack. | 2388   // Get the receiver from the stack. | 
| 2182   const int argc = arguments().immediate(); | 2389   const int argc = arguments().immediate(); | 
| 2183   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 2390   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 
| 2184 | 2391 | 
| 2185   // Check that the receiver isn't a smi. | 2392   // Check that the receiver isn't a smi. | 
| 2186   __ JumpIfSmi(edx, &miss_before_stack_reserved); | 2393   __ JumpIfSmi(edx, &miss_before_stack_reserved); | 
| 2187 | 2394 | 
| 2188   Counters* counters = isolate()->counters(); | 2395   Counters* counters = isolate()->counters(); | 
| 2189   __ IncrementCounter(counters->call_const(), 1); | 2396   __ IncrementCounter(counters->call_const(), 1); | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 2203 | 2410 | 
| 2204   // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains | 2411   // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains | 
| 2205   // duplicate of return address and will be overwritten. | 2412   // duplicate of return address and will be overwritten. | 
| 2206   MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc); | 2413   MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc); | 
| 2207   if (result->IsFailure()) return result; | 2414   if (result->IsFailure()) return result; | 
| 2208 | 2415 | 
| 2209   __ bind(&miss); | 2416   __ bind(&miss); | 
| 2210   __ add(esp, Immediate(kFastApiCallArguments * kPointerSize)); | 2417   __ add(esp, Immediate(kFastApiCallArguments * kPointerSize)); | 
| 2211 | 2418 | 
| 2212   __ bind(&miss_before_stack_reserved); | 2419   __ bind(&miss_before_stack_reserved); | 
| 2213   MaybeObject* maybe_result = GenerateMissBranch(); | 2420   MaybeObject* maybe_result = TryGenerateMissBranch(); | 
| 2214   if (maybe_result->IsFailure()) return maybe_result; | 2421   if (maybe_result->IsFailure()) return maybe_result; | 
| 2215 | 2422 | 
| 2216   // Return the generated code. | 2423   // Return the generated code. | 
| 2217   return GetCode(function); | 2424   return TryGetCode(function); | 
| 2218 } | 2425 } | 
| 2219 | 2426 | 
| 2220 | 2427 | 
| 2221 MaybeObject* CallStubCompiler::CompileCallConstant( | 2428 MaybeObject* CallStubCompiler::CompileCallConstant( | 
| 2222     Object* object, | 2429     Object* object, | 
| 2223     JSObject* holder, | 2430     JSObject* holder, | 
| 2224     JSFunction* function, | 2431     JSFunction* function, | 
| 2225     String* name, | 2432     String* name, | 
| 2226     CheckType check) { | 2433     CheckType check) { | 
| 2227   // ----------- S t a t e ------------- | 2434   // ----------- S t a t e ------------- | 
| 2228   //  -- ecx                 : name | 2435   //  -- ecx                 : name | 
| 2229   //  -- esp[0]              : return address | 2436   //  -- esp[0]              : return address | 
| 2230   //  -- esp[(argc - n) * 4] : arg[n] (zero-based) | 2437   //  -- esp[(argc - n) * 4] : arg[n] (zero-based) | 
| 2231   //  -- ... | 2438   //  -- ... | 
| 2232   //  -- esp[(argc + 1) * 4] : receiver | 2439   //  -- esp[(argc + 1) * 4] : receiver | 
| 2233   // ----------------------------------- | 2440   // ----------------------------------- | 
| 2234 | 2441 | 
| 2235   if (HasCustomCallGenerator(function)) { | 2442   if (HasCustomCallGenerator(function)) { | 
| 2236     MaybeObject* maybe_result = CompileCustomCall( | 2443     MaybeObject* maybe_result = CompileCustomCall( | 
| 2237         object, holder, NULL, function, name); | 2444         object, holder, NULL, function, name); | 
| 2238     Object* result; | 2445     Object* result; | 
| 2239     if (!maybe_result->ToObject(&result)) return maybe_result; | 2446     if (!maybe_result->ToObject(&result)) return maybe_result; | 
| 2240     // undefined means bail out to regular compiler. | 2447     // undefined means bail out to regular compiler. | 
| 2241     if (!result->IsUndefined()) return result; | 2448     if (!result->IsUndefined()) return result; | 
| 2242   } | 2449   } | 
| 2243 | 2450 | 
| 2244   Label miss; | 2451   Label miss; | 
| 2245 | 2452 | 
| 2246   GenerateNameCheck(name, &miss); | 2453   GenerateNameCheck(Handle<String>(name), &miss); | 
| 2247 | 2454 | 
| 2248   // Get the receiver from the stack. | 2455   // Get the receiver from the stack. | 
| 2249   const int argc = arguments().immediate(); | 2456   const int argc = arguments().immediate(); | 
| 2250   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 2457   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 
| 2251 | 2458 | 
| 2252   // Check that the receiver isn't a smi. | 2459   // Check that the receiver isn't a smi. | 
| 2253   if (check != NUMBER_CHECK) { | 2460   if (check != NUMBER_CHECK) { | 
| 2254     __ JumpIfSmi(edx, &miss); | 2461     __ JumpIfSmi(edx, &miss); | 
| 2255   } | 2462   } | 
| 2256 | 2463 | 
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2332         CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, | 2539         CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, | 
| 2333                         ebx, edx, edi, name, &miss); | 2540                         ebx, edx, edi, name, &miss); | 
| 2334       } | 2541       } | 
| 2335       break; | 2542       break; | 
| 2336     } | 2543     } | 
| 2337 | 2544 | 
| 2338     default: | 2545     default: | 
| 2339       UNREACHABLE(); | 2546       UNREACHABLE(); | 
| 2340   } | 2547   } | 
| 2341 | 2548 | 
| 2342   CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 2549   CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 
| 2343       ? CALL_AS_FUNCTION | 2550       ? CALL_AS_FUNCTION | 
| 2344       : CALL_AS_METHOD; | 2551       : CALL_AS_METHOD; | 
| 2345   __ InvokeFunction(function, arguments(), JUMP_FUNCTION, | 2552   __ InvokeFunction(function, arguments(), JUMP_FUNCTION, | 
| 2346                     NullCallWrapper(), call_kind); | 2553                     NullCallWrapper(), call_kind); | 
| 2347 | 2554 | 
| 2348   // Handle call cache miss. | 2555   // Handle call cache miss. | 
| 2349   __ bind(&miss); | 2556   __ bind(&miss); | 
| 2350   MaybeObject* maybe_result = GenerateMissBranch(); | 2557   MaybeObject* maybe_result = TryGenerateMissBranch(); | 
| 2351   if (maybe_result->IsFailure()) return maybe_result; | 2558   if (maybe_result->IsFailure()) return maybe_result; | 
| 2352 | 2559 | 
| 2353   // Return the generated code. | 2560   // Return the generated code. | 
| 2354   return GetCode(function); | 2561   return TryGetCode(function); | 
| 2355 } | 2562 } | 
| 2356 | 2563 | 
| 2357 | 2564 | 
| 2358 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, | 2565 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, | 
| 2359                                                       JSObject* holder, | 2566                                                       JSObject* holder, | 
| 2360                                                       String* name) { | 2567                                                       String* name) { | 
| 2361   // ----------- S t a t e ------------- | 2568   // ----------- S t a t e ------------- | 
| 2362   //  -- ecx                 : name | 2569   //  -- ecx                 : name | 
| 2363   //  -- esp[0]              : return address | 2570   //  -- esp[0]              : return address | 
| 2364   //  -- esp[(argc - n) * 4] : arg[n] (zero-based) | 2571   //  -- esp[(argc - n) * 4] : arg[n] (zero-based) | 
| 2365   //  -- ... | 2572   //  -- ... | 
| 2366   //  -- esp[(argc + 1) * 4] : receiver | 2573   //  -- esp[(argc + 1) * 4] : receiver | 
| 2367   // ----------------------------------- | 2574   // ----------------------------------- | 
| 2368   Label miss; | 2575   Label miss; | 
| 2369 | 2576 | 
| 2370   GenerateNameCheck(name, &miss); | 2577   GenerateNameCheck(Handle<String>(name), &miss); | 
| 2371 | 2578 | 
| 2372   // Get the number of arguments. | 2579   // Get the number of arguments. | 
| 2373   const int argc = arguments().immediate(); | 2580   const int argc = arguments().immediate(); | 
| 2374 | 2581 | 
| 2375   LookupResult lookup; | 2582   LookupResult lookup(isolate()); | 
| 2376   LookupPostInterceptor(holder, name, &lookup); | 2583   LookupPostInterceptor(holder, name, &lookup); | 
| 2377 | 2584 | 
| 2378   // Get the receiver from the stack. | 2585   // Get the receiver from the stack. | 
| 2379   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 2586   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 
| 2380 | 2587 | 
| 2381   CallInterceptorCompiler compiler(this, arguments(), ecx, extra_ic_state_); | 2588   CallInterceptorCompiler compiler(this, arguments(), ecx, extra_state_); | 
| 2382   MaybeObject* result = compiler.Compile(masm(), | 2589   MaybeObject* result = compiler.Compile(masm(), | 
| 2383                                          object, | 2590                                          object, | 
| 2384                                          holder, | 2591                                          holder, | 
| 2385                                          name, | 2592                                          name, | 
| 2386                                          &lookup, | 2593                                          &lookup, | 
| 2387                                          edx, | 2594                                          edx, | 
| 2388                                          ebx, | 2595                                          ebx, | 
| 2389                                          edi, | 2596                                          edi, | 
| 2390                                          eax, | 2597                                          eax, | 
| 2391                                          &miss); | 2598                                          &miss); | 
| 2392   if (result->IsFailure()) return result; | 2599   if (result->IsFailure()) return result; | 
| 2393 | 2600 | 
| 2394   // Restore receiver. | 2601   // Restore receiver. | 
| 2395   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 2602   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 
| 2396 | 2603 | 
| 2397   // Check that the function really is a function. | 2604   // Check that the function really is a function. | 
| 2398   __ JumpIfSmi(eax, &miss); | 2605   __ JumpIfSmi(eax, &miss); | 
| 2399   __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx); | 2606   __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx); | 
| 2400   __ j(not_equal, &miss); | 2607   __ j(not_equal, &miss); | 
| 2401 | 2608 | 
| 2402   // Patch the receiver on the stack with the global proxy if | 2609   // Patch the receiver on the stack with the global proxy if | 
| 2403   // necessary. | 2610   // necessary. | 
| 2404   if (object->IsGlobalObject()) { | 2611   if (object->IsGlobalObject()) { | 
| 2405     __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 2612     __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 
| 2406     __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 2613     __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 
| 2407   } | 2614   } | 
| 2408 | 2615 | 
| 2409   // Invoke the function. | 2616   // Invoke the function. | 
| 2410   __ mov(edi, eax); | 2617   __ mov(edi, eax); | 
| 2411   CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 2618   CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 
| 2412       ? CALL_AS_FUNCTION | 2619       ? CALL_AS_FUNCTION | 
| 2413       : CALL_AS_METHOD; | 2620       : CALL_AS_METHOD; | 
| 2414   __ InvokeFunction(edi, arguments(), JUMP_FUNCTION, | 2621   __ InvokeFunction(edi, arguments(), JUMP_FUNCTION, | 
| 2415                     NullCallWrapper(), call_kind); | 2622                     NullCallWrapper(), call_kind); | 
| 2416 | 2623 | 
| 2417   // Handle load cache miss. | 2624   // Handle load cache miss. | 
| 2418   __ bind(&miss); | 2625   __ bind(&miss); | 
| 2419   MaybeObject* maybe_result = GenerateMissBranch(); | 2626   MaybeObject* maybe_result = TryGenerateMissBranch(); | 
| 2420   if (maybe_result->IsFailure()) return maybe_result; | 2627   if (maybe_result->IsFailure()) return maybe_result; | 
| 2421 | 2628 | 
| 2422   // Return the generated code. | 2629   // Return the generated code. | 
| 2423   return GetCode(INTERCEPTOR, name); | 2630   return TryGetCode(INTERCEPTOR, name); | 
| 2424 } | 2631 } | 
| 2425 | 2632 | 
| 2426 | 2633 | 
| 2427 MaybeObject* CallStubCompiler::CompileCallGlobal( | 2634 MaybeObject* CallStubCompiler::CompileCallGlobal( | 
| 2428     JSObject* object, | 2635     JSObject* object, | 
| 2429     GlobalObject* holder, | 2636     GlobalObject* holder, | 
| 2430     JSGlobalPropertyCell* cell, | 2637     JSGlobalPropertyCell* cell, | 
| 2431     JSFunction* function, | 2638     JSFunction* function, | 
| 2432     String* name) { | 2639     String* name) { | 
| 2433   // ----------- S t a t e ------------- | 2640   // ----------- S t a t e ------------- | 
| 2434   //  -- ecx                 : name | 2641   //  -- ecx                 : name | 
| 2435   //  -- esp[0]              : return address | 2642   //  -- esp[0]              : return address | 
| 2436   //  -- esp[(argc - n) * 4] : arg[n] (zero-based) | 2643   //  -- esp[(argc - n) * 4] : arg[n] (zero-based) | 
| 2437   //  -- ... | 2644   //  -- ... | 
| 2438   //  -- esp[(argc + 1) * 4] : receiver | 2645   //  -- esp[(argc + 1) * 4] : receiver | 
| 2439   // ----------------------------------- | 2646   // ----------------------------------- | 
| 2440 | 2647 | 
| 2441   if (HasCustomCallGenerator(function)) { | 2648   if (HasCustomCallGenerator(function)) { | 
| 2442     MaybeObject* maybe_result = CompileCustomCall( | 2649     MaybeObject* maybe_result = CompileCustomCall( | 
| 2443         object, holder, cell, function, name); | 2650         object, holder, cell, function, name); | 
| 2444     Object* result; | 2651     Object* result; | 
| 2445     if (!maybe_result->ToObject(&result)) return maybe_result; | 2652     if (!maybe_result->ToObject(&result)) return maybe_result; | 
| 2446     // undefined means bail out to regular compiler. | 2653     // undefined means bail out to regular compiler. | 
| 2447     if (!result->IsUndefined()) return result; | 2654     if (!result->IsUndefined()) return result; | 
| 2448   } | 2655   } | 
| 2449 | 2656 | 
| 2450   Label miss; | 2657   Label miss; | 
| 2451 | 2658 | 
| 2452   GenerateNameCheck(name, &miss); | 2659   GenerateNameCheck(Handle<String>(name), &miss); | 
| 2453 | 2660 | 
| 2454   // Get the number of arguments. | 2661   // Get the number of arguments. | 
| 2455   const int argc = arguments().immediate(); | 2662   const int argc = arguments().immediate(); | 
| 2456 | 2663 | 
| 2457   GenerateGlobalReceiverCheck(object, holder, name, &miss); | 2664   GenerateGlobalReceiverCheck(object, holder, name, &miss); | 
| 2458 | 2665 | 
| 2459   GenerateLoadFunctionFromCell(cell, function, &miss); | 2666   GenerateLoadFunctionFromCell(cell, function, &miss); | 
| 2460 | 2667 | 
| 2461   // Patch the receiver on the stack with the global proxy. | 2668   // Patch the receiver on the stack with the global proxy. | 
| 2462   if (object->IsGlobalObject()) { | 2669   if (object->IsGlobalObject()) { | 
| 2463     __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 2670     __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 
| 2464     __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 2671     __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 
| 2465   } | 2672   } | 
| 2466 | 2673 | 
| 2467   // Setup the context (function already in edi). | 2674   // Setup the context (function already in edi). | 
| 2468   __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 2675   __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 
| 2469 | 2676 | 
| 2470   // Jump to the cached code (tail call). | 2677   // Jump to the cached code (tail call). | 
| 2471   Counters* counters = isolate()->counters(); | 2678   Counters* counters = isolate()->counters(); | 
| 2472   __ IncrementCounter(counters->call_global_inline(), 1); | 2679   __ IncrementCounter(counters->call_global_inline(), 1); | 
| 2473   ASSERT(function->is_compiled()); |  | 
| 2474   ParameterCount expected(function->shared()->formal_parameter_count()); | 2680   ParameterCount expected(function->shared()->formal_parameter_count()); | 
| 2475   CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 2681   CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 
| 2476       ? CALL_AS_FUNCTION | 2682       ? CALL_AS_FUNCTION | 
| 2477       : CALL_AS_METHOD; | 2683       : CALL_AS_METHOD; | 
| 2478   if (V8::UseCrankshaft()) { | 2684   // We call indirectly through the code field in the function to | 
| 2479     // TODO(kasperl): For now, we always call indirectly through the | 2685   // allow recompilation to take effect without changing any of the | 
| 2480     // code field in the function to allow recompilation to take effect | 2686   // call sites. | 
| 2481     // without changing any of the call sites. | 2687   __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), | 
| 2482     __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), | 2688                 expected, arguments(), JUMP_FUNCTION, | 
| 2483                   expected, arguments(), JUMP_FUNCTION, | 2689                 NullCallWrapper(), call_kind); | 
| 2484                   NullCallWrapper(), call_kind); |  | 
| 2485   } else { |  | 
| 2486     Handle<Code> code(function->code()); |  | 
| 2487     __ InvokeCode(code, expected, arguments(), |  | 
| 2488                   RelocInfo::CODE_TARGET, JUMP_FUNCTION, |  | 
| 2489                   NullCallWrapper(), call_kind); |  | 
| 2490   } |  | 
| 2491 | 2690 | 
| 2492   // Handle call cache miss. | 2691   // Handle call cache miss. | 
| 2493   __ bind(&miss); | 2692   __ bind(&miss); | 
| 2494   __ IncrementCounter(counters->call_global_inline_miss(), 1); | 2693   __ IncrementCounter(counters->call_global_inline_miss(), 1); | 
| 2495   MaybeObject* maybe_result = GenerateMissBranch(); | 2694   MaybeObject* maybe_result = TryGenerateMissBranch(); | 
| 2496   if (maybe_result->IsFailure()) return maybe_result; | 2695   if (maybe_result->IsFailure()) return maybe_result; | 
| 2497 | 2696 | 
| 2498   // Return the generated code. | 2697   // Return the generated code. | 
| 2499   return GetCode(NORMAL, name); | 2698   return TryGetCode(NORMAL, name); | 
| 2500 } | 2699 } | 
| 2501 | 2700 | 
| 2502 | 2701 | 
| 2503 MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object, | 2702 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, | 
| 2504                                                   int index, | 2703                                                   int index, | 
| 2505                                                   Map* transition, | 2704                                                   Handle<Map> transition, | 
| 2506                                                   String* name) { | 2705                                                   Handle<String> name) { | 
| 2507   // ----------- S t a t e ------------- | 2706   // ----------- S t a t e ------------- | 
| 2508   //  -- eax    : value | 2707   //  -- eax    : value | 
| 2509   //  -- ecx    : name | 2708   //  -- ecx    : name | 
| 2510   //  -- edx    : receiver | 2709   //  -- edx    : receiver | 
| 2511   //  -- esp[0] : return address | 2710   //  -- esp[0] : return address | 
| 2512   // ----------------------------------- | 2711   // ----------------------------------- | 
| 2513   Label miss; | 2712   Label miss; | 
| 2514 | 2713 | 
| 2515   // Generate store field code.  Trashes the name register. | 2714   // Generate store field code.  Trashes the name register. | 
| 2516   GenerateStoreField(masm(), | 2715   GenerateStoreField(masm(), object, index, transition, edx, ecx, ebx, &miss); | 
| 2517                      object, |  | 
| 2518                      index, |  | 
| 2519                      transition, |  | 
| 2520                      edx, ecx, ebx, |  | 
| 2521                      &miss); |  | 
| 2522 | 2716 | 
| 2523   // Handle store cache miss. | 2717   // Handle store cache miss. | 
| 2524   __ bind(&miss); | 2718   __ bind(&miss); | 
| 2525   __ mov(ecx, Immediate(Handle<String>(name)));  // restore name | 2719   __ mov(ecx, Immediate(name));  // restore name | 
| 2526   Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); | 2720   Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); | 
| 2527   __ jmp(ic, RelocInfo::CODE_TARGET); | 2721   __ jmp(ic, RelocInfo::CODE_TARGET); | 
| 2528 | 2722 | 
| 2529   // Return the generated code. | 2723   // Return the generated code. | 
| 2530   return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 2724   return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name); | 
| 2531 } | 2725 } | 
| 2532 | 2726 | 
| 2533 | 2727 | 
| 2534 MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object, | 2728 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 
| 2535                                                      AccessorInfo* callback, | 2729     Handle<JSObject> object, | 
| 2536                                                      String* name) { | 2730     Handle<AccessorInfo> callback, | 
|  | 2731     Handle<String> name) { | 
| 2537   // ----------- S t a t e ------------- | 2732   // ----------- S t a t e ------------- | 
| 2538   //  -- eax    : value | 2733   //  -- eax    : value | 
| 2539   //  -- ecx    : name | 2734   //  -- ecx    : name | 
| 2540   //  -- edx    : receiver | 2735   //  -- edx    : receiver | 
| 2541   //  -- esp[0] : return address | 2736   //  -- esp[0] : return address | 
| 2542   // ----------------------------------- | 2737   // ----------------------------------- | 
| 2543   Label miss; | 2738   Label miss; | 
| 2544 | 2739 | 
| 2545   // Check that the object isn't a smi. | 2740   // Check that the object isn't a smi. | 
| 2546   __ JumpIfSmi(edx, &miss); | 2741   __ JumpIfSmi(edx, &miss); | 
| 2547 | 2742 | 
| 2548   // Check that the map of the object hasn't changed. | 2743   // Check that the map of the object hasn't changed. | 
| 2549   __ cmp(FieldOperand(edx, HeapObject::kMapOffset), | 2744   __ cmp(FieldOperand(edx, HeapObject::kMapOffset), | 
| 2550          Immediate(Handle<Map>(object->map()))); | 2745          Immediate(Handle<Map>(object->map()))); | 
| 2551   __ j(not_equal, &miss); | 2746   __ j(not_equal, &miss); | 
| 2552 | 2747 | 
| 2553   // Perform global security token check if needed. | 2748   // Perform global security token check if needed. | 
| 2554   if (object->IsJSGlobalProxy()) { | 2749   if (object->IsJSGlobalProxy()) { | 
| 2555     __ CheckAccessGlobalProxy(edx, ebx, &miss); | 2750     __ CheckAccessGlobalProxy(edx, ebx, &miss); | 
| 2556   } | 2751   } | 
| 2557 | 2752 | 
| 2558   // Stub never generated for non-global objects that require access | 2753   // Stub never generated for non-global objects that require access | 
| 2559   // checks. | 2754   // checks. | 
| 2560   ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 2755   ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 
| 2561 | 2756 | 
| 2562   __ pop(ebx);  // remove the return address | 2757   __ pop(ebx);  // remove the return address | 
| 2563   __ push(edx);  // receiver | 2758   __ push(edx);  // receiver | 
| 2564   __ push(Immediate(Handle<AccessorInfo>(callback)));  // callback info | 2759   __ push(Immediate(callback));  // callback info | 
| 2565   __ push(ecx);  // name | 2760   __ push(ecx);  // name | 
| 2566   __ push(eax);  // value | 2761   __ push(eax);  // value | 
| 2567   __ push(ebx);  // restore return address | 2762   __ push(ebx);  // restore return address | 
| 2568 | 2763 | 
| 2569   // Do tail-call to the runtime system. | 2764   // Do tail-call to the runtime system. | 
| 2570   ExternalReference store_callback_property = | 2765   ExternalReference store_callback_property = | 
| 2571       ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); | 2766       ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); | 
| 2572   __ TailCallExternalReference(store_callback_property, 4, 1); | 2767   __ TailCallExternalReference(store_callback_property, 4, 1); | 
| 2573 | 2768 | 
| 2574   // Handle store cache miss. | 2769   // Handle store cache miss. | 
| 2575   __ bind(&miss); | 2770   __ bind(&miss); | 
| 2576   Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); | 2771   Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); | 
| 2577   __ jmp(ic, RelocInfo::CODE_TARGET); | 2772   __ jmp(ic, RelocInfo::CODE_TARGET); | 
| 2578 | 2773 | 
| 2579   // Return the generated code. | 2774   // Return the generated code. | 
| 2580   return GetCode(CALLBACKS, name); | 2775   return GetCode(CALLBACKS, name); | 
| 2581 } | 2776 } | 
| 2582 | 2777 | 
| 2583 | 2778 | 
| 2584 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, | 2779 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( | 
| 2585                                                         String* name) { | 2780     Handle<JSObject> receiver, | 
|  | 2781     Handle<String> name) { | 
| 2586   // ----------- S t a t e ------------- | 2782   // ----------- S t a t e ------------- | 
| 2587   //  -- eax    : value | 2783   //  -- eax    : value | 
| 2588   //  -- ecx    : name | 2784   //  -- ecx    : name | 
| 2589   //  -- edx    : receiver | 2785   //  -- edx    : receiver | 
| 2590   //  -- esp[0] : return address | 2786   //  -- esp[0] : return address | 
| 2591   // ----------------------------------- | 2787   // ----------------------------------- | 
| 2592   Label miss; | 2788   Label miss; | 
| 2593 | 2789 | 
| 2594   // Check that the object isn't a smi. | 2790   // Check that the object isn't a smi. | 
| 2595   __ JumpIfSmi(edx, &miss); | 2791   __ JumpIfSmi(edx, &miss); | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 2623   // Handle store cache miss. | 2819   // Handle store cache miss. | 
| 2624   __ bind(&miss); | 2820   __ bind(&miss); | 
| 2625   Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); | 2821   Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); | 
| 2626   __ jmp(ic, RelocInfo::CODE_TARGET); | 2822   __ jmp(ic, RelocInfo::CODE_TARGET); | 
| 2627 | 2823 | 
| 2628   // Return the generated code. | 2824   // Return the generated code. | 
| 2629   return GetCode(INTERCEPTOR, name); | 2825   return GetCode(INTERCEPTOR, name); | 
| 2630 } | 2826 } | 
| 2631 | 2827 | 
| 2632 | 2828 | 
| 2633 MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object, | 2829 Handle<Code> StoreStubCompiler::CompileStoreGlobal( | 
| 2634                                                    JSGlobalPropertyCell* cell, | 2830     Handle<GlobalObject> object, | 
| 2635                                                    String* name) { | 2831     Handle<JSGlobalPropertyCell> cell, | 
|  | 2832     Handle<String> name) { | 
| 2636   // ----------- S t a t e ------------- | 2833   // ----------- S t a t e ------------- | 
| 2637   //  -- eax    : value | 2834   //  -- eax    : value | 
| 2638   //  -- ecx    : name | 2835   //  -- ecx    : name | 
| 2639   //  -- edx    : receiver | 2836   //  -- edx    : receiver | 
| 2640   //  -- esp[0] : return address | 2837   //  -- esp[0] : return address | 
| 2641   // ----------------------------------- | 2838   // ----------------------------------- | 
| 2642   Label miss; | 2839   Label miss; | 
| 2643 | 2840 | 
| 2644   // Check that the map of the global has not changed. | 2841   // Check that the map of the global has not changed. | 
| 2645   __ cmp(FieldOperand(edx, HeapObject::kMapOffset), | 2842   __ cmp(FieldOperand(edx, HeapObject::kMapOffset), | 
| 2646          Immediate(Handle<Map>(object->map()))); | 2843          Immediate(Handle<Map>(object->map()))); | 
| 2647   __ j(not_equal, &miss); | 2844   __ j(not_equal, &miss); | 
| 2648 | 2845 | 
| 2649   // Compute the cell operand to use. | 2846   // Compute the cell operand to use. | 
| 2650   __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell))); | 2847   __ mov(ebx, Immediate(cell)); | 
| 2651   Operand cell_operand = FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset); | 2848   Operand cell_operand = FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset); | 
| 2652 | 2849 | 
| 2653   // Check that the value in the cell is not the hole. If it is, this | 2850   // Check that the value in the cell is not the hole. If it is, this | 
| 2654   // cell could have been deleted and reintroducing the global needs | 2851   // cell could have been deleted and reintroducing the global needs | 
| 2655   // to update the property details in the property dictionary of the | 2852   // to update the property details in the property dictionary of the | 
| 2656   // global object. We bail out to the runtime system to do that. | 2853   // global object. We bail out to the runtime system to do that. | 
| 2657   __ cmp(cell_operand, factory()->the_hole_value()); | 2854   __ cmp(cell_operand, factory()->the_hole_value()); | 
| 2658   __ j(equal, &miss); | 2855   __ j(equal, &miss); | 
| 2659 | 2856 | 
| 2660   // Store the value in the cell. | 2857   // Store the value in the cell. | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 2684   __ bind(&miss); | 2881   __ bind(&miss); | 
| 2685   __ IncrementCounter(counters->named_store_global_inline_miss(), 1); | 2882   __ IncrementCounter(counters->named_store_global_inline_miss(), 1); | 
| 2686   Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); | 2883   Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); | 
| 2687   __ jmp(ic, RelocInfo::CODE_TARGET); | 2884   __ jmp(ic, RelocInfo::CODE_TARGET); | 
| 2688 | 2885 | 
| 2689   // Return the generated code. | 2886   // Return the generated code. | 
| 2690   return GetCode(NORMAL, name); | 2887   return GetCode(NORMAL, name); | 
| 2691 } | 2888 } | 
| 2692 | 2889 | 
| 2693 | 2890 | 
| 2694 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, | 2891 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object, | 
| 2695                                                        int index, | 2892                                                        int index, | 
| 2696                                                        Map* transition, | 2893                                                        Handle<Map> transition, | 
| 2697                                                        String* name) { | 2894                                                        Handle<String> name) { | 
| 2698   // ----------- S t a t e ------------- | 2895   // ----------- S t a t e ------------- | 
| 2699   //  -- eax    : value | 2896   //  -- eax    : value | 
| 2700   //  -- ecx    : key | 2897   //  -- ecx    : key | 
| 2701   //  -- edx    : receiver | 2898   //  -- edx    : receiver | 
| 2702   //  -- esp[0] : return address | 2899   //  -- esp[0] : return address | 
| 2703   // ----------------------------------- | 2900   // ----------------------------------- | 
| 2704   Label miss; | 2901   Label miss; | 
| 2705 | 2902 | 
| 2706   Counters* counters = isolate()->counters(); | 2903   Counters* counters = isolate()->counters(); | 
| 2707   __ IncrementCounter(counters->keyed_store_field(), 1); | 2904   __ IncrementCounter(counters->keyed_store_field(), 1); | 
| 2708 | 2905 | 
| 2709   // Check that the name has not changed. | 2906   // Check that the name has not changed. | 
| 2710   __ cmp(ecx, Immediate(Handle<String>(name))); | 2907   __ cmp(ecx, Immediate(name)); | 
| 2711   __ j(not_equal, &miss); | 2908   __ j(not_equal, &miss); | 
| 2712 | 2909 | 
| 2713   // Generate store field code.  Trashes the name register. | 2910   // Generate store field code.  Trashes the name register. | 
| 2714   GenerateStoreField(masm(), | 2911   GenerateStoreField(masm(), object, index, transition, edx, ecx, ebx, &miss); | 
| 2715                      object, |  | 
| 2716                      index, |  | 
| 2717                      transition, |  | 
| 2718                      edx, ecx, ebx, |  | 
| 2719                      &miss); |  | 
| 2720 | 2912 | 
| 2721   // Handle store cache miss. | 2913   // Handle store cache miss. | 
| 2722   __ bind(&miss); | 2914   __ bind(&miss); | 
| 2723   __ DecrementCounter(counters->keyed_store_field(), 1); | 2915   __ DecrementCounter(counters->keyed_store_field(), 1); | 
| 2724   Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 2916   Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 
| 2725   __ jmp(ic, RelocInfo::CODE_TARGET); | 2917   __ jmp(ic, RelocInfo::CODE_TARGET); | 
| 2726 | 2918 | 
| 2727   // Return the generated code. | 2919   // Return the generated code. | 
| 2728   return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 2920   return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name); | 
| 2729 } | 2921 } | 
| 2730 | 2922 | 
| 2731 | 2923 | 
| 2732 MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(Map* receiver_map) { | 2924 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement( | 
|  | 2925     Handle<Map> receiver_map) { | 
| 2733   // ----------- S t a t e ------------- | 2926   // ----------- S t a t e ------------- | 
| 2734   //  -- eax    : value | 2927   //  -- eax    : value | 
| 2735   //  -- ecx    : key | 2928   //  -- ecx    : key | 
| 2736   //  -- edx    : receiver | 2929   //  -- edx    : receiver | 
| 2737   //  -- esp[0] : return address | 2930   //  -- esp[0] : return address | 
| 2738   // ----------------------------------- | 2931   // ----------------------------------- | 
| 2739   Code* stub; |  | 
| 2740   ElementsKind elements_kind = receiver_map->elements_kind(); | 2932   ElementsKind elements_kind = receiver_map->elements_kind(); | 
| 2741   bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; | 2933   bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; | 
| 2742   MaybeObject* maybe_stub = | 2934   Handle<Code> stub = | 
| 2743       KeyedStoreElementStub(is_jsarray, elements_kind).TryGetCode(); | 2935       KeyedStoreElementStub(is_jsarray, elements_kind).GetCode(); | 
| 2744   if (!maybe_stub->To(&stub)) return maybe_stub; | 2936 | 
| 2745   __ DispatchMap(edx, | 2937   __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK); | 
| 2746                  Handle<Map>(receiver_map), |  | 
| 2747                  Handle<Code>(stub), |  | 
| 2748                  DO_SMI_CHECK); |  | 
| 2749 | 2938 | 
| 2750   Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 2939   Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 
| 2751   __ jmp(ic, RelocInfo::CODE_TARGET); | 2940   __ jmp(ic, RelocInfo::CODE_TARGET); | 
| 2752 | 2941 | 
| 2753   // Return the generated code. | 2942   // Return the generated code. | 
| 2754   return GetCode(NORMAL, NULL); | 2943   return GetCode(NORMAL, factory()->empty_string()); | 
| 2755 } | 2944 } | 
| 2756 | 2945 | 
| 2757 | 2946 | 
| 2758 MaybeObject* KeyedStoreStubCompiler::CompileStorePolymorphic( | 2947 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( | 
| 2759     MapList* receiver_maps, | 2948     MapHandleList* receiver_maps, | 
| 2760     CodeList* handler_stubs, | 2949     CodeHandleList* handler_stubs, | 
| 2761     MapList* transitioned_maps) { | 2950     MapHandleList* transitioned_maps) { | 
| 2762   // ----------- S t a t e ------------- | 2951   // ----------- S t a t e ------------- | 
| 2763   //  -- eax    : value | 2952   //  -- eax    : value | 
| 2764   //  -- ecx    : key | 2953   //  -- ecx    : key | 
| 2765   //  -- edx    : receiver | 2954   //  -- edx    : receiver | 
| 2766   //  -- esp[0] : return address | 2955   //  -- esp[0] : return address | 
| 2767   // ----------------------------------- | 2956   // ----------------------------------- | 
| 2768   Label miss; | 2957   Label miss; | 
| 2769   __ JumpIfSmi(edx, &miss, Label::kNear); | 2958   __ JumpIfSmi(edx, &miss, Label::kNear); | 
| 2770   __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset)); | 2959   __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset)); | 
| 2771   // ebx: receiver->map(). | 2960   // ebx: receiver->map(). | 
| 2772   for (int i = 0; i < receiver_maps->length(); ++i) { | 2961   for (int i = 0; i < receiver_maps->length(); ++i) { | 
| 2773     Handle<Map> map(receiver_maps->at(i)); | 2962     __ cmp(edi, receiver_maps->at(i)); | 
| 2774     __ cmp(edi, map); | 2963     if (transitioned_maps->at(i).is_null()) { | 
| 2775     if (transitioned_maps->at(i) == NULL) { | 2964       __ j(equal, handler_stubs->at(i)); | 
| 2776       __ j(equal, Handle<Code>(handler_stubs->at(i))); |  | 
| 2777     } else { | 2965     } else { | 
| 2778       Label next_map; | 2966       Label next_map; | 
| 2779       __ j(not_equal, &next_map, Label::kNear); | 2967       __ j(not_equal, &next_map, Label::kNear); | 
| 2780       __ mov(ebx, Immediate(Handle<Map>(transitioned_maps->at(i)))); | 2968       __ mov(ebx, Immediate(transitioned_maps->at(i))); | 
| 2781       __ jmp(Handle<Code>(handler_stubs->at(i)), RelocInfo::CODE_TARGET); | 2969       __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET); | 
| 2782       __ bind(&next_map); | 2970       __ bind(&next_map); | 
| 2783     } | 2971     } | 
| 2784   } | 2972   } | 
| 2785   __ bind(&miss); | 2973   __ bind(&miss); | 
| 2786   Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 2974   Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 
| 2787   __ jmp(miss_ic, RelocInfo::CODE_TARGET); | 2975   __ jmp(miss_ic, RelocInfo::CODE_TARGET); | 
| 2788 | 2976 | 
| 2789   // Return the generated code. | 2977   // Return the generated code. | 
| 2790   return GetCode(NORMAL, NULL, MEGAMORPHIC); | 2978   return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC); | 
| 2791 } | 2979 } | 
| 2792 | 2980 | 
| 2793 | 2981 | 
| 2794 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, | 2982 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<String> name, | 
| 2795                                                       JSObject* object, | 2983                                                       Handle<JSObject> object, | 
| 2796                                                       JSObject* last) { | 2984                                                       Handle<JSObject> last) { | 
| 2797   // ----------- S t a t e ------------- | 2985   // ----------- S t a t e ------------- | 
| 2798   //  -- eax    : receiver | 2986   //  -- eax    : receiver | 
| 2799   //  -- ecx    : name | 2987   //  -- ecx    : name | 
| 2800   //  -- esp[0] : return address | 2988   //  -- esp[0] : return address | 
| 2801   // ----------------------------------- | 2989   // ----------------------------------- | 
| 2802   Label miss; | 2990   Label miss; | 
| 2803 | 2991 | 
| 2804   // Check that the receiver isn't a smi. | 2992   // Check that the receiver isn't a smi. | 
| 2805   __ JumpIfSmi(eax, &miss); | 2993   __ JumpIfSmi(eax, &miss); | 
| 2806 | 2994 | 
| 2807   ASSERT(last->IsGlobalObject() || last->HasFastProperties()); | 2995   ASSERT(last->IsGlobalObject() || last->HasFastProperties()); | 
| 2808 | 2996 | 
| 2809   // Check the maps of the full prototype chain. Also check that | 2997   // Check the maps of the full prototype chain. Also check that | 
| 2810   // global property cells up to (but not including) the last object | 2998   // global property cells up to (but not including) the last object | 
| 2811   // in the prototype chain are empty. | 2999   // in the prototype chain are empty. | 
| 2812   CheckPrototypes(object, eax, last, ebx, edx, edi, name, &miss); | 3000   CheckPrototypes(object, eax, last, ebx, edx, edi, name, &miss); | 
| 2813 | 3001 | 
| 2814   // If the last object in the prototype chain is a global object, | 3002   // If the last object in the prototype chain is a global object, | 
| 2815   // check that the global property cell is empty. | 3003   // check that the global property cell is empty. | 
| 2816   if (last->IsGlobalObject()) { | 3004   if (last->IsGlobalObject()) { | 
| 2817     MaybeObject* cell = GenerateCheckPropertyCell(masm(), | 3005     GenerateCheckPropertyCell( | 
| 2818                                                   GlobalObject::cast(last), | 3006         masm(), Handle<GlobalObject>::cast(last), name, edx, &miss); | 
| 2819                                                   name, |  | 
| 2820                                                   edx, |  | 
| 2821                                                   &miss); |  | 
| 2822     if (cell->IsFailure()) { |  | 
| 2823       miss.Unuse(); |  | 
| 2824       return cell; |  | 
| 2825     } |  | 
| 2826   } | 3007   } | 
| 2827 | 3008 | 
| 2828   // Return undefined if maps of the full prototype chain are still the | 3009   // Return undefined if maps of the full prototype chain are still the | 
| 2829   // same and no global property with this name contains a value. | 3010   // same and no global property with this name contains a value. | 
| 2830   __ mov(eax, isolate()->factory()->undefined_value()); | 3011   __ mov(eax, isolate()->factory()->undefined_value()); | 
| 2831   __ ret(0); | 3012   __ ret(0); | 
| 2832 | 3013 | 
| 2833   __ bind(&miss); | 3014   __ bind(&miss); | 
| 2834   GenerateLoadMiss(masm(), Code::LOAD_IC); | 3015   GenerateLoadMiss(masm(), Code::LOAD_IC); | 
| 2835 | 3016 | 
| 2836   // Return the generated code. | 3017   // Return the generated code. | 
| 2837   return GetCode(NONEXISTENT, isolate()->heap()->empty_string()); | 3018   return GetCode(NONEXISTENT, factory()->empty_string()); | 
| 2838 } | 3019 } | 
| 2839 | 3020 | 
| 2840 | 3021 | 
| 2841 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object, | 3022 Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object, | 
| 2842                                                 JSObject* holder, | 3023                                                 Handle<JSObject> holder, | 
| 2843                                                 int index, | 3024                                                 int index, | 
| 2844                                                 String* name) { | 3025                                                 Handle<String> name) { | 
| 2845   // ----------- S t a t e ------------- | 3026   // ----------- S t a t e ------------- | 
| 2846   //  -- eax    : receiver | 3027   //  -- eax    : receiver | 
| 2847   //  -- ecx    : name | 3028   //  -- ecx    : name | 
| 2848   //  -- esp[0] : return address | 3029   //  -- esp[0] : return address | 
| 2849   // ----------------------------------- | 3030   // ----------------------------------- | 
| 2850   Label miss; | 3031   Label miss; | 
| 2851 | 3032 | 
| 2852   GenerateLoadField(object, holder, eax, ebx, edx, edi, index, name, &miss); | 3033   GenerateLoadField(object, holder, eax, ebx, edx, edi, index, name, &miss); | 
| 2853   __ bind(&miss); | 3034   __ bind(&miss); | 
| 2854   GenerateLoadMiss(masm(), Code::LOAD_IC); | 3035   GenerateLoadMiss(masm(), Code::LOAD_IC); | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
| 2873                                              edi, callback, name, &miss); | 3054                                              edi, callback, name, &miss); | 
| 2874   if (result->IsFailure()) { | 3055   if (result->IsFailure()) { | 
| 2875     miss.Unuse(); | 3056     miss.Unuse(); | 
| 2876     return result; | 3057     return result; | 
| 2877   } | 3058   } | 
| 2878 | 3059 | 
| 2879   __ bind(&miss); | 3060   __ bind(&miss); | 
| 2880   GenerateLoadMiss(masm(), Code::LOAD_IC); | 3061   GenerateLoadMiss(masm(), Code::LOAD_IC); | 
| 2881 | 3062 | 
| 2882   // Return the generated code. | 3063   // Return the generated code. | 
| 2883   return GetCode(CALLBACKS, name); | 3064   return TryGetCode(CALLBACKS, name); | 
| 2884 } | 3065 } | 
| 2885 | 3066 | 
| 2886 | 3067 | 
| 2887 MaybeObject* LoadStubCompiler::CompileLoadConstant(JSObject* object, | 3068 Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object, | 
| 2888                                                    JSObject* holder, | 3069                                                    Handle<JSObject> holder, | 
| 2889                                                    Object* value, | 3070                                                    Handle<Object> value, | 
| 2890                                                    String* name) { | 3071                                                    Handle<String> name) { | 
| 2891   // ----------- S t a t e ------------- | 3072   // ----------- S t a t e ------------- | 
| 2892   //  -- eax    : receiver | 3073   //  -- eax    : receiver | 
| 2893   //  -- ecx    : name | 3074   //  -- ecx    : name | 
| 2894   //  -- esp[0] : return address | 3075   //  -- esp[0] : return address | 
| 2895   // ----------------------------------- | 3076   // ----------------------------------- | 
| 2896   Label miss; | 3077   Label miss; | 
| 2897 | 3078 | 
| 2898   GenerateLoadConstant(object, holder, eax, ebx, edx, edi, value, name, &miss); | 3079   GenerateLoadConstant(object, holder, eax, ebx, edx, edi, value, name, &miss); | 
| 2899   __ bind(&miss); | 3080   __ bind(&miss); | 
| 2900   GenerateLoadMiss(masm(), Code::LOAD_IC); | 3081   GenerateLoadMiss(masm(), Code::LOAD_IC); | 
| 2901 | 3082 | 
| 2902   // Return the generated code. | 3083   // Return the generated code. | 
| 2903   return GetCode(CONSTANT_FUNCTION, name); | 3084   return GetCode(CONSTANT_FUNCTION, name); | 
| 2904 } | 3085 } | 
| 2905 | 3086 | 
| 2906 | 3087 | 
| 2907 MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 3088 MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 
| 2908                                                       JSObject* holder, | 3089                                                       JSObject* holder, | 
| 2909                                                       String* name) { | 3090                                                       String* name) { | 
| 2910   // ----------- S t a t e ------------- | 3091   // ----------- S t a t e ------------- | 
| 2911   //  -- eax    : receiver | 3092   //  -- eax    : receiver | 
| 2912   //  -- ecx    : name | 3093   //  -- ecx    : name | 
| 2913   //  -- esp[0] : return address | 3094   //  -- esp[0] : return address | 
| 2914   // ----------------------------------- | 3095   // ----------------------------------- | 
| 2915   Label miss; | 3096   Label miss; | 
| 2916 | 3097 | 
| 2917   LookupResult lookup; | 3098   LookupResult lookup(isolate()); | 
| 2918   LookupPostInterceptor(holder, name, &lookup); | 3099   LookupPostInterceptor(holder, name, &lookup); | 
| 2919 | 3100 | 
| 2920   // TODO(368): Compile in the whole chain: all the interceptors in | 3101   // TODO(368): Compile in the whole chain: all the interceptors in | 
| 2921   // prototypes and ultimate answer. | 3102   // prototypes and ultimate answer. | 
| 2922   GenerateLoadInterceptor(receiver, | 3103   GenerateLoadInterceptor(receiver, | 
| 2923                           holder, | 3104                           holder, | 
| 2924                           &lookup, | 3105                           &lookup, | 
| 2925                           eax, | 3106                           eax, | 
| 2926                           ecx, | 3107                           ecx, | 
| 2927                           edx, | 3108                           edx, | 
| 2928                           ebx, | 3109                           ebx, | 
| 2929                           edi, | 3110                           edi, | 
| 2930                           name, | 3111                           name, | 
| 2931                           &miss); | 3112                           &miss); | 
| 2932 | 3113 | 
| 2933   __ bind(&miss); | 3114   __ bind(&miss); | 
| 2934   GenerateLoadMiss(masm(), Code::LOAD_IC); | 3115   GenerateLoadMiss(masm(), Code::LOAD_IC); | 
| 2935 | 3116 | 
| 2936   // Return the generated code. | 3117   // Return the generated code. | 
| 2937   return GetCode(INTERCEPTOR, name); | 3118   return TryGetCode(INTERCEPTOR, name); | 
| 2938 } | 3119 } | 
| 2939 | 3120 | 
| 2940 | 3121 | 
| 2941 MaybeObject* LoadStubCompiler::CompileLoadGlobal(JSObject* object, | 3122 Handle<Code> LoadStubCompiler::CompileLoadGlobal( | 
| 2942                                                  GlobalObject* holder, | 3123     Handle<JSObject> object, | 
| 2943                                                  JSGlobalPropertyCell* cell, | 3124     Handle<GlobalObject> holder, | 
| 2944                                                  String* name, | 3125     Handle<JSGlobalPropertyCell> cell, | 
| 2945                                                  bool is_dont_delete) { | 3126     Handle<String> name, | 
|  | 3127     bool is_dont_delete) { | 
| 2946   // ----------- S t a t e ------------- | 3128   // ----------- S t a t e ------------- | 
| 2947   //  -- eax    : receiver | 3129   //  -- eax    : receiver | 
| 2948   //  -- ecx    : name | 3130   //  -- ecx    : name | 
| 2949   //  -- esp[0] : return address | 3131   //  -- esp[0] : return address | 
| 2950   // ----------------------------------- | 3132   // ----------------------------------- | 
| 2951   Label miss; | 3133   Label miss; | 
| 2952 | 3134 | 
| 2953   // If the object is the holder then we know that it's a global | 3135   // If the object is the holder then we know that it's a global | 
| 2954   // object which can only happen for contextual loads. In this case, | 3136   // object which can only happen for contextual loads. In this case, | 
| 2955   // the receiver cannot be a smi. | 3137   // the receiver cannot be a smi. | 
| 2956   if (object != holder) { | 3138   if (!object.is_identical_to(holder)) { | 
| 2957     __ JumpIfSmi(eax, &miss); | 3139     __ JumpIfSmi(eax, &miss); | 
| 2958   } | 3140   } | 
| 2959 | 3141 | 
| 2960   // Check that the maps haven't changed. | 3142   // Check that the maps haven't changed. | 
| 2961   CheckPrototypes(object, eax, holder, ebx, edx, edi, name, &miss); | 3143   CheckPrototypes(object, eax, holder, ebx, edx, edi, name, &miss); | 
| 2962 | 3144 | 
| 2963   // Get the value from the cell. | 3145   // Get the value from the cell. | 
| 2964   if (Serializer::enabled()) { | 3146   if (Serializer::enabled()) { | 
| 2965     __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell))); | 3147     __ mov(ebx, Immediate(cell)); | 
| 2966     __ mov(ebx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset)); | 3148     __ mov(ebx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset)); | 
| 2967   } else { | 3149   } else { | 
| 2968     __ mov(ebx, Operand::Cell(Handle<JSGlobalPropertyCell>(cell))); | 3150     __ mov(ebx, Operand::Cell(cell)); | 
| 2969   } | 3151   } | 
| 2970 | 3152 | 
| 2971   // Check for deleted property if property can actually be deleted. | 3153   // Check for deleted property if property can actually be deleted. | 
| 2972   if (!is_dont_delete) { | 3154   if (!is_dont_delete) { | 
| 2973     __ cmp(ebx, factory()->the_hole_value()); | 3155     __ cmp(ebx, factory()->the_hole_value()); | 
| 2974     __ j(equal, &miss); | 3156     __ j(equal, &miss); | 
| 2975   } else if (FLAG_debug_code) { | 3157   } else if (FLAG_debug_code) { | 
| 2976     __ cmp(ebx, factory()->the_hole_value()); | 3158     __ cmp(ebx, factory()->the_hole_value()); | 
| 2977     __ Check(not_equal, "DontDelete cells can't contain the hole"); | 3159     __ Check(not_equal, "DontDelete cells can't contain the hole"); | 
| 2978   } | 3160   } | 
| 2979 | 3161 | 
| 2980   Counters* counters = isolate()->counters(); | 3162   Counters* counters = isolate()->counters(); | 
| 2981   __ IncrementCounter(counters->named_load_global_stub(), 1); | 3163   __ IncrementCounter(counters->named_load_global_stub(), 1); | 
| 2982   __ mov(eax, ebx); | 3164   __ mov(eax, ebx); | 
| 2983   __ ret(0); | 3165   __ ret(0); | 
| 2984 | 3166 | 
| 2985   __ bind(&miss); | 3167   __ bind(&miss); | 
| 2986   __ IncrementCounter(counters->named_load_global_stub_miss(), 1); | 3168   __ IncrementCounter(counters->named_load_global_stub_miss(), 1); | 
| 2987   GenerateLoadMiss(masm(), Code::LOAD_IC); | 3169   GenerateLoadMiss(masm(), Code::LOAD_IC); | 
| 2988 | 3170 | 
| 2989   // Return the generated code. | 3171   // Return the generated code. | 
| 2990   return GetCode(NORMAL, name); | 3172   return GetCode(NORMAL, name); | 
| 2991 } | 3173 } | 
| 2992 | 3174 | 
| 2993 | 3175 | 
| 2994 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, | 3176 Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name, | 
| 2995                                                      JSObject* receiver, | 3177                                                      Handle<JSObject> receiver, | 
| 2996                                                      JSObject* holder, | 3178                                                      Handle<JSObject> holder, | 
| 2997                                                      int index) { | 3179                                                      int index) { | 
| 2998   // ----------- S t a t e ------------- | 3180   // ----------- S t a t e ------------- | 
| 2999   //  -- eax    : key | 3181   //  -- eax    : key | 
| 3000   //  -- edx    : receiver | 3182   //  -- edx    : receiver | 
| 3001   //  -- esp[0] : return address | 3183   //  -- esp[0] : return address | 
| 3002   // ----------------------------------- | 3184   // ----------------------------------- | 
| 3003   Label miss; | 3185   Label miss; | 
| 3004 | 3186 | 
| 3005   Counters* counters = isolate()->counters(); | 3187   Counters* counters = isolate()->counters(); | 
| 3006   __ IncrementCounter(counters->keyed_load_field(), 1); | 3188   __ IncrementCounter(counters->keyed_load_field(), 1); | 
| 3007 | 3189 | 
| 3008   // Check that the name has not changed. | 3190   // Check that the name has not changed. | 
| 3009   __ cmp(eax, Immediate(Handle<String>(name))); | 3191   __ cmp(eax, Immediate(name)); | 
| 3010   __ j(not_equal, &miss); | 3192   __ j(not_equal, &miss); | 
| 3011 | 3193 | 
| 3012   GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss); | 3194   GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss); | 
| 3013 | 3195 | 
| 3014   __ bind(&miss); | 3196   __ bind(&miss); | 
| 3015   __ DecrementCounter(counters->keyed_load_field(), 1); | 3197   __ DecrementCounter(counters->keyed_load_field(), 1); | 
| 3016   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3198   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| 3017 | 3199 | 
| 3018   // Return the generated code. | 3200   // Return the generated code. | 
| 3019   return GetCode(FIELD, name); | 3201   return GetCode(FIELD, name); | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 3045     miss.Unuse(); | 3227     miss.Unuse(); | 
| 3046     return result; | 3228     return result; | 
| 3047   } | 3229   } | 
| 3048 | 3230 | 
| 3049   __ bind(&miss); | 3231   __ bind(&miss); | 
| 3050 | 3232 | 
| 3051   __ DecrementCounter(counters->keyed_load_callback(), 1); | 3233   __ DecrementCounter(counters->keyed_load_callback(), 1); | 
| 3052   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3234   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| 3053 | 3235 | 
| 3054   // Return the generated code. | 3236   // Return the generated code. | 
| 3055   return GetCode(CALLBACKS, name); | 3237   return TryGetCode(CALLBACKS, name); | 
| 3056 } | 3238 } | 
| 3057 | 3239 | 
| 3058 | 3240 | 
| 3059 MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name, | 3241 Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant( | 
| 3060                                                         JSObject* receiver, | 3242     Handle<String> name, | 
| 3061                                                         JSObject* holder, | 3243     Handle<JSObject> receiver, | 
| 3062                                                         Object* value) { | 3244     Handle<JSObject> holder, | 
|  | 3245     Handle<Object> value) { | 
| 3063   // ----------- S t a t e ------------- | 3246   // ----------- S t a t e ------------- | 
| 3064   //  -- eax    : key | 3247   //  -- eax    : key | 
| 3065   //  -- edx    : receiver | 3248   //  -- edx    : receiver | 
| 3066   //  -- esp[0] : return address | 3249   //  -- esp[0] : return address | 
| 3067   // ----------------------------------- | 3250   // ----------------------------------- | 
| 3068   Label miss; | 3251   Label miss; | 
| 3069 | 3252 | 
| 3070   Counters* counters = isolate()->counters(); | 3253   Counters* counters = isolate()->counters(); | 
| 3071   __ IncrementCounter(counters->keyed_load_constant_function(), 1); | 3254   __ IncrementCounter(counters->keyed_load_constant_function(), 1); | 
| 3072 | 3255 | 
| 3073   // Check that the name has not changed. | 3256   // Check that the name has not changed. | 
| 3074   __ cmp(eax, Immediate(Handle<String>(name))); | 3257   __ cmp(eax, Immediate(name)); | 
| 3075   __ j(not_equal, &miss); | 3258   __ j(not_equal, &miss); | 
| 3076 | 3259 | 
| 3077   GenerateLoadConstant(receiver, holder, edx, ebx, ecx, edi, | 3260   GenerateLoadConstant( | 
| 3078                        value, name, &miss); | 3261       receiver, holder, edx, ebx, ecx, edi, value, name, &miss); | 
| 3079   __ bind(&miss); | 3262   __ bind(&miss); | 
| 3080   __ DecrementCounter(counters->keyed_load_constant_function(), 1); | 3263   __ DecrementCounter(counters->keyed_load_constant_function(), 1); | 
| 3081   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3264   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| 3082 | 3265 | 
| 3083   // Return the generated code. | 3266   // Return the generated code. | 
| 3084   return GetCode(CONSTANT_FUNCTION, name); | 3267   return GetCode(CONSTANT_FUNCTION, name); | 
| 3085 } | 3268 } | 
| 3086 | 3269 | 
| 3087 | 3270 | 
| 3088 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 3271 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 
| 3089                                                            JSObject* holder, | 3272                                                            JSObject* holder, | 
| 3090                                                            String* name) { | 3273                                                            String* name) { | 
| 3091   // ----------- S t a t e ------------- | 3274   // ----------- S t a t e ------------- | 
| 3092   //  -- eax    : key | 3275   //  -- eax    : key | 
| 3093   //  -- edx    : receiver | 3276   //  -- edx    : receiver | 
| 3094   //  -- esp[0] : return address | 3277   //  -- esp[0] : return address | 
| 3095   // ----------------------------------- | 3278   // ----------------------------------- | 
| 3096   Label miss; | 3279   Label miss; | 
| 3097 | 3280 | 
| 3098   Counters* counters = isolate()->counters(); | 3281   Counters* counters = isolate()->counters(); | 
| 3099   __ IncrementCounter(counters->keyed_load_interceptor(), 1); | 3282   __ IncrementCounter(counters->keyed_load_interceptor(), 1); | 
| 3100 | 3283 | 
| 3101   // Check that the name has not changed. | 3284   // Check that the name has not changed. | 
| 3102   __ cmp(eax, Immediate(Handle<String>(name))); | 3285   __ cmp(eax, Immediate(Handle<String>(name))); | 
| 3103   __ j(not_equal, &miss); | 3286   __ j(not_equal, &miss); | 
| 3104 | 3287 | 
| 3105   LookupResult lookup; | 3288   LookupResult lookup(isolate()); | 
| 3106   LookupPostInterceptor(holder, name, &lookup); | 3289   LookupPostInterceptor(holder, name, &lookup); | 
| 3107   GenerateLoadInterceptor(receiver, | 3290   GenerateLoadInterceptor(receiver, | 
| 3108                           holder, | 3291                           holder, | 
| 3109                           &lookup, | 3292                           &lookup, | 
| 3110                           edx, | 3293                           edx, | 
| 3111                           eax, | 3294                           eax, | 
| 3112                           ecx, | 3295                           ecx, | 
| 3113                           ebx, | 3296                           ebx, | 
| 3114                           edi, | 3297                           edi, | 
| 3115                           name, | 3298                           name, | 
| 3116                           &miss); | 3299                           &miss); | 
| 3117   __ bind(&miss); | 3300   __ bind(&miss); | 
| 3118   __ DecrementCounter(counters->keyed_load_interceptor(), 1); | 3301   __ DecrementCounter(counters->keyed_load_interceptor(), 1); | 
| 3119   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3302   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| 3120 | 3303 | 
| 3121   // Return the generated code. | 3304   // Return the generated code. | 
| 3122   return GetCode(INTERCEPTOR, name); | 3305   return TryGetCode(INTERCEPTOR, name); | 
| 3123 } | 3306 } | 
| 3124 | 3307 | 
| 3125 | 3308 | 
| 3126 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { | 3309 Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength( | 
|  | 3310     Handle<String> name) { | 
| 3127   // ----------- S t a t e ------------- | 3311   // ----------- S t a t e ------------- | 
| 3128   //  -- eax    : key | 3312   //  -- eax    : key | 
| 3129   //  -- edx    : receiver | 3313   //  -- edx    : receiver | 
| 3130   //  -- esp[0] : return address | 3314   //  -- esp[0] : return address | 
| 3131   // ----------------------------------- | 3315   // ----------------------------------- | 
| 3132   Label miss; | 3316   Label miss; | 
| 3133 | 3317 | 
| 3134   Counters* counters = isolate()->counters(); | 3318   Counters* counters = isolate()->counters(); | 
| 3135   __ IncrementCounter(counters->keyed_load_array_length(), 1); | 3319   __ IncrementCounter(counters->keyed_load_array_length(), 1); | 
| 3136 | 3320 | 
| 3137   // Check that the name has not changed. | 3321   // Check that the name has not changed. | 
| 3138   __ cmp(eax, Immediate(Handle<String>(name))); | 3322   __ cmp(eax, Immediate(name)); | 
| 3139   __ j(not_equal, &miss); | 3323   __ j(not_equal, &miss); | 
| 3140 | 3324 | 
| 3141   GenerateLoadArrayLength(masm(), edx, ecx, &miss); | 3325   GenerateLoadArrayLength(masm(), edx, ecx, &miss); | 
| 3142   __ bind(&miss); | 3326   __ bind(&miss); | 
| 3143   __ DecrementCounter(counters->keyed_load_array_length(), 1); | 3327   __ DecrementCounter(counters->keyed_load_array_length(), 1); | 
| 3144   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3328   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| 3145 | 3329 | 
| 3146   // Return the generated code. | 3330   // Return the generated code. | 
| 3147   return GetCode(CALLBACKS, name); | 3331   return GetCode(CALLBACKS, name); | 
| 3148 } | 3332 } | 
| 3149 | 3333 | 
| 3150 | 3334 | 
| 3151 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { | 3335 Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength( | 
|  | 3336     Handle<String> name) { | 
| 3152   // ----------- S t a t e ------------- | 3337   // ----------- S t a t e ------------- | 
| 3153   //  -- eax    : key | 3338   //  -- eax    : key | 
| 3154   //  -- edx    : receiver | 3339   //  -- edx    : receiver | 
| 3155   //  -- esp[0] : return address | 3340   //  -- esp[0] : return address | 
| 3156   // ----------------------------------- | 3341   // ----------------------------------- | 
| 3157   Label miss; | 3342   Label miss; | 
| 3158 | 3343 | 
| 3159   Counters* counters = isolate()->counters(); | 3344   Counters* counters = isolate()->counters(); | 
| 3160   __ IncrementCounter(counters->keyed_load_string_length(), 1); | 3345   __ IncrementCounter(counters->keyed_load_string_length(), 1); | 
| 3161 | 3346 | 
| 3162   // Check that the name has not changed. | 3347   // Check that the name has not changed. | 
| 3163   __ cmp(eax, Immediate(Handle<String>(name))); | 3348   __ cmp(eax, Immediate(name)); | 
| 3164   __ j(not_equal, &miss); | 3349   __ j(not_equal, &miss); | 
| 3165 | 3350 | 
| 3166   GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true); | 3351   GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true); | 
| 3167   __ bind(&miss); | 3352   __ bind(&miss); | 
| 3168   __ DecrementCounter(counters->keyed_load_string_length(), 1); | 3353   __ DecrementCounter(counters->keyed_load_string_length(), 1); | 
| 3169   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3354   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| 3170 | 3355 | 
| 3171   // Return the generated code. | 3356   // Return the generated code. | 
| 3172   return GetCode(CALLBACKS, name); | 3357   return GetCode(CALLBACKS, name); | 
| 3173 } | 3358 } | 
| 3174 | 3359 | 
| 3175 | 3360 | 
| 3176 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { | 3361 Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype( | 
|  | 3362     Handle<String> name) { | 
| 3177   // ----------- S t a t e ------------- | 3363   // ----------- S t a t e ------------- | 
| 3178   //  -- eax    : key | 3364   //  -- eax    : key | 
| 3179   //  -- edx    : receiver | 3365   //  -- edx    : receiver | 
| 3180   //  -- esp[0] : return address | 3366   //  -- esp[0] : return address | 
| 3181   // ----------------------------------- | 3367   // ----------------------------------- | 
| 3182   Label miss; | 3368   Label miss; | 
| 3183 | 3369 | 
| 3184   Counters* counters = isolate()->counters(); | 3370   Counters* counters = isolate()->counters(); | 
| 3185   __ IncrementCounter(counters->keyed_load_function_prototype(), 1); | 3371   __ IncrementCounter(counters->keyed_load_function_prototype(), 1); | 
| 3186 | 3372 | 
| 3187   // Check that the name has not changed. | 3373   // Check that the name has not changed. | 
| 3188   __ cmp(eax, Immediate(Handle<String>(name))); | 3374   __ cmp(eax, Immediate(name)); | 
| 3189   __ j(not_equal, &miss); | 3375   __ j(not_equal, &miss); | 
| 3190 | 3376 | 
| 3191   GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); | 3377   GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); | 
| 3192   __ bind(&miss); | 3378   __ bind(&miss); | 
| 3193   __ DecrementCounter(counters->keyed_load_function_prototype(), 1); | 3379   __ DecrementCounter(counters->keyed_load_function_prototype(), 1); | 
| 3194   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3380   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| 3195 | 3381 | 
| 3196   // Return the generated code. | 3382   // Return the generated code. | 
| 3197   return GetCode(CALLBACKS, name); | 3383   return GetCode(CALLBACKS, name); | 
| 3198 } | 3384 } | 
| 3199 | 3385 | 
| 3200 | 3386 | 
| 3201 MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) { | 3387 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( | 
|  | 3388     Handle<Map> receiver_map) { | 
| 3202   // ----------- S t a t e ------------- | 3389   // ----------- S t a t e ------------- | 
| 3203   //  -- eax    : key | 3390   //  -- eax    : key | 
| 3204   //  -- edx    : receiver | 3391   //  -- edx    : receiver | 
| 3205   //  -- esp[0] : return address | 3392   //  -- esp[0] : return address | 
| 3206   // ----------------------------------- | 3393   // ----------------------------------- | 
| 3207   Code* stub; | 3394 | 
| 3208   ElementsKind elements_kind = receiver_map->elements_kind(); | 3395   ElementsKind elements_kind = receiver_map->elements_kind(); | 
| 3209   MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode(); | 3396   Handle<Code> stub = KeyedLoadElementStub(elements_kind).GetCode(); | 
| 3210   if (!maybe_stub->To(&stub)) return maybe_stub; | 3397 | 
| 3211   __ DispatchMap(edx, | 3398   __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK); | 
| 3212                  Handle<Map>(receiver_map), |  | 
| 3213                  Handle<Code>(stub), |  | 
| 3214                  DO_SMI_CHECK); |  | 
| 3215 | 3399 | 
| 3216   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3400   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| 3217 | 3401 | 
| 3218   // Return the generated code. | 3402   // Return the generated code. | 
| 3219   return GetCode(NORMAL, NULL); | 3403   return GetCode(NORMAL, factory()->empty_string()); | 
| 3220 } | 3404 } | 
| 3221 | 3405 | 
| 3222 | 3406 | 
| 3223 MaybeObject* KeyedLoadStubCompiler::CompileLoadPolymorphic( | 3407 Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic( | 
| 3224     MapList* receiver_maps, | 3408     MapHandleList* receiver_maps, | 
| 3225     CodeList* handler_ics) { | 3409     CodeHandleList* handler_ics) { | 
| 3226   // ----------- S t a t e ------------- | 3410   // ----------- S t a t e ------------- | 
| 3227   //  -- eax    : key | 3411   //  -- eax    : key | 
| 3228   //  -- edx    : receiver | 3412   //  -- edx    : receiver | 
| 3229   //  -- esp[0] : return address | 3413   //  -- esp[0] : return address | 
| 3230   // ----------------------------------- | 3414   // ----------------------------------- | 
| 3231   Label miss; | 3415   Label miss; | 
| 3232   __ JumpIfSmi(edx, &miss); | 3416   __ JumpIfSmi(edx, &miss); | 
| 3233 | 3417 | 
| 3234   Register map_reg = ebx; | 3418   Register map_reg = ebx; | 
| 3235   __ mov(map_reg, FieldOperand(edx, HeapObject::kMapOffset)); | 3419   __ mov(map_reg, FieldOperand(edx, HeapObject::kMapOffset)); | 
| 3236   int receiver_count = receiver_maps->length(); | 3420   int receiver_count = receiver_maps->length(); | 
| 3237   for (int current = 0; current < receiver_count; ++current) { | 3421   for (int current = 0; current < receiver_count; ++current) { | 
| 3238     Handle<Map> map(receiver_maps->at(current)); | 3422     __ cmp(map_reg, receiver_maps->at(current)); | 
| 3239     __ cmp(map_reg, map); | 3423     __ j(equal, handler_ics->at(current)); | 
| 3240     __ j(equal, Handle<Code>(handler_ics->at(current))); |  | 
| 3241   } | 3424   } | 
| 3242 | 3425 | 
| 3243   __ bind(&miss); | 3426   __ bind(&miss); | 
| 3244   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3427   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| 3245 | 3428 | 
| 3246   // Return the generated code. | 3429   // Return the generated code. | 
| 3247   return GetCode(NORMAL, NULL, MEGAMORPHIC); | 3430   return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC); | 
| 3248 } | 3431 } | 
| 3249 | 3432 | 
| 3250 | 3433 | 
| 3251 // Specialized stub for constructing objects from functions which only have only | 3434 // Specialized stub for constructing objects from functions which only have only | 
| 3252 // simple assignments of the form this.x = ...; in their body. | 3435 // simple assignments of the form this.x = ...; in their body. | 
| 3253 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { | 3436 MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { | 
| 3254   // ----------- S t a t e ------------- | 3437   // ----------- S t a t e ------------- | 
| 3255   //  -- eax : argc | 3438   //  -- eax : argc | 
| 3256   //  -- edi : constructor | 3439   //  -- edi : constructor | 
| 3257   //  -- esp[0] : return address | 3440   //  -- esp[0] : return address | 
| (...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4026   Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 4209   Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 
| 4027   __ jmp(ic_miss, RelocInfo::CODE_TARGET); | 4210   __ jmp(ic_miss, RelocInfo::CODE_TARGET); | 
| 4028 } | 4211 } | 
| 4029 | 4212 | 
| 4030 | 4213 | 
| 4031 #undef __ | 4214 #undef __ | 
| 4032 | 4215 | 
| 4033 } }  // namespace v8::internal | 4216 } }  // namespace v8::internal | 
| 4034 | 4217 | 
| 4035 #endif  // V8_TARGET_ARCH_IA32 | 4218 #endif  // V8_TARGET_ARCH_IA32 | 
| OLD | NEW | 
|---|