| OLD | NEW | 
|---|
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 85 | 85 | 
| 86 // Helper function used to check that the dictionary doesn't contain | 86 // Helper function used to check that the dictionary doesn't contain | 
| 87 // the property. This function may return false negatives, so miss_label | 87 // the property. This function may return false negatives, so miss_label | 
| 88 // must always call a backup property check that is complete. | 88 // must always call a backup property check that is complete. | 
| 89 // This function is safe to call if the receiver has fast properties. | 89 // This function is safe to call if the receiver has fast properties. | 
| 90 // Name must be a symbol and receiver must be a heap object. | 90 // Name must be a symbol and receiver must be a heap object. | 
| 91 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, | 91 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, | 
| 92                                              Label* miss_label, | 92                                              Label* miss_label, | 
| 93                                              Register receiver, | 93                                              Register receiver, | 
| 94                                              String* name, | 94                                              String* name, | 
| 95                                              Register r0, | 95                                              Register scratch0, | 
| 96                                              Register extra) { | 96                                              Register scratch1) { | 
| 97   ASSERT(name->IsSymbol()); | 97   ASSERT(name->IsSymbol()); | 
| 98   if (!extra.is(no_reg)) { | 98   __ IncrementCounter(&Counters::negative_lookups, 1, scratch0, scratch1); | 
| 99     __ IncrementCounter(&Counters::negative_lookups, 1, r0, extra); | 99   __ IncrementCounter(&Counters::negative_lookups_miss, 1, scratch0, scratch1); | 
| 100     __ IncrementCounter(&Counters::negative_lookups_miss, 1, r0, extra); |  | 
| 101   } |  | 
| 102 | 100 | 
| 103   Label done; | 101   Label done; | 
| 104 | 102 | 
| 105   const int kInterceptorOrAccessCheckNeededMask = | 103   const int kInterceptorOrAccessCheckNeededMask = | 
| 106       (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 104       (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 
| 107 | 105 | 
| 108   // Bail out if the receiver has a named interceptor or requires access checks. | 106   // Bail out if the receiver has a named interceptor or requires access checks. | 
| 109   Register map = extra.is(no_reg) ? r0 : extra; | 107   Register map = scratch1; | 
| 110   __ ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 108   __ ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 
| 111   __ ldrb(r0, FieldMemOperand(map, Map::kBitFieldOffset)); | 109   __ ldrb(scratch0, FieldMemOperand(map, Map::kBitFieldOffset)); | 
| 112   __ tst(r0, Operand(kInterceptorOrAccessCheckNeededMask)); | 110   __ tst(scratch0, Operand(kInterceptorOrAccessCheckNeededMask)); | 
| 113   __ b(ne, miss_label); | 111   __ b(ne, miss_label); | 
| 114 | 112 | 
| 115   // Check that receiver is a JSObject. | 113   // Check that receiver is a JSObject. | 
| 116   if (extra.is(no_reg)) { | 114   __ ldrb(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset)); | 
| 117      __ ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 115   __ cmp(scratch0, Operand(FIRST_JS_OBJECT_TYPE)); | 
| 118   } |  | 
| 119   __ ldrb(r0, FieldMemOperand(map, Map::kInstanceTypeOffset)); |  | 
| 120   __ cmp(r0, Operand(FIRST_JS_OBJECT_TYPE)); |  | 
| 121   __ b(lt, miss_label); | 116   __ b(lt, miss_label); | 
| 122 | 117 | 
| 123   // Load properties array. | 118   // Load properties array. | 
| 124   Register properties = r0; | 119   Register properties = scratch0; | 
| 125   __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 120   __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 
| 126   // Check that the properties array is a dictionary. | 121   // Check that the properties array is a dictionary. | 
| 127   if (!extra.is(no_reg)) { | 122   __ ldr(map, FieldMemOperand(properties, HeapObject::kMapOffset)); | 
| 128     __ ldr(extra, FieldMemOperand(properties, HeapObject::kMapOffset)); | 123   Register tmp = properties; | 
| 129     Register tmp = properties; | 124   __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); | 
| 130     __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); | 125   __ cmp(map, tmp); | 
| 131     __ cmp(extra, tmp); |  | 
| 132   } else { |  | 
| 133     Register tmp1 = receiver; |  | 
| 134     Register tmp2 = properties; |  | 
| 135     __ push(tmp1); |  | 
| 136     __ ldr(tmp1, FieldMemOperand(properties, HeapObject::kMapOffset)); |  | 
| 137     __ LoadRoot(tmp2, Heap::kHashTableMapRootIndex); |  | 
| 138     __ cmp(tmp1, tmp2); |  | 
| 139     __ pop(tmp1); |  | 
| 140   } |  | 
| 141   __ b(ne, miss_label); | 126   __ b(ne, miss_label); | 
| 142 | 127 | 
| 143   // Restore the temporarily used register. | 128   // Restore the temporarily used register. | 
| 144   __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 129   __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 
| 145 | 130 | 
| 146   // Compute the capacity mask. | 131   // Compute the capacity mask. | 
| 147   const int kCapacityOffset = | 132   const int kCapacityOffset = | 
| 148       StringDictionary::kHeaderSize + | 133       StringDictionary::kHeaderSize + | 
| 149       StringDictionary::kCapacityIndex * kPointerSize; | 134       StringDictionary::kCapacityIndex * kPointerSize; | 
| 150 | 135 | 
| 151   // Generate an unrolled loop that performs a few probes before | 136   // Generate an unrolled loop that performs a few probes before | 
| 152   // giving up. | 137   // giving up. | 
| 153   static const int kProbes = 4; | 138   static const int kProbes = 4; | 
| 154   const int kElementsStartOffset = | 139   const int kElementsStartOffset = | 
| 155       StringDictionary::kHeaderSize + | 140       StringDictionary::kHeaderSize + | 
| 156       StringDictionary::kElementsStartIndex * kPointerSize; | 141       StringDictionary::kElementsStartIndex * kPointerSize; | 
| 157 | 142 | 
| 158   // If names of slots in range from 1 to kProbes - 1 for the hash value are | 143   // If names of slots in range from 1 to kProbes - 1 for the hash value are | 
| 159   // not equal to the name and kProbes-th slot is not used (its name is the | 144   // not equal to the name and kProbes-th slot is not used (its name is the | 
| 160   // undefined value), it guarantees the hash table doesn't contain the | 145   // undefined value), it guarantees the hash table doesn't contain the | 
| 161   // property. It's true even if some slots represent deleted properties | 146   // property. It's true even if some slots represent deleted properties | 
| 162   // (their names are the null value). | 147   // (their names are the null value). | 
| 163   for (int i = 0; i < kProbes; i++) { | 148   for (int i = 0; i < kProbes; i++) { | 
| 164     // r0 points to properties hash. | 149     // scratch0 points to properties hash. | 
| 165     // Compute the masked index: (hash + i + i * i) & mask. | 150     // Compute the masked index: (hash + i + i * i) & mask. | 
| 166     if (extra.is(no_reg)) { | 151     Register index = scratch1; | 
| 167       __ push(receiver); |  | 
| 168     } |  | 
| 169     Register index = extra.is(no_reg) ? receiver : extra; |  | 
| 170     // Capacity is smi 2^n. | 152     // Capacity is smi 2^n. | 
| 171     __ ldr(index, FieldMemOperand(properties, kCapacityOffset)); | 153     __ ldr(index, FieldMemOperand(properties, kCapacityOffset)); | 
| 172     __ sub(index, index, Operand(1)); | 154     __ sub(index, index, Operand(1)); | 
| 173     __ and_(index, index, Operand( | 155     __ and_(index, index, Operand( | 
| 174         Smi::FromInt(name->Hash() + StringDictionary::GetProbeOffset(i)))); | 156         Smi::FromInt(name->Hash() + StringDictionary::GetProbeOffset(i)))); | 
| 175 | 157 | 
| 176     // Scale the index by multiplying by the entry size. | 158     // Scale the index by multiplying by the entry size. | 
| 177     ASSERT(StringDictionary::kEntrySize == 3); | 159     ASSERT(StringDictionary::kEntrySize == 3); | 
| 178     __ add(index, index, Operand(index, LSL, 1));  // index *= 3. | 160     __ add(index, index, Operand(index, LSL, 1));  // index *= 3. | 
| 179 | 161 | 
| 180     Register entity_name = extra.is(no_reg) ? properties : extra; | 162     Register entity_name = scratch1; | 
| 181     // Having undefined at this place means the name is not contained. | 163     // Having undefined at this place means the name is not contained. | 
| 182     ASSERT_EQ(kSmiTagSize, 1); | 164     ASSERT_EQ(kSmiTagSize, 1); | 
| 183     Register tmp = extra.is(no_reg) ? receiver : properties; | 165     Register tmp = properties; | 
| 184     __ add(tmp, properties, Operand(index, LSL, 1)); | 166     __ add(tmp, properties, Operand(index, LSL, 1)); | 
| 185     __ ldr(entity_name, FieldMemOperand(tmp, kElementsStartOffset)); | 167     __ ldr(entity_name, FieldMemOperand(tmp, kElementsStartOffset)); | 
| 186 | 168 | 
| 187     ASSERT(!tmp.is(entity_name)); | 169     ASSERT(!tmp.is(entity_name)); | 
| 188     __ LoadRoot(tmp, Heap::kUndefinedValueRootIndex); | 170     __ LoadRoot(tmp, Heap::kUndefinedValueRootIndex); | 
| 189     __ cmp(entity_name, tmp); | 171     __ cmp(entity_name, tmp); | 
| 190     if (extra.is(no_reg)) { |  | 
| 191       // 'receiver' shares a register with 'entity_name'. |  | 
| 192       __ pop(receiver); |  | 
| 193     } |  | 
| 194     if (i != kProbes - 1) { | 172     if (i != kProbes - 1) { | 
| 195       __ b(eq, &done); | 173       __ b(eq, &done); | 
| 196 | 174 | 
| 197       // Stop if found the property. | 175       // Stop if found the property. | 
| 198       __ cmp(entity_name, Operand(Handle<String>(name))); | 176       __ cmp(entity_name, Operand(Handle<String>(name))); | 
| 199       __ b(eq, miss_label); | 177       __ b(eq, miss_label); | 
| 200 | 178 | 
| 201       // Restore the properties. | 179       // Restore the properties. | 
| 202       __ ldr(properties, | 180       __ ldr(properties, | 
| 203              FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 181              FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 
| 204     } else { | 182     } else { | 
| 205       // Give up probing if still not found the undefined value. | 183       // Give up probing if still not found the undefined value. | 
| 206       __ b(ne, miss_label); | 184       __ b(ne, miss_label); | 
| 207     } | 185     } | 
| 208   } | 186   } | 
| 209   __ bind(&done); | 187   __ bind(&done); | 
| 210   if (!extra.is(no_reg)) { | 188   __ DecrementCounter(&Counters::negative_lookups_miss, 1, scratch0, scratch1); | 
| 211     __ DecrementCounter(&Counters::negative_lookups_miss, 1, r0, extra); |  | 
| 212   } |  | 
| 213 } | 189 } | 
| 214 | 190 | 
| 215 | 191 | 
| 216 void StubCache::GenerateProbe(MacroAssembler* masm, | 192 void StubCache::GenerateProbe(MacroAssembler* masm, | 
| 217                               Code::Flags flags, | 193                               Code::Flags flags, | 
| 218                               Register receiver, | 194                               Register receiver, | 
| 219                               Register name, | 195                               Register name, | 
| 220                               Register scratch, | 196                               Register scratch, | 
| 221                               Register extra) { | 197                               Register extra) { | 
| 222   Label miss; | 198   Label miss; | 
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 640         name_(name) {} | 616         name_(name) {} | 
| 641 | 617 | 
| 642   void Compile(MacroAssembler* masm, | 618   void Compile(MacroAssembler* masm, | 
| 643                JSObject* object, | 619                JSObject* object, | 
| 644                JSObject* holder, | 620                JSObject* holder, | 
| 645                String* name, | 621                String* name, | 
| 646                LookupResult* lookup, | 622                LookupResult* lookup, | 
| 647                Register receiver, | 623                Register receiver, | 
| 648                Register scratch1, | 624                Register scratch1, | 
| 649                Register scratch2, | 625                Register scratch2, | 
|  | 626                Register scratch3, | 
| 650                Label* miss) { | 627                Label* miss) { | 
| 651     ASSERT(holder->HasNamedInterceptor()); | 628     ASSERT(holder->HasNamedInterceptor()); | 
| 652     ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); | 629     ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); | 
| 653 | 630 | 
| 654     // Check that the receiver isn't a smi. | 631     // Check that the receiver isn't a smi. | 
| 655     __ BranchOnSmi(receiver, miss); | 632     __ BranchOnSmi(receiver, miss); | 
| 656 | 633 | 
| 657     CallOptimization optimization(lookup); | 634     CallOptimization optimization(lookup); | 
| 658 | 635 | 
| 659     if (optimization.is_constant_call()) { | 636     if (optimization.is_constant_call()) { | 
| 660       CompileCacheable(masm, | 637       CompileCacheable(masm, | 
| 661                        object, | 638                        object, | 
| 662                        receiver, | 639                        receiver, | 
| 663                        scratch1, | 640                        scratch1, | 
| 664                        scratch2, | 641                        scratch2, | 
|  | 642                        scratch3, | 
| 665                        holder, | 643                        holder, | 
| 666                        lookup, | 644                        lookup, | 
| 667                        name, | 645                        name, | 
| 668                        optimization, | 646                        optimization, | 
| 669                        miss); | 647                        miss); | 
| 670     } else { | 648     } else { | 
| 671       CompileRegular(masm, | 649       CompileRegular(masm, | 
| 672                      object, | 650                      object, | 
| 673                      receiver, | 651                      receiver, | 
| 674                      scratch1, | 652                      scratch1, | 
| 675                      scratch2, | 653                      scratch2, | 
|  | 654                      scratch3, | 
| 676                      name, | 655                      name, | 
| 677                      holder, | 656                      holder, | 
| 678                      miss); | 657                      miss); | 
| 679     } | 658     } | 
| 680   } | 659   } | 
| 681 | 660 | 
| 682  private: | 661  private: | 
| 683   void CompileCacheable(MacroAssembler* masm, | 662   void CompileCacheable(MacroAssembler* masm, | 
| 684                        JSObject* object, | 663                        JSObject* object, | 
| 685                        Register receiver, | 664                        Register receiver, | 
| 686                        Register scratch1, | 665                        Register scratch1, | 
| 687                        Register scratch2, | 666                        Register scratch2, | 
|  | 667                        Register scratch3, | 
| 688                        JSObject* interceptor_holder, | 668                        JSObject* interceptor_holder, | 
| 689                        LookupResult* lookup, | 669                        LookupResult* lookup, | 
| 690                        String* name, | 670                        String* name, | 
| 691                        const CallOptimization& optimization, | 671                        const CallOptimization& optimization, | 
| 692                        Label* miss_label) { | 672                        Label* miss_label) { | 
| 693     ASSERT(optimization.is_constant_call()); | 673     ASSERT(optimization.is_constant_call()); | 
| 694     ASSERT(!lookup->holder()->IsGlobalObject()); | 674     ASSERT(!lookup->holder()->IsGlobalObject()); | 
| 695 | 675 | 
| 696     int depth1 = kInvalidProtoDepth; | 676     int depth1 = kInvalidProtoDepth; | 
| 697     int depth2 = kInvalidProtoDepth; | 677     int depth2 = kInvalidProtoDepth; | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 719       ReserveSpaceForFastApiCall(masm, scratch1); | 699       ReserveSpaceForFastApiCall(masm, scratch1); | 
| 720     } | 700     } | 
| 721 | 701 | 
| 722     // Check that the maps from receiver to interceptor's holder | 702     // Check that the maps from receiver to interceptor's holder | 
| 723     // haven't changed and thus we can invoke interceptor. | 703     // haven't changed and thus we can invoke interceptor. | 
| 724     Label miss_cleanup; | 704     Label miss_cleanup; | 
| 725     Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; | 705     Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; | 
| 726     Register holder = | 706     Register holder = | 
| 727         stub_compiler_->CheckPrototypes(object, receiver, | 707         stub_compiler_->CheckPrototypes(object, receiver, | 
| 728                                         interceptor_holder, scratch1, | 708                                         interceptor_holder, scratch1, | 
| 729                                         scratch2, name, depth1, miss); | 709                                         scratch2, scratch3, name, depth1, miss); | 
| 730 | 710 | 
| 731     // Invoke an interceptor and if it provides a value, | 711     // Invoke an interceptor and if it provides a value, | 
| 732     // branch to |regular_invoke|. | 712     // branch to |regular_invoke|. | 
| 733     Label regular_invoke; | 713     Label regular_invoke; | 
| 734     LoadWithInterceptor(masm, receiver, holder, interceptor_holder, scratch2, | 714     LoadWithInterceptor(masm, receiver, holder, interceptor_holder, scratch2, | 
| 735                         ®ular_invoke); | 715                         ®ular_invoke); | 
| 736 | 716 | 
| 737     // Interceptor returned nothing for this property.  Try to use cached | 717     // Interceptor returned nothing for this property.  Try to use cached | 
| 738     // constant function. | 718     // constant function. | 
| 739 | 719 | 
| 740     // Check that the maps from interceptor's holder to constant function's | 720     // Check that the maps from interceptor's holder to constant function's | 
| 741     // holder haven't changed and thus we can use cached constant function. | 721     // holder haven't changed and thus we can use cached constant function. | 
| 742     if (interceptor_holder != lookup->holder()) { | 722     if (interceptor_holder != lookup->holder()) { | 
| 743       stub_compiler_->CheckPrototypes(interceptor_holder, receiver, | 723       stub_compiler_->CheckPrototypes(interceptor_holder, receiver, | 
| 744                                       lookup->holder(), scratch1, | 724                                       lookup->holder(), scratch1, | 
| 745                                       scratch2, name, depth2, miss); | 725                                       scratch2, scratch3, name, depth2, miss); | 
| 746     } else { | 726     } else { | 
| 747       // CheckPrototypes has a side effect of fetching a 'holder' | 727       // CheckPrototypes has a side effect of fetching a 'holder' | 
| 748       // for API (object which is instanceof for the signature).  It's | 728       // for API (object which is instanceof for the signature).  It's | 
| 749       // safe to omit it here, as if present, it should be fetched | 729       // safe to omit it here, as if present, it should be fetched | 
| 750       // by the previous CheckPrototypes. | 730       // by the previous CheckPrototypes. | 
| 751       ASSERT(depth2 == kInvalidProtoDepth); | 731       ASSERT(depth2 == kInvalidProtoDepth); | 
| 752     } | 732     } | 
| 753 | 733 | 
| 754     // Invoke function. | 734     // Invoke function. | 
| 755     if (can_do_fast_api_call) { | 735     if (can_do_fast_api_call) { | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 771     if (can_do_fast_api_call) { | 751     if (can_do_fast_api_call) { | 
| 772       FreeSpaceForFastApiCall(masm); | 752       FreeSpaceForFastApiCall(masm); | 
| 773     } | 753     } | 
| 774   } | 754   } | 
| 775 | 755 | 
| 776   void CompileRegular(MacroAssembler* masm, | 756   void CompileRegular(MacroAssembler* masm, | 
| 777                       JSObject* object, | 757                       JSObject* object, | 
| 778                       Register receiver, | 758                       Register receiver, | 
| 779                       Register scratch1, | 759                       Register scratch1, | 
| 780                       Register scratch2, | 760                       Register scratch2, | 
|  | 761                       Register scratch3, | 
| 781                       String* name, | 762                       String* name, | 
| 782                       JSObject* interceptor_holder, | 763                       JSObject* interceptor_holder, | 
| 783                       Label* miss_label) { | 764                       Label* miss_label) { | 
| 784     Register holder = | 765     Register holder = | 
| 785         stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, | 766         stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, | 
| 786                                         scratch1, scratch2, name, | 767                                         scratch1, scratch2, scratch3, name, | 
| 787                                         miss_label); | 768                                         miss_label); | 
| 788 | 769 | 
| 789     // Call a runtime function to load the interceptor property. | 770     // Call a runtime function to load the interceptor property. | 
| 790     __ EnterInternalFrame(); | 771     __ EnterInternalFrame(); | 
| 791     // Save the name_ register across the call. | 772     // Save the name_ register across the call. | 
| 792     __ push(name_); | 773     __ push(name_); | 
| 793 | 774 | 
| 794     PushInterceptorArguments(masm, | 775     PushInterceptorArguments(masm, | 
| 795                              receiver, | 776                              receiver, | 
| 796                              holder, | 777                              holder, | 
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 861 | 842 | 
| 862 | 843 | 
| 863 #undef __ | 844 #undef __ | 
| 864 #define __ ACCESS_MASM(masm()) | 845 #define __ ACCESS_MASM(masm()) | 
| 865 | 846 | 
| 866 | 847 | 
| 867 Register StubCompiler::CheckPrototypes(JSObject* object, | 848 Register StubCompiler::CheckPrototypes(JSObject* object, | 
| 868                                        Register object_reg, | 849                                        Register object_reg, | 
| 869                                        JSObject* holder, | 850                                        JSObject* holder, | 
| 870                                        Register holder_reg, | 851                                        Register holder_reg, | 
| 871                                        Register scratch, | 852                                        Register scratch1, | 
|  | 853                                        Register scratch2, | 
| 872                                        String* name, | 854                                        String* name, | 
| 873                                        int save_at_depth, | 855                                        int save_at_depth, | 
| 874                                        Label* miss, | 856                                        Label* miss) { | 
| 875                                        Register extra) { | 857   // Make sure there's no overlap between holder and object registers. | 
| 876   // Make sure there's no overlap between scratch and the other | 858   ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 
| 877   // registers. | 859   ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 
| 878   ASSERT(!scratch.is(object_reg) && !scratch.is(holder_reg)); | 860          && !scratch2.is(scratch1)); | 
| 879 | 861 | 
| 880   // Keep track of the current object in register reg. | 862   // Keep track of the current object in register reg. | 
| 881   Register reg = object_reg; | 863   Register reg = object_reg; | 
| 882   int depth = 0; | 864   int depth = 0; | 
| 883 | 865 | 
| 884   if (save_at_depth == depth) { | 866   if (save_at_depth == depth) { | 
| 885     __ str(reg, MemOperand(sp)); | 867     __ str(reg, MemOperand(sp)); | 
| 886   } | 868   } | 
| 887 | 869 | 
| 888   // Check the maps in the prototype chain. | 870   // Check the maps in the prototype chain. | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 908           name = String::cast(lookup_result); | 890           name = String::cast(lookup_result); | 
| 909         } | 891         } | 
| 910       } | 892       } | 
| 911       ASSERT(current->property_dictionary()->FindEntry(name) == | 893       ASSERT(current->property_dictionary()->FindEntry(name) == | 
| 912              StringDictionary::kNotFound); | 894              StringDictionary::kNotFound); | 
| 913 | 895 | 
| 914       GenerateDictionaryNegativeLookup(masm(), | 896       GenerateDictionaryNegativeLookup(masm(), | 
| 915                                        miss, | 897                                        miss, | 
| 916                                        reg, | 898                                        reg, | 
| 917                                        name, | 899                                        name, | 
| 918                                        scratch, | 900                                        scratch1, | 
| 919                                        extra); | 901                                        scratch2); | 
| 920       __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); | 902       __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 
| 921       reg = holder_reg;  // from now the object is in holder_reg | 903       reg = holder_reg;  // from now the object is in holder_reg | 
| 922       __ ldr(reg, FieldMemOperand(scratch, Map::kPrototypeOffset)); | 904       __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | 
| 923     } else { | 905     } else { | 
| 924       // Get the map of the current object. | 906       // Get the map of the current object. | 
| 925       __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); | 907       __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 
| 926       __ cmp(scratch, Operand(Handle<Map>(current->map()))); | 908       __ cmp(scratch1, Operand(Handle<Map>(current->map()))); | 
| 927 | 909 | 
| 928       // Branch on the result of the map check. | 910       // Branch on the result of the map check. | 
| 929       __ b(ne, miss); | 911       __ b(ne, miss); | 
| 930 | 912 | 
| 931       // Check access rights to the global object.  This has to happen | 913       // Check access rights to the global object.  This has to happen | 
| 932       // after the map check so that we know that the object is | 914       // after the map check so that we know that the object is | 
| 933       // actually a global object. | 915       // actually a global object. | 
| 934       if (current->IsJSGlobalProxy()) { | 916       if (current->IsJSGlobalProxy()) { | 
| 935         __ CheckAccessGlobalProxy(reg, scratch, miss); | 917         __ CheckAccessGlobalProxy(reg, scratch1, miss); | 
| 936         // Restore scratch register to be the map of the object.  In the | 918         // Restore scratch register to be the map of the object.  In the | 
| 937         // new space case below, we load the prototype from the map in | 919         // new space case below, we load the prototype from the map in | 
| 938         // the scratch register. | 920         // the scratch register. | 
| 939         __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); | 921         __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 
| 940       } | 922       } | 
| 941 | 923 | 
| 942       reg = holder_reg;  // from now the object is in holder_reg | 924       reg = holder_reg;  // from now the object is in holder_reg | 
| 943       if (Heap::InNewSpace(prototype)) { | 925       if (Heap::InNewSpace(prototype)) { | 
| 944         // The prototype is in new space; we cannot store a reference | 926         // The prototype is in new space; we cannot store a reference | 
| 945         // to it in the code. Load it from the map. | 927         // to it in the code. Load it from the map. | 
| 946         __ ldr(reg, FieldMemOperand(scratch, Map::kPrototypeOffset)); | 928         __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | 
| 947       } else { | 929       } else { | 
| 948         // The prototype is in old space; load it directly. | 930         // The prototype is in old space; load it directly. | 
| 949         __ mov(reg, Operand(Handle<JSObject>(prototype))); | 931         __ mov(reg, Operand(Handle<JSObject>(prototype))); | 
| 950       } | 932       } | 
| 951     } | 933     } | 
| 952 | 934 | 
| 953     if (save_at_depth == depth) { | 935     if (save_at_depth == depth) { | 
| 954       __ str(reg, MemOperand(sp)); | 936       __ str(reg, MemOperand(sp)); | 
| 955     } | 937     } | 
| 956 | 938 | 
| 957     // Go to the next object in the prototype chain. | 939     // Go to the next object in the prototype chain. | 
| 958     current = prototype; | 940     current = prototype; | 
| 959   } | 941   } | 
| 960 | 942 | 
| 961   // Check the holder map. | 943   // Check the holder map. | 
| 962   __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); | 944   __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 
| 963   __ cmp(scratch, Operand(Handle<Map>(current->map()))); | 945   __ cmp(scratch1, Operand(Handle<Map>(current->map()))); | 
| 964   __ b(ne, miss); | 946   __ b(ne, miss); | 
| 965 | 947 | 
| 966   // Log the check depth. | 948   // Log the check depth. | 
| 967   LOG(IntEvent("check-maps-depth", depth + 1)); | 949   LOG(IntEvent("check-maps-depth", depth + 1)); | 
| 968 | 950 | 
| 969   // Perform security check for access to the global object and return | 951   // Perform security check for access to the global object and return | 
| 970   // the holder register. | 952   // the holder register. | 
| 971   ASSERT(current == holder); | 953   ASSERT(current == holder); | 
| 972   ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 954   ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 
| 973   if (current->IsJSGlobalProxy()) { | 955   if (current->IsJSGlobalProxy()) { | 
| 974     __ CheckAccessGlobalProxy(reg, scratch, miss); | 956     __ CheckAccessGlobalProxy(reg, scratch1, miss); | 
| 975   } | 957   } | 
| 976 | 958 | 
| 977   // If we've skipped any global objects, it's not enough to verify | 959   // If we've skipped any global objects, it's not enough to verify | 
| 978   // that their maps haven't changed.  We also need to check that the | 960   // that their maps haven't changed.  We also need to check that the | 
| 979   // property cell for the property is still empty. | 961   // property cell for the property is still empty. | 
| 980   current = object; | 962   current = object; | 
| 981   while (current != holder) { | 963   while (current != holder) { | 
| 982     if (current->IsGlobalObject()) { | 964     if (current->IsGlobalObject()) { | 
| 983       Object* cell = GenerateCheckPropertyCell(masm(), | 965       Object* cell = GenerateCheckPropertyCell(masm(), | 
| 984                                                GlobalObject::cast(current), | 966                                                GlobalObject::cast(current), | 
| 985                                                name, | 967                                                name, | 
| 986                                                scratch, | 968                                                scratch1, | 
| 987                                                miss); | 969                                                miss); | 
| 988       if (cell->IsFailure()) { | 970       if (cell->IsFailure()) { | 
| 989         set_failure(Failure::cast(cell)); | 971         set_failure(Failure::cast(cell)); | 
| 990         return reg; | 972         return reg; | 
| 991       } | 973       } | 
| 992     } | 974     } | 
| 993     current = JSObject::cast(current->GetPrototype()); | 975     current = JSObject::cast(current->GetPrototype()); | 
| 994   } | 976   } | 
| 995 | 977 | 
| 996   // Return the register containing the holder. | 978   // Return the register containing the holder. | 
| 997   return reg; | 979   return reg; | 
| 998 } | 980 } | 
| 999 | 981 | 
| 1000 | 982 | 
| 1001 void StubCompiler::GenerateLoadField(JSObject* object, | 983 void StubCompiler::GenerateLoadField(JSObject* object, | 
| 1002                                      JSObject* holder, | 984                                      JSObject* holder, | 
| 1003                                      Register receiver, | 985                                      Register receiver, | 
| 1004                                      Register scratch1, | 986                                      Register scratch1, | 
| 1005                                      Register scratch2, | 987                                      Register scratch2, | 
|  | 988                                      Register scratch3, | 
| 1006                                      int index, | 989                                      int index, | 
| 1007                                      String* name, | 990                                      String* name, | 
| 1008                                      Label* miss) { | 991                                      Label* miss) { | 
| 1009   // Check that the receiver isn't a smi. | 992   // Check that the receiver isn't a smi. | 
| 1010   __ tst(receiver, Operand(kSmiTagMask)); | 993   __ tst(receiver, Operand(kSmiTagMask)); | 
| 1011   __ b(eq, miss); | 994   __ b(eq, miss); | 
| 1012 | 995 | 
| 1013   // Check that the maps haven't changed. | 996   // Check that the maps haven't changed. | 
| 1014   Register reg = | 997   Register reg = | 
| 1015       CheckPrototypes(object, receiver, holder, scratch1, scratch2, name, miss); | 998       CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, | 
|  | 999                       name, miss); | 
| 1016   GenerateFastPropertyLoad(masm(), r0, reg, holder, index); | 1000   GenerateFastPropertyLoad(masm(), r0, reg, holder, index); | 
| 1017   __ Ret(); | 1001   __ Ret(); | 
| 1018 } | 1002 } | 
| 1019 | 1003 | 
| 1020 | 1004 | 
| 1021 void StubCompiler::GenerateLoadConstant(JSObject* object, | 1005 void StubCompiler::GenerateLoadConstant(JSObject* object, | 
| 1022                                         JSObject* holder, | 1006                                         JSObject* holder, | 
| 1023                                         Register receiver, | 1007                                         Register receiver, | 
| 1024                                         Register scratch1, | 1008                                         Register scratch1, | 
| 1025                                         Register scratch2, | 1009                                         Register scratch2, | 
|  | 1010                                         Register scratch3, | 
| 1026                                         Object* value, | 1011                                         Object* value, | 
| 1027                                         String* name, | 1012                                         String* name, | 
| 1028                                         Label* miss) { | 1013                                         Label* miss) { | 
| 1029   // Check that the receiver isn't a smi. | 1014   // Check that the receiver isn't a smi. | 
| 1030   __ tst(receiver, Operand(kSmiTagMask)); | 1015   __ tst(receiver, Operand(kSmiTagMask)); | 
| 1031   __ b(eq, miss); | 1016   __ b(eq, miss); | 
| 1032 | 1017 | 
| 1033   // Check that the maps haven't changed. | 1018   // Check that the maps haven't changed. | 
| 1034   Register reg = | 1019   Register reg = | 
| 1035       CheckPrototypes(object, receiver, holder, scratch1, scratch2, name, miss); | 1020       CheckPrototypes(object, receiver, holder, | 
|  | 1021                       scratch1, scratch2, scratch3, name, miss); | 
| 1036 | 1022 | 
| 1037   // Return the constant value. | 1023   // Return the constant value. | 
| 1038   __ mov(r0, Operand(Handle<Object>(value))); | 1024   __ mov(r0, Operand(Handle<Object>(value))); | 
| 1039   __ Ret(); | 1025   __ Ret(); | 
| 1040 } | 1026 } | 
| 1041 | 1027 | 
| 1042 | 1028 | 
| 1043 bool StubCompiler::GenerateLoadCallback(JSObject* object, | 1029 bool StubCompiler::GenerateLoadCallback(JSObject* object, | 
| 1044                                         JSObject* holder, | 1030                                         JSObject* holder, | 
| 1045                                         Register receiver, | 1031                                         Register receiver, | 
| 1046                                         Register name_reg, | 1032                                         Register name_reg, | 
| 1047                                         Register scratch1, | 1033                                         Register scratch1, | 
| 1048                                         Register scratch2, | 1034                                         Register scratch2, | 
|  | 1035                                         Register scratch3, | 
| 1049                                         AccessorInfo* callback, | 1036                                         AccessorInfo* callback, | 
| 1050                                         String* name, | 1037                                         String* name, | 
| 1051                                         Label* miss, | 1038                                         Label* miss, | 
| 1052                                         Failure** failure) { | 1039                                         Failure** failure) { | 
| 1053   // Check that the receiver isn't a smi. | 1040   // Check that the receiver isn't a smi. | 
| 1054   __ tst(receiver, Operand(kSmiTagMask)); | 1041   __ tst(receiver, Operand(kSmiTagMask)); | 
| 1055   __ b(eq, miss); | 1042   __ b(eq, miss); | 
| 1056 | 1043 | 
| 1057   // Check that the maps haven't changed. | 1044   // Check that the maps haven't changed. | 
| 1058   Register reg = | 1045   Register reg = | 
| 1059       CheckPrototypes(object, receiver, holder, scratch1, scratch2, name, miss); | 1046       CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, | 
|  | 1047                       name, miss); | 
| 1060 | 1048 | 
| 1061   // Push the arguments on the JS stack of the caller. | 1049   // Push the arguments on the JS stack of the caller. | 
| 1062   __ push(receiver);  // Receiver. | 1050   __ push(receiver);  // Receiver. | 
| 1063   __ push(reg);  // Holder. | 1051   __ push(reg);  // Holder. | 
| 1064   __ mov(ip, Operand(Handle<AccessorInfo>(callback)));  // callback data | 1052   __ mov(ip, Operand(Handle<AccessorInfo>(callback)));  // callback data | 
| 1065   __ ldr(reg, FieldMemOperand(ip, AccessorInfo::kDataOffset)); | 1053   __ ldr(reg, FieldMemOperand(ip, AccessorInfo::kDataOffset)); | 
| 1066   __ Push(ip, reg, name_reg); | 1054   __ Push(ip, reg, name_reg); | 
| 1067 | 1055 | 
| 1068   // Do tail-call to the runtime system. | 1056   // Do tail-call to the runtime system. | 
| 1069   ExternalReference load_callback_property = | 1057   ExternalReference load_callback_property = | 
| 1070       ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); | 1058       ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); | 
| 1071   __ TailCallExternalReference(load_callback_property, 5, 1); | 1059   __ TailCallExternalReference(load_callback_property, 5, 1); | 
| 1072 | 1060 | 
| 1073   return true; | 1061   return true; | 
| 1074 } | 1062 } | 
| 1075 | 1063 | 
| 1076 | 1064 | 
| 1077 void StubCompiler::GenerateLoadInterceptor(JSObject* object, | 1065 void StubCompiler::GenerateLoadInterceptor(JSObject* object, | 
| 1078                                            JSObject* interceptor_holder, | 1066                                            JSObject* interceptor_holder, | 
| 1079                                            LookupResult* lookup, | 1067                                            LookupResult* lookup, | 
| 1080                                            Register receiver, | 1068                                            Register receiver, | 
| 1081                                            Register name_reg, | 1069                                            Register name_reg, | 
| 1082                                            Register scratch1, | 1070                                            Register scratch1, | 
| 1083                                            Register scratch2, | 1071                                            Register scratch2, | 
|  | 1072                                            Register scratch3, | 
| 1084                                            String* name, | 1073                                            String* name, | 
| 1085                                            Label* miss) { | 1074                                            Label* miss) { | 
| 1086   ASSERT(interceptor_holder->HasNamedInterceptor()); | 1075   ASSERT(interceptor_holder->HasNamedInterceptor()); | 
| 1087   ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); | 1076   ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); | 
| 1088 | 1077 | 
| 1089   // Check that the receiver isn't a smi. | 1078   // Check that the receiver isn't a smi. | 
| 1090   __ BranchOnSmi(receiver, miss); | 1079   __ BranchOnSmi(receiver, miss); | 
| 1091 | 1080 | 
| 1092   // So far the most popular follow ups for interceptor loads are FIELD | 1081   // So far the most popular follow ups for interceptor loads are FIELD | 
| 1093   // and CALLBACKS, so inline only them, other cases may be added | 1082   // and CALLBACKS, so inline only them, other cases may be added | 
| 1094   // later. | 1083   // later. | 
| 1095   bool compile_followup_inline = false; | 1084   bool compile_followup_inline = false; | 
| 1096   if (lookup->IsProperty() && lookup->IsCacheable()) { | 1085   if (lookup->IsProperty() && lookup->IsCacheable()) { | 
| 1097     if (lookup->type() == FIELD) { | 1086     if (lookup->type() == FIELD) { | 
| 1098       compile_followup_inline = true; | 1087       compile_followup_inline = true; | 
| 1099     } else if (lookup->type() == CALLBACKS && | 1088     } else if (lookup->type() == CALLBACKS && | 
| 1100         lookup->GetCallbackObject()->IsAccessorInfo() && | 1089         lookup->GetCallbackObject()->IsAccessorInfo() && | 
| 1101         AccessorInfo::cast(lookup->GetCallbackObject())->getter() != NULL) { | 1090         AccessorInfo::cast(lookup->GetCallbackObject())->getter() != NULL) { | 
| 1102       compile_followup_inline = true; | 1091       compile_followup_inline = true; | 
| 1103     } | 1092     } | 
| 1104   } | 1093   } | 
| 1105 | 1094 | 
| 1106   if (compile_followup_inline) { | 1095   if (compile_followup_inline) { | 
| 1107     // Compile the interceptor call, followed by inline code to load the | 1096     // Compile the interceptor call, followed by inline code to load the | 
| 1108     // property from further up the prototype chain if the call fails. | 1097     // property from further up the prototype chain if the call fails. | 
| 1109     // Check that the maps haven't changed. | 1098     // Check that the maps haven't changed. | 
| 1110     Register holder_reg = CheckPrototypes(object, receiver, interceptor_holder, | 1099     Register holder_reg = CheckPrototypes(object, receiver, interceptor_holder, | 
| 1111                                           scratch1, scratch2, name, miss); | 1100                                           scratch1, scratch2, scratch3, | 
|  | 1101                                           name, miss); | 
| 1112     ASSERT(holder_reg.is(receiver) || holder_reg.is(scratch1)); | 1102     ASSERT(holder_reg.is(receiver) || holder_reg.is(scratch1)); | 
| 1113 | 1103 | 
| 1114     // Save necessary data before invoking an interceptor. | 1104     // Save necessary data before invoking an interceptor. | 
| 1115     // Requires a frame to make GC aware of pushed pointers. | 1105     // Requires a frame to make GC aware of pushed pointers. | 
| 1116     __ EnterInternalFrame(); | 1106     __ EnterInternalFrame(); | 
| 1117 | 1107 | 
| 1118     if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) { | 1108     if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) { | 
| 1119       // CALLBACKS case needs a receiver to be passed into C++ callback. | 1109       // CALLBACKS case needs a receiver to be passed into C++ callback. | 
| 1120       __ Push(receiver, holder_reg, name_reg); | 1110       __ Push(receiver, holder_reg, name_reg); | 
| 1121     } else { | 1111     } else { | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
| 1150     __ LeaveInternalFrame(); | 1140     __ LeaveInternalFrame(); | 
| 1151 | 1141 | 
| 1152     // Check that the maps from interceptor's holder to lookup's holder | 1142     // Check that the maps from interceptor's holder to lookup's holder | 
| 1153     // haven't changed.  And load lookup's holder into |holder| register. | 1143     // haven't changed.  And load lookup's holder into |holder| register. | 
| 1154     if (interceptor_holder != lookup->holder()) { | 1144     if (interceptor_holder != lookup->holder()) { | 
| 1155       holder_reg = CheckPrototypes(interceptor_holder, | 1145       holder_reg = CheckPrototypes(interceptor_holder, | 
| 1156                                    holder_reg, | 1146                                    holder_reg, | 
| 1157                                    lookup->holder(), | 1147                                    lookup->holder(), | 
| 1158                                    scratch1, | 1148                                    scratch1, | 
| 1159                                    scratch2, | 1149                                    scratch2, | 
|  | 1150                                    scratch3, | 
| 1160                                    name, | 1151                                    name, | 
| 1161                                    miss); | 1152                                    miss); | 
| 1162     } | 1153     } | 
| 1163 | 1154 | 
| 1164     if (lookup->type() == FIELD) { | 1155     if (lookup->type() == FIELD) { | 
| 1165       // We found FIELD property in prototype chain of interceptor's holder. | 1156       // We found FIELD property in prototype chain of interceptor's holder. | 
| 1166       // Retrieve a field from field's holder. | 1157       // Retrieve a field from field's holder. | 
| 1167       GenerateFastPropertyLoad(masm(), r0, holder_reg, | 1158       GenerateFastPropertyLoad(masm(), r0, holder_reg, | 
| 1168                                lookup->holder(), lookup->GetFieldIndex()); | 1159                                lookup->holder(), lookup->GetFieldIndex()); | 
| 1169       __ Ret(); | 1160       __ Ret(); | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 1195       } | 1186       } | 
| 1196 | 1187 | 
| 1197       ExternalReference ref = | 1188       ExternalReference ref = | 
| 1198           ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); | 1189           ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); | 
| 1199       __ TailCallExternalReference(ref, 5, 1); | 1190       __ TailCallExternalReference(ref, 5, 1); | 
| 1200     } | 1191     } | 
| 1201   } else {  // !compile_followup_inline | 1192   } else {  // !compile_followup_inline | 
| 1202     // Call the runtime system to load the interceptor. | 1193     // Call the runtime system to load the interceptor. | 
| 1203     // Check that the maps haven't changed. | 1194     // Check that the maps haven't changed. | 
| 1204     Register holder_reg = CheckPrototypes(object, receiver, interceptor_holder, | 1195     Register holder_reg = CheckPrototypes(object, receiver, interceptor_holder, | 
| 1205                                           scratch1, scratch2, name, miss); | 1196                                           scratch1, scratch2, scratch3, | 
|  | 1197                                           name, miss); | 
| 1206     PushInterceptorArguments(masm(), receiver, holder_reg, | 1198     PushInterceptorArguments(masm(), receiver, holder_reg, | 
| 1207                              name_reg, interceptor_holder); | 1199                              name_reg, interceptor_holder); | 
| 1208 | 1200 | 
| 1209     ExternalReference ref = ExternalReference( | 1201     ExternalReference ref = ExternalReference( | 
| 1210         IC_Utility(IC::kLoadPropertyWithInterceptorForLoad)); | 1202         IC_Utility(IC::kLoadPropertyWithInterceptorForLoad)); | 
| 1211     __ TailCallExternalReference(ref, 5, 1); | 1203     __ TailCallExternalReference(ref, 5, 1); | 
| 1212   } | 1204   } | 
| 1213 } | 1205 } | 
| 1214 | 1206 | 
| 1215 | 1207 | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1273 | 1265 | 
| 1274   const int argc = arguments().immediate(); | 1266   const int argc = arguments().immediate(); | 
| 1275 | 1267 | 
| 1276   // Get the receiver of the function from the stack into r0. | 1268   // Get the receiver of the function from the stack into r0. | 
| 1277   __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 1269   __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 
| 1278   // Check that the receiver isn't a smi. | 1270   // Check that the receiver isn't a smi. | 
| 1279   __ tst(r0, Operand(kSmiTagMask)); | 1271   __ tst(r0, Operand(kSmiTagMask)); | 
| 1280   __ b(eq, &miss); | 1272   __ b(eq, &miss); | 
| 1281 | 1273 | 
| 1282   // Do the right check and compute the holder register. | 1274   // Do the right check and compute the holder register. | 
| 1283   Register reg = CheckPrototypes(object, r0, holder, r1, r3, name, &miss, r4); | 1275   Register reg = CheckPrototypes(object, r0, holder, r1, r3, r4, name, &miss); | 
| 1284   GenerateFastPropertyLoad(masm(), r1, reg, holder, index); | 1276   GenerateFastPropertyLoad(masm(), r1, reg, holder, index); | 
| 1285 | 1277 | 
| 1286   GenerateCallFunction(masm(), object, arguments(), &miss); | 1278   GenerateCallFunction(masm(), object, arguments(), &miss); | 
| 1287 | 1279 | 
| 1288   // Handle call cache miss. | 1280   // Handle call cache miss. | 
| 1289   __ bind(&miss); | 1281   __ bind(&miss); | 
| 1290   GenerateMissBranch(); | 1282   GenerateMissBranch(); | 
| 1291 | 1283 | 
| 1292   // Return the generated code. | 1284   // Return the generated code. | 
| 1293   return GetCode(FIELD, name); | 1285   return GetCode(FIELD, name); | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
| 1318 | 1310 | 
| 1319   // Get the receiver from the stack | 1311   // Get the receiver from the stack | 
| 1320   const int argc = arguments().immediate(); | 1312   const int argc = arguments().immediate(); | 
| 1321   __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 1313   __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 
| 1322 | 1314 | 
| 1323   // Check that the receiver isn't a smi. | 1315   // Check that the receiver isn't a smi. | 
| 1324   __ tst(r1, Operand(kSmiTagMask)); | 1316   __ tst(r1, Operand(kSmiTagMask)); | 
| 1325   __ b(eq, &miss); | 1317   __ b(eq, &miss); | 
| 1326 | 1318 | 
| 1327   // Check that the maps haven't changed. | 1319   // Check that the maps haven't changed. | 
| 1328   CheckPrototypes(JSObject::cast(object), r1, holder, r3, r0, name, &miss, r4); | 1320   CheckPrototypes(JSObject::cast(object), r1, holder, r3, r0, r4, name, &miss); | 
| 1329 | 1321 | 
| 1330   if (object->IsGlobalObject()) { | 1322   if (object->IsGlobalObject()) { | 
| 1331     __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 1323     __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 
| 1332     __ str(r3, MemOperand(sp, argc * kPointerSize)); | 1324     __ str(r3, MemOperand(sp, argc * kPointerSize)); | 
| 1333   } | 1325   } | 
| 1334 | 1326 | 
| 1335   __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush), | 1327   __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush), | 
| 1336                                argc + 1, | 1328                                argc + 1, | 
| 1337                                1); | 1329                                1); | 
| 1338 | 1330 | 
| (...skipping 30 matching lines...) Expand all  Loading... | 
| 1369 | 1361 | 
| 1370   // Get the receiver from the stack | 1362   // Get the receiver from the stack | 
| 1371   const int argc = arguments().immediate(); | 1363   const int argc = arguments().immediate(); | 
| 1372   __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 1364   __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 
| 1373 | 1365 | 
| 1374   // Check that the receiver isn't a smi. | 1366   // Check that the receiver isn't a smi. | 
| 1375   __ tst(r1, Operand(kSmiTagMask)); | 1367   __ tst(r1, Operand(kSmiTagMask)); | 
| 1376   __ b(eq, &miss); | 1368   __ b(eq, &miss); | 
| 1377 | 1369 | 
| 1378   // Check that the maps haven't changed. | 1370   // Check that the maps haven't changed. | 
| 1379   CheckPrototypes(JSObject::cast(object), r1, holder, r3, r0, name, &miss, r4); | 1371   CheckPrototypes(JSObject::cast(object), r1, holder, r3, r0, r4, name, &miss); | 
| 1380 | 1372 | 
| 1381   if (object->IsGlobalObject()) { | 1373   if (object->IsGlobalObject()) { | 
| 1382     __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 1374     __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 
| 1383     __ str(r3, MemOperand(sp, argc * kPointerSize)); | 1375     __ str(r3, MemOperand(sp, argc * kPointerSize)); | 
| 1384   } | 1376   } | 
| 1385 | 1377 | 
| 1386   __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop), | 1378   __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop), | 
| 1387                                argc + 1, | 1379                                argc + 1, | 
| 1388                                1); | 1380                                1); | 
| 1389 | 1381 | 
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1466         depth = optimization.GetPrototypeDepthOfExpectedType( | 1458         depth = optimization.GetPrototypeDepthOfExpectedType( | 
| 1467             JSObject::cast(object), holder); | 1459             JSObject::cast(object), holder); | 
| 1468       } | 1460       } | 
| 1469 | 1461 | 
| 1470       if (depth != kInvalidProtoDepth) { | 1462       if (depth != kInvalidProtoDepth) { | 
| 1471         __ IncrementCounter(&Counters::call_const_fast_api, 1, r0, r3); | 1463         __ IncrementCounter(&Counters::call_const_fast_api, 1, r0, r3); | 
| 1472         ReserveSpaceForFastApiCall(masm(), r0); | 1464         ReserveSpaceForFastApiCall(masm(), r0); | 
| 1473       } | 1465       } | 
| 1474 | 1466 | 
| 1475       // Check that the maps haven't changed. | 1467       // Check that the maps haven't changed. | 
| 1476       CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, name, | 1468       CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, | 
| 1477                       depth, &miss, r4); | 1469                       depth, &miss); | 
| 1478 | 1470 | 
| 1479       // Patch the receiver on the stack with the global proxy if | 1471       // Patch the receiver on the stack with the global proxy if | 
| 1480       // necessary. | 1472       // necessary. | 
| 1481       if (object->IsGlobalObject()) { | 1473       if (object->IsGlobalObject()) { | 
| 1482         ASSERT(depth == kInvalidProtoDepth); | 1474         ASSERT(depth == kInvalidProtoDepth); | 
| 1483         __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 1475         __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 
| 1484         __ str(r3, MemOperand(sp, argc * kPointerSize)); | 1476         __ str(r3, MemOperand(sp, argc * kPointerSize)); | 
| 1485       } | 1477       } | 
| 1486       break; | 1478       break; | 
| 1487 | 1479 | 
| 1488     case STRING_CHECK: | 1480     case STRING_CHECK: | 
| 1489       if (!function->IsBuiltin()) { | 1481       if (!function->IsBuiltin()) { | 
| 1490         // Calling non-builtins with a value as receiver requires boxing. | 1482         // Calling non-builtins with a value as receiver requires boxing. | 
| 1491         __ jmp(&miss); | 1483         __ jmp(&miss); | 
| 1492       } else { | 1484       } else { | 
| 1493         // Check that the object is a two-byte string or a symbol. | 1485         // Check that the object is a two-byte string or a symbol. | 
| 1494         __ CompareObjectType(r1, r3, r3, FIRST_NONSTRING_TYPE); | 1486         __ CompareObjectType(r1, r3, r3, FIRST_NONSTRING_TYPE); | 
| 1495         __ b(hs, &miss); | 1487         __ b(hs, &miss); | 
| 1496         // Check that the maps starting from the prototype haven't changed. | 1488         // Check that the maps starting from the prototype haven't changed. | 
| 1497         GenerateDirectLoadGlobalFunctionPrototype( | 1489         GenerateDirectLoadGlobalFunctionPrototype( | 
| 1498             masm(), Context::STRING_FUNCTION_INDEX, r0); | 1490             masm(), Context::STRING_FUNCTION_INDEX, r0); | 
| 1499         CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, r3, | 1491         CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, r3, | 
| 1500                         r1, name, &miss, r4); | 1492                         r1, r4, name, &miss); | 
| 1501       } | 1493       } | 
| 1502       break; | 1494       break; | 
| 1503 | 1495 | 
| 1504     case NUMBER_CHECK: { | 1496     case NUMBER_CHECK: { | 
| 1505       if (!function->IsBuiltin()) { | 1497       if (!function->IsBuiltin()) { | 
| 1506         // Calling non-builtins with a value as receiver requires boxing. | 1498         // Calling non-builtins with a value as receiver requires boxing. | 
| 1507         __ jmp(&miss); | 1499         __ jmp(&miss); | 
| 1508       } else { | 1500       } else { | 
| 1509         Label fast; | 1501         Label fast; | 
| 1510         // Check that the object is a smi or a heap number. | 1502         // Check that the object is a smi or a heap number. | 
| 1511         __ tst(r1, Operand(kSmiTagMask)); | 1503         __ tst(r1, Operand(kSmiTagMask)); | 
| 1512         __ b(eq, &fast); | 1504         __ b(eq, &fast); | 
| 1513         __ CompareObjectType(r1, r0, r0, HEAP_NUMBER_TYPE); | 1505         __ CompareObjectType(r1, r0, r0, HEAP_NUMBER_TYPE); | 
| 1514         __ b(ne, &miss); | 1506         __ b(ne, &miss); | 
| 1515         __ bind(&fast); | 1507         __ bind(&fast); | 
| 1516         // Check that the maps starting from the prototype haven't changed. | 1508         // Check that the maps starting from the prototype haven't changed. | 
| 1517         GenerateDirectLoadGlobalFunctionPrototype( | 1509         GenerateDirectLoadGlobalFunctionPrototype( | 
| 1518             masm(), Context::NUMBER_FUNCTION_INDEX, r0); | 1510             masm(), Context::NUMBER_FUNCTION_INDEX, r0); | 
| 1519         CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, r3, | 1511         CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, r3, | 
| 1520                         r1, name, &miss, r4); | 1512                         r1, r4, name, &miss); | 
| 1521       } | 1513       } | 
| 1522       break; | 1514       break; | 
| 1523     } | 1515     } | 
| 1524 | 1516 | 
| 1525     case BOOLEAN_CHECK: { | 1517     case BOOLEAN_CHECK: { | 
| 1526       if (!function->IsBuiltin()) { | 1518       if (!function->IsBuiltin()) { | 
| 1527         // Calling non-builtins with a value as receiver requires boxing. | 1519         // Calling non-builtins with a value as receiver requires boxing. | 
| 1528         __ jmp(&miss); | 1520         __ jmp(&miss); | 
| 1529       } else { | 1521       } else { | 
| 1530         Label fast; | 1522         Label fast; | 
| 1531         // Check that the object is a boolean. | 1523         // Check that the object is a boolean. | 
| 1532         __ LoadRoot(ip, Heap::kTrueValueRootIndex); | 1524         __ LoadRoot(ip, Heap::kTrueValueRootIndex); | 
| 1533         __ cmp(r1, ip); | 1525         __ cmp(r1, ip); | 
| 1534         __ b(eq, &fast); | 1526         __ b(eq, &fast); | 
| 1535         __ LoadRoot(ip, Heap::kFalseValueRootIndex); | 1527         __ LoadRoot(ip, Heap::kFalseValueRootIndex); | 
| 1536         __ cmp(r1, ip); | 1528         __ cmp(r1, ip); | 
| 1537         __ b(ne, &miss); | 1529         __ b(ne, &miss); | 
| 1538         __ bind(&fast); | 1530         __ bind(&fast); | 
| 1539         // Check that the maps starting from the prototype haven't changed. | 1531         // Check that the maps starting from the prototype haven't changed. | 
| 1540         GenerateDirectLoadGlobalFunctionPrototype( | 1532         GenerateDirectLoadGlobalFunctionPrototype( | 
| 1541             masm(), Context::BOOLEAN_FUNCTION_INDEX, r0); | 1533             masm(), Context::BOOLEAN_FUNCTION_INDEX, r0); | 
| 1542         CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, r3, | 1534         CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, r3, | 
| 1543                         r1, name, &miss, r4); | 1535                         r1, r4, name, &miss); | 
| 1544       } | 1536       } | 
| 1545       break; | 1537       break; | 
| 1546     } | 1538     } | 
| 1547 | 1539 | 
| 1548     default: | 1540     default: | 
| 1549       UNREACHABLE(); | 1541       UNREACHABLE(); | 
| 1550   } | 1542   } | 
| 1551 | 1543 | 
| 1552   if (depth != kInvalidProtoDepth) { | 1544   if (depth != kInvalidProtoDepth) { | 
| 1553     GenerateFastApiCall(masm(), optimization, argc); | 1545     GenerateFastApiCall(masm(), optimization, argc); | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1592 | 1584 | 
| 1593   CallInterceptorCompiler compiler(this, arguments(), r2); | 1585   CallInterceptorCompiler compiler(this, arguments(), r2); | 
| 1594   compiler.Compile(masm(), | 1586   compiler.Compile(masm(), | 
| 1595                    object, | 1587                    object, | 
| 1596                    holder, | 1588                    holder, | 
| 1597                    name, | 1589                    name, | 
| 1598                    &lookup, | 1590                    &lookup, | 
| 1599                    r1, | 1591                    r1, | 
| 1600                    r3, | 1592                    r3, | 
| 1601                    r4, | 1593                    r4, | 
|  | 1594                    r0, | 
| 1602                    &miss); | 1595                    &miss); | 
| 1603 | 1596 | 
| 1604   // Move returned value, the function to call, to r1. | 1597   // Move returned value, the function to call, to r1. | 
| 1605   __ mov(r1, r0); | 1598   __ mov(r1, r0); | 
| 1606   // Restore receiver. | 1599   // Restore receiver. | 
| 1607   __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 1600   __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 
| 1608 | 1601 | 
| 1609   GenerateCallFunction(masm(), object, arguments(), &miss); | 1602   GenerateCallFunction(masm(), object, arguments(), &miss); | 
| 1610 | 1603 | 
| 1611   // Handle call cache miss. | 1604   // Handle call cache miss. | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
| 1638 | 1631 | 
| 1639   // If the object is the holder then we know that it's a global | 1632   // If the object is the holder then we know that it's a global | 
| 1640   // object which can only happen for contextual calls. In this case, | 1633   // object which can only happen for contextual calls. In this case, | 
| 1641   // the receiver cannot be a smi. | 1634   // the receiver cannot be a smi. | 
| 1642   if (object != holder) { | 1635   if (object != holder) { | 
| 1643     __ tst(r0, Operand(kSmiTagMask)); | 1636     __ tst(r0, Operand(kSmiTagMask)); | 
| 1644     __ b(eq, &miss); | 1637     __ b(eq, &miss); | 
| 1645   } | 1638   } | 
| 1646 | 1639 | 
| 1647   // Check that the maps haven't changed. | 1640   // Check that the maps haven't changed. | 
| 1648   CheckPrototypes(object, r0, holder, r3, r1, name, &miss, r4); | 1641   CheckPrototypes(object, r0, holder, r3, r1, r4, name, &miss); | 
| 1649 | 1642 | 
| 1650   // Get the value from the cell. | 1643   // Get the value from the cell. | 
| 1651   __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell))); | 1644   __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell))); | 
| 1652   __ ldr(r1, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); | 1645   __ ldr(r1, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); | 
| 1653 | 1646 | 
| 1654   // Check that the cell contains the same function. | 1647   // Check that the cell contains the same function. | 
| 1655   if (Heap::InNewSpace(function)) { | 1648   if (Heap::InNewSpace(function)) { | 
| 1656     // We can't embed a pointer to a function in new space so we have | 1649     // We can't embed a pointer to a function in new space so we have | 
| 1657     // to verify that the shared function info is unchanged. This has | 1650     // to verify that the shared function info is unchanged. This has | 
| 1658     // the nice side effect that multiple closures based on the same | 1651     // the nice side effect that multiple closures based on the same | 
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1862   //  -- r0    : receiver | 1855   //  -- r0    : receiver | 
| 1863   //  -- lr    : return address | 1856   //  -- lr    : return address | 
| 1864   // ----------------------------------- | 1857   // ----------------------------------- | 
| 1865   Label miss; | 1858   Label miss; | 
| 1866 | 1859 | 
| 1867   // Check that receiver is not a smi. | 1860   // Check that receiver is not a smi. | 
| 1868   __ tst(r0, Operand(kSmiTagMask)); | 1861   __ tst(r0, Operand(kSmiTagMask)); | 
| 1869   __ b(eq, &miss); | 1862   __ b(eq, &miss); | 
| 1870 | 1863 | 
| 1871   // Check the maps of the full prototype chain. | 1864   // Check the maps of the full prototype chain. | 
| 1872   CheckPrototypes(object, r0, last, r3, r1, name, &miss, r4); | 1865   CheckPrototypes(object, r0, last, r3, r1, r4, name, &miss); | 
| 1873 | 1866 | 
| 1874   // If the last object in the prototype chain is a global object, | 1867   // If the last object in the prototype chain is a global object, | 
| 1875   // check that the global property cell is empty. | 1868   // check that the global property cell is empty. | 
| 1876   if (last->IsGlobalObject()) { | 1869   if (last->IsGlobalObject()) { | 
| 1877     Object* cell = GenerateCheckPropertyCell(masm(), | 1870     Object* cell = GenerateCheckPropertyCell(masm(), | 
| 1878                                              GlobalObject::cast(last), | 1871                                              GlobalObject::cast(last), | 
| 1879                                              name, | 1872                                              name, | 
| 1880                                              r1, | 1873                                              r1, | 
| 1881                                              &miss); | 1874                                              &miss); | 
| 1882     if (cell->IsFailure()) return cell; | 1875     if (cell->IsFailure()) return cell; | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 1899                                            JSObject* holder, | 1892                                            JSObject* holder, | 
| 1900                                            int index, | 1893                                            int index, | 
| 1901                                            String* name) { | 1894                                            String* name) { | 
| 1902   // ----------- S t a t e ------------- | 1895   // ----------- S t a t e ------------- | 
| 1903   //  -- r0    : receiver | 1896   //  -- r0    : receiver | 
| 1904   //  -- r2    : name | 1897   //  -- r2    : name | 
| 1905   //  -- lr    : return address | 1898   //  -- lr    : return address | 
| 1906   // ----------------------------------- | 1899   // ----------------------------------- | 
| 1907   Label miss; | 1900   Label miss; | 
| 1908 | 1901 | 
| 1909   GenerateLoadField(object, holder, r0, r3, r1, index, name, &miss); | 1902   GenerateLoadField(object, holder, r0, r3, r1, r4, index, name, &miss); | 
| 1910   __ bind(&miss); | 1903   __ bind(&miss); | 
| 1911   GenerateLoadMiss(masm(), Code::LOAD_IC); | 1904   GenerateLoadMiss(masm(), Code::LOAD_IC); | 
| 1912 | 1905 | 
| 1913   // Return the generated code. | 1906   // Return the generated code. | 
| 1914   return GetCode(FIELD, name); | 1907   return GetCode(FIELD, name); | 
| 1915 } | 1908 } | 
| 1916 | 1909 | 
| 1917 | 1910 | 
| 1918 Object* LoadStubCompiler::CompileLoadCallback(String* name, | 1911 Object* LoadStubCompiler::CompileLoadCallback(String* name, | 
| 1919                                               JSObject* object, | 1912                                               JSObject* object, | 
| 1920                                               JSObject* holder, | 1913                                               JSObject* holder, | 
| 1921                                               AccessorInfo* callback) { | 1914                                               AccessorInfo* callback) { | 
| 1922   // ----------- S t a t e ------------- | 1915   // ----------- S t a t e ------------- | 
| 1923   //  -- r0    : receiver | 1916   //  -- r0    : receiver | 
| 1924   //  -- r2    : name | 1917   //  -- r2    : name | 
| 1925   //  -- lr    : return address | 1918   //  -- lr    : return address | 
| 1926   // ----------------------------------- | 1919   // ----------------------------------- | 
| 1927   Label miss; | 1920   Label miss; | 
| 1928 | 1921 | 
| 1929   Failure* failure = Failure::InternalError(); | 1922   Failure* failure = Failure::InternalError(); | 
| 1930   bool success = GenerateLoadCallback(object, holder, r0, r2, r3, r1, | 1923   bool success = GenerateLoadCallback(object, holder, r0, r2, r3, r1, r4, | 
| 1931                                       callback, name, &miss, &failure); | 1924                                       callback, name, &miss, &failure); | 
| 1932   if (!success) return failure; | 1925   if (!success) return failure; | 
| 1933 | 1926 | 
| 1934   __ bind(&miss); | 1927   __ bind(&miss); | 
| 1935   GenerateLoadMiss(masm(), Code::LOAD_IC); | 1928   GenerateLoadMiss(masm(), Code::LOAD_IC); | 
| 1936 | 1929 | 
| 1937   // Return the generated code. | 1930   // Return the generated code. | 
| 1938   return GetCode(CALLBACKS, name); | 1931   return GetCode(CALLBACKS, name); | 
| 1939 } | 1932 } | 
| 1940 | 1933 | 
| 1941 | 1934 | 
| 1942 Object* LoadStubCompiler::CompileLoadConstant(JSObject* object, | 1935 Object* LoadStubCompiler::CompileLoadConstant(JSObject* object, | 
| 1943                                               JSObject* holder, | 1936                                               JSObject* holder, | 
| 1944                                               Object* value, | 1937                                               Object* value, | 
| 1945                                               String* name) { | 1938                                               String* name) { | 
| 1946   // ----------- S t a t e ------------- | 1939   // ----------- S t a t e ------------- | 
| 1947   //  -- r0    : receiver | 1940   //  -- r0    : receiver | 
| 1948   //  -- r2    : name | 1941   //  -- r2    : name | 
| 1949   //  -- lr    : return address | 1942   //  -- lr    : return address | 
| 1950   // ----------------------------------- | 1943   // ----------------------------------- | 
| 1951   Label miss; | 1944   Label miss; | 
| 1952 | 1945 | 
| 1953   GenerateLoadConstant(object, holder, r0, r3, r1, value, name, &miss); | 1946   GenerateLoadConstant(object, holder, r0, r3, r1, r4, value, name, &miss); | 
| 1954   __ bind(&miss); | 1947   __ bind(&miss); | 
| 1955   GenerateLoadMiss(masm(), Code::LOAD_IC); | 1948   GenerateLoadMiss(masm(), Code::LOAD_IC); | 
| 1956 | 1949 | 
| 1957   // Return the generated code. | 1950   // Return the generated code. | 
| 1958   return GetCode(CONSTANT_FUNCTION, name); | 1951   return GetCode(CONSTANT_FUNCTION, name); | 
| 1959 } | 1952 } | 
| 1960 | 1953 | 
| 1961 | 1954 | 
| 1962 Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* object, | 1955 Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* object, | 
| 1963                                                  JSObject* holder, | 1956                                                  JSObject* holder, | 
| 1964                                                  String* name) { | 1957                                                  String* name) { | 
| 1965   // ----------- S t a t e ------------- | 1958   // ----------- S t a t e ------------- | 
| 1966   //  -- r0    : receiver | 1959   //  -- r0    : receiver | 
| 1967   //  -- r2    : name | 1960   //  -- r2    : name | 
| 1968   //  -- lr    : return address | 1961   //  -- lr    : return address | 
| 1969   // ----------------------------------- | 1962   // ----------------------------------- | 
| 1970   Label miss; | 1963   Label miss; | 
| 1971 | 1964 | 
| 1972   LookupResult lookup; | 1965   LookupResult lookup; | 
| 1973   LookupPostInterceptor(holder, name, &lookup); | 1966   LookupPostInterceptor(holder, name, &lookup); | 
| 1974   GenerateLoadInterceptor(object, | 1967   GenerateLoadInterceptor(object, | 
| 1975                           holder, | 1968                           holder, | 
| 1976                           &lookup, | 1969                           &lookup, | 
| 1977                           r0, | 1970                           r0, | 
| 1978                           r2, | 1971                           r2, | 
| 1979                           r3, | 1972                           r3, | 
| 1980                           r1, | 1973                           r1, | 
|  | 1974                           r4, | 
| 1981                           name, | 1975                           name, | 
| 1982                           &miss); | 1976                           &miss); | 
| 1983   __ bind(&miss); | 1977   __ bind(&miss); | 
| 1984   GenerateLoadMiss(masm(), Code::LOAD_IC); | 1978   GenerateLoadMiss(masm(), Code::LOAD_IC); | 
| 1985 | 1979 | 
| 1986   // Return the generated code. | 1980   // Return the generated code. | 
| 1987   return GetCode(INTERCEPTOR, name); | 1981   return GetCode(INTERCEPTOR, name); | 
| 1988 } | 1982 } | 
| 1989 | 1983 | 
| 1990 | 1984 | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 2002 | 1996 | 
| 2003   // If the object is the holder then we know that it's a global | 1997   // If the object is the holder then we know that it's a global | 
| 2004   // object which can only happen for contextual calls. In this case, | 1998   // object which can only happen for contextual calls. In this case, | 
| 2005   // the receiver cannot be a smi. | 1999   // the receiver cannot be a smi. | 
| 2006   if (object != holder) { | 2000   if (object != holder) { | 
| 2007     __ tst(r0, Operand(kSmiTagMask)); | 2001     __ tst(r0, Operand(kSmiTagMask)); | 
| 2008     __ b(eq, &miss); | 2002     __ b(eq, &miss); | 
| 2009   } | 2003   } | 
| 2010 | 2004 | 
| 2011   // Check that the map of the global has not changed. | 2005   // Check that the map of the global has not changed. | 
| 2012   CheckPrototypes(object, r0, holder, r3, r4, name, &miss, r1); | 2006   CheckPrototypes(object, r0, holder, r3, r4, r1, name, &miss); | 
| 2013 | 2007 | 
| 2014   // Get the value from the cell. | 2008   // Get the value from the cell. | 
| 2015   __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell))); | 2009   __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell))); | 
| 2016   __ ldr(r4, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); | 2010   __ ldr(r4, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); | 
| 2017 | 2011 | 
| 2018   // Check for deleted property if property can actually be deleted. | 2012   // Check for deleted property if property can actually be deleted. | 
| 2019   if (!is_dont_delete) { | 2013   if (!is_dont_delete) { | 
| 2020     __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 2014     __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 
| 2021     __ cmp(r4, ip); | 2015     __ cmp(r4, ip); | 
| 2022     __ b(eq, &miss); | 2016     __ b(eq, &miss); | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 2043   //  -- lr    : return address | 2037   //  -- lr    : return address | 
| 2044   //  -- r0    : key | 2038   //  -- r0    : key | 
| 2045   //  -- r1    : receiver | 2039   //  -- r1    : receiver | 
| 2046   // ----------------------------------- | 2040   // ----------------------------------- | 
| 2047   Label miss; | 2041   Label miss; | 
| 2048 | 2042 | 
| 2049   // Check the key is the cached one. | 2043   // Check the key is the cached one. | 
| 2050   __ cmp(r0, Operand(Handle<String>(name))); | 2044   __ cmp(r0, Operand(Handle<String>(name))); | 
| 2051   __ b(ne, &miss); | 2045   __ b(ne, &miss); | 
| 2052 | 2046 | 
| 2053   GenerateLoadField(receiver, holder, r1, r2, r3, index, name, &miss); | 2047   GenerateLoadField(receiver, holder, r1, r2, r3, r4, index, name, &miss); | 
| 2054   __ bind(&miss); | 2048   __ bind(&miss); | 
| 2055   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2049   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| 2056 | 2050 | 
| 2057   return GetCode(FIELD, name); | 2051   return GetCode(FIELD, name); | 
| 2058 } | 2052 } | 
| 2059 | 2053 | 
| 2060 | 2054 | 
| 2061 Object* KeyedLoadStubCompiler::CompileLoadCallback(String* name, | 2055 Object* KeyedLoadStubCompiler::CompileLoadCallback(String* name, | 
| 2062                                                    JSObject* receiver, | 2056                                                    JSObject* receiver, | 
| 2063                                                    JSObject* holder, | 2057                                                    JSObject* holder, | 
| 2064                                                    AccessorInfo* callback) { | 2058                                                    AccessorInfo* callback) { | 
| 2065   // ----------- S t a t e ------------- | 2059   // ----------- S t a t e ------------- | 
| 2066   //  -- lr    : return address | 2060   //  -- lr    : return address | 
| 2067   //  -- r0    : key | 2061   //  -- r0    : key | 
| 2068   //  -- r1    : receiver | 2062   //  -- r1    : receiver | 
| 2069   // ----------------------------------- | 2063   // ----------------------------------- | 
| 2070   Label miss; | 2064   Label miss; | 
| 2071 | 2065 | 
| 2072   // Check the key is the cached one. | 2066   // Check the key is the cached one. | 
| 2073   __ cmp(r0, Operand(Handle<String>(name))); | 2067   __ cmp(r0, Operand(Handle<String>(name))); | 
| 2074   __ b(ne, &miss); | 2068   __ b(ne, &miss); | 
| 2075 | 2069 | 
| 2076   Failure* failure = Failure::InternalError(); | 2070   Failure* failure = Failure::InternalError(); | 
| 2077   bool success = GenerateLoadCallback(receiver, holder, r1, r0, r2, r3, | 2071   bool success = GenerateLoadCallback(receiver, holder, r1, r0, r2, r3, r4, | 
| 2078                                       callback, name, &miss, &failure); | 2072                                       callback, name, &miss, &failure); | 
| 2079   if (!success) return failure; | 2073   if (!success) return failure; | 
| 2080 | 2074 | 
| 2081   __ bind(&miss); | 2075   __ bind(&miss); | 
| 2082   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2076   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| 2083 | 2077 | 
| 2084   return GetCode(CALLBACKS, name); | 2078   return GetCode(CALLBACKS, name); | 
| 2085 } | 2079 } | 
| 2086 | 2080 | 
| 2087 | 2081 | 
| 2088 Object* KeyedLoadStubCompiler::CompileLoadConstant(String* name, | 2082 Object* KeyedLoadStubCompiler::CompileLoadConstant(String* name, | 
| 2089                                                    JSObject* receiver, | 2083                                                    JSObject* receiver, | 
| 2090                                                    JSObject* holder, | 2084                                                    JSObject* holder, | 
| 2091                                                    Object* value) { | 2085                                                    Object* value) { | 
| 2092   // ----------- S t a t e ------------- | 2086   // ----------- S t a t e ------------- | 
| 2093   //  -- lr    : return address | 2087   //  -- lr    : return address | 
| 2094   //  -- r0    : key | 2088   //  -- r0    : key | 
| 2095   //  -- r1    : receiver | 2089   //  -- r1    : receiver | 
| 2096   // ----------------------------------- | 2090   // ----------------------------------- | 
| 2097   Label miss; | 2091   Label miss; | 
| 2098 | 2092 | 
| 2099   // Check the key is the cached one. | 2093   // Check the key is the cached one. | 
| 2100   __ cmp(r0, Operand(Handle<String>(name))); | 2094   __ cmp(r0, Operand(Handle<String>(name))); | 
| 2101   __ b(ne, &miss); | 2095   __ b(ne, &miss); | 
| 2102 | 2096 | 
| 2103   GenerateLoadConstant(receiver, holder, r1, r2, r3, value, name, &miss); | 2097   GenerateLoadConstant(receiver, holder, r1, r2, r3, r4, value, name, &miss); | 
| 2104   __ bind(&miss); | 2098   __ bind(&miss); | 
| 2105   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2099   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| 2106 | 2100 | 
| 2107   // Return the generated code. | 2101   // Return the generated code. | 
| 2108   return GetCode(CONSTANT_FUNCTION, name); | 2102   return GetCode(CONSTANT_FUNCTION, name); | 
| 2109 } | 2103 } | 
| 2110 | 2104 | 
| 2111 | 2105 | 
| 2112 Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 2106 Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 
| 2113                                                       JSObject* holder, | 2107                                                       JSObject* holder, | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 2125 | 2119 | 
| 2126   LookupResult lookup; | 2120   LookupResult lookup; | 
| 2127   LookupPostInterceptor(holder, name, &lookup); | 2121   LookupPostInterceptor(holder, name, &lookup); | 
| 2128   GenerateLoadInterceptor(receiver, | 2122   GenerateLoadInterceptor(receiver, | 
| 2129                           holder, | 2123                           holder, | 
| 2130                           &lookup, | 2124                           &lookup, | 
| 2131                           r1, | 2125                           r1, | 
| 2132                           r0, | 2126                           r0, | 
| 2133                           r2, | 2127                           r2, | 
| 2134                           r3, | 2128                           r3, | 
|  | 2129                           r4, | 
| 2135                           name, | 2130                           name, | 
| 2136                           &miss); | 2131                           &miss); | 
| 2137   __ bind(&miss); | 2132   __ bind(&miss); | 
| 2138   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2133   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 
| 2139 | 2134 | 
| 2140   return GetCode(INTERCEPTOR, name); | 2135   return GetCode(INTERCEPTOR, name); | 
| 2141 } | 2136 } | 
| 2142 | 2137 | 
| 2143 | 2138 | 
| 2144 Object* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { | 2139 Object* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { | 
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2376   // Return the generated code. | 2371   // Return the generated code. | 
| 2377   return GetCode(); | 2372   return GetCode(); | 
| 2378 } | 2373 } | 
| 2379 | 2374 | 
| 2380 | 2375 | 
| 2381 #undef __ | 2376 #undef __ | 
| 2382 | 2377 | 
| 2383 } }  // namespace v8::internal | 2378 } }  // namespace v8::internal | 
| 2384 | 2379 | 
| 2385 #endif  // V8_TARGET_ARCH_ARM | 2380 #endif  // V8_TARGET_ARCH_ARM | 
| OLD | NEW | 
|---|