| 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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 86                                              Label* miss_label, | 86                                              Label* miss_label, | 
| 87                                              Register receiver, | 87                                              Register receiver, | 
| 88                                              String* name, | 88                                              String* name, | 
| 89                                              Register r0, | 89                                              Register r0, | 
| 90                                              Register r1) { | 90                                              Register r1) { | 
| 91   ASSERT(name->IsSymbol()); | 91   ASSERT(name->IsSymbol()); | 
| 92   Counters* counters = masm->isolate()->counters(); | 92   Counters* counters = masm->isolate()->counters(); | 
| 93   __ IncrementCounter(counters->negative_lookups(), 1); | 93   __ IncrementCounter(counters->negative_lookups(), 1); | 
| 94   __ IncrementCounter(counters->negative_lookups_miss(), 1); | 94   __ IncrementCounter(counters->negative_lookups_miss(), 1); | 
| 95 | 95 | 
| 96   Label done; |  | 
| 97   __ movq(r0, FieldOperand(receiver, HeapObject::kMapOffset)); | 96   __ movq(r0, FieldOperand(receiver, HeapObject::kMapOffset)); | 
| 98 | 97 | 
| 99   const int kInterceptorOrAccessCheckNeededMask = | 98   const int kInterceptorOrAccessCheckNeededMask = | 
| 100       (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 99       (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 
| 101 | 100 | 
| 102   // Bail out if the receiver has a named interceptor or requires access checks. | 101   // Bail out if the receiver has a named interceptor or requires access checks. | 
| 103   __ testb(FieldOperand(r0, Map::kBitFieldOffset), | 102   __ testb(FieldOperand(r0, Map::kBitFieldOffset), | 
| 104            Immediate(kInterceptorOrAccessCheckNeededMask)); | 103            Immediate(kInterceptorOrAccessCheckNeededMask)); | 
| 105   __ j(not_zero, miss_label); | 104   __ j(not_zero, miss_label); | 
| 106 | 105 | 
| 107   // Check that receiver is a JSObject. | 106   // Check that receiver is a JSObject. | 
| 108   __ CmpInstanceType(r0, FIRST_JS_OBJECT_TYPE); | 107   __ CmpInstanceType(r0, FIRST_JS_OBJECT_TYPE); | 
| 109   __ j(below, miss_label); | 108   __ j(below, miss_label); | 
| 110 | 109 | 
| 111   // Load properties array. | 110   // Load properties array. | 
| 112   Register properties = r0; | 111   Register properties = r0; | 
| 113   __ movq(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 112   __ movq(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 
| 114 | 113 | 
| 115   // Check that the properties array is a dictionary. | 114   // Check that the properties array is a dictionary. | 
| 116   __ CompareRoot(FieldOperand(properties, HeapObject::kMapOffset), | 115   __ CompareRoot(FieldOperand(properties, HeapObject::kMapOffset), | 
| 117                  Heap::kHashTableMapRootIndex); | 116                  Heap::kHashTableMapRootIndex); | 
| 118   __ j(not_equal, miss_label); | 117   __ j(not_equal, miss_label); | 
| 119 | 118 | 
| 120   // Compute the capacity mask. | 119   Label done; | 
| 121   const int kCapacityOffset = | 120   StringDictionaryLookupStub::GenerateNegativeLookup(masm, | 
| 122       StringDictionary::kHeaderSize + | 121                                                      miss_label, | 
| 123       StringDictionary::kCapacityIndex * kPointerSize; | 122                                                      &done, | 
| 124 | 123                                                      properties, | 
| 125   // Generate an unrolled loop that performs a few probes before | 124                                                      name, | 
| 126   // giving up. | 125                                                      r1); | 
| 127   static const int kProbes = 4; |  | 
| 128   const int kElementsStartOffset = |  | 
| 129       StringDictionary::kHeaderSize + |  | 
| 130       StringDictionary::kElementsStartIndex * kPointerSize; |  | 
| 131 |  | 
| 132   // If names of slots in range from 1 to kProbes - 1 for the hash value are |  | 
| 133   // not equal to the name and kProbes-th slot is not used (its name is the |  | 
| 134   // undefined value), it guarantees the hash table doesn't contain the |  | 
| 135   // property. It's true even if some slots represent deleted properties |  | 
| 136   // (their names are the null value). |  | 
| 137   for (int i = 0; i < kProbes; i++) { |  | 
| 138     // r0 points to properties hash. |  | 
| 139     // Compute the masked index: (hash + i + i * i) & mask. |  | 
| 140     Register index = r1; |  | 
| 141     // Capacity is smi 2^n. |  | 
| 142     __ SmiToInteger32(index, FieldOperand(properties, kCapacityOffset)); |  | 
| 143     __ decl(index); |  | 
| 144     __ and_(index, |  | 
| 145             Immediate(name->Hash() + StringDictionary::GetProbeOffset(i))); |  | 
| 146 |  | 
| 147     // Scale the index by multiplying by the entry size. |  | 
| 148     ASSERT(StringDictionary::kEntrySize == 3); |  | 
| 149     __ lea(index, Operand(index, index, times_2, 0));  // index *= 3. |  | 
| 150 |  | 
| 151     Register entity_name = r1; |  | 
| 152     // Having undefined at this place means the name is not contained. |  | 
| 153     ASSERT_EQ(kSmiTagSize, 1); |  | 
| 154     __ movq(entity_name, Operand(properties, index, times_pointer_size, |  | 
| 155                                  kElementsStartOffset - kHeapObjectTag)); |  | 
| 156     __ Cmp(entity_name, masm->isolate()->factory()->undefined_value()); |  | 
| 157     // __ jmp(miss_label); |  | 
| 158     if (i != kProbes - 1) { |  | 
| 159       __ j(equal, &done); |  | 
| 160 |  | 
| 161       // Stop if found the property. |  | 
| 162       __ Cmp(entity_name, Handle<String>(name)); |  | 
| 163       __ j(equal, miss_label); |  | 
| 164 |  | 
| 165       // Check if the entry name is not a symbol. |  | 
| 166       __ movq(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset)); |  | 
| 167       __ testb(FieldOperand(entity_name, Map::kInstanceTypeOffset), |  | 
| 168                Immediate(kIsSymbolMask)); |  | 
| 169       __ j(zero, miss_label); |  | 
| 170     } else { |  | 
| 171       // Give up probing if still not found the undefined value. |  | 
| 172       __ j(not_equal, miss_label); |  | 
| 173     } |  | 
| 174   } |  | 
| 175 |  | 
| 176   __ bind(&done); | 126   __ bind(&done); | 
| 177   __ DecrementCounter(counters->negative_lookups_miss(), 1); | 127   __ DecrementCounter(counters->negative_lookups_miss(), 1); | 
| 178 } | 128 } | 
| 179 | 129 | 
| 180 | 130 | 
| 181 void StubCache::GenerateProbe(MacroAssembler* masm, | 131 void StubCache::GenerateProbe(MacroAssembler* masm, | 
| 182                               Code::Flags flags, | 132                               Code::Flags flags, | 
| 183                               Register receiver, | 133                               Register receiver, | 
| 184                               Register name, | 134                               Register name, | 
| 185                               Register scratch, | 135                               Register scratch, | 
| (...skipping 3277 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3463   __ TailCallRuntime(Runtime::kSetProperty, 5, 1); | 3413   __ TailCallRuntime(Runtime::kSetProperty, 5, 1); | 
| 3464 | 3414 | 
| 3465   return GetCode(flags); | 3415   return GetCode(flags); | 
| 3466 } | 3416 } | 
| 3467 | 3417 | 
| 3468 #undef __ | 3418 #undef __ | 
| 3469 | 3419 | 
| 3470 } }  // namespace v8::internal | 3420 } }  // namespace v8::internal | 
| 3471 | 3421 | 
| 3472 #endif  // V8_TARGET_ARCH_X64 | 3422 #endif  // V8_TARGET_ARCH_X64 | 
| OLD | NEW | 
|---|