| OLD | NEW | 
|    1 // Copyright 2012 the V8 project authors. All rights reserved. |    1 // Copyright 2012 the V8 project authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "src/v8.h" |    5 #include "src/v8.h" | 
|    6  |    6  | 
|    7 #include "src/objects.h" |    7 #include "src/objects.h" | 
|    8 #include "src/transitions-inl.h" |    8 #include "src/transitions-inl.h" | 
|    9 #include "src/utils.h" |    9 #include "src/utils.h" | 
|   10  |   10  | 
| (...skipping 30 matching lines...) Expand all  Loading... | 
|   41 } |   41 } | 
|   42  |   42  | 
|   43  |   43  | 
|   44 Handle<TransitionArray> TransitionArray::NewWith(Handle<Map> map, |   44 Handle<TransitionArray> TransitionArray::NewWith(Handle<Map> map, | 
|   45                                                  Handle<Name> name, |   45                                                  Handle<Name> name, | 
|   46                                                  Handle<Map> target, |   46                                                  Handle<Map> target, | 
|   47                                                  SimpleTransitionFlag flag) { |   47                                                  SimpleTransitionFlag flag) { | 
|   48   Handle<TransitionArray> result; |   48   Handle<TransitionArray> result; | 
|   49   Isolate* isolate = name->GetIsolate(); |   49   Isolate* isolate = name->GetIsolate(); | 
|   50  |   50  | 
|   51   if (flag == SIMPLE_TRANSITION) { |   51   if (flag == SIMPLE_PROPERTY_TRANSITION) { | 
|   52     result = AllocateSimple(isolate, target); |   52     result = AllocateSimple(isolate, target); | 
|   53   } else { |   53   } else { | 
|   54     result = Allocate(isolate, 1); |   54     result = Allocate(isolate, 1); | 
|   55     result->NoIncrementalWriteBarrierSet(0, *name, *target); |   55     result->NoIncrementalWriteBarrierSet(0, *name, *target); | 
|   56   } |   56   } | 
|   57   result->set_back_pointer_storage(map->GetBackPointer()); |   57   result->set_back_pointer_storage(map->GetBackPointer()); | 
|   58   return result; |   58   return result; | 
|   59 } |   59 } | 
|   60  |   60  | 
|   61  |   61  | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
|   87                                                 Handle<Name> name, |   87                                                 Handle<Name> name, | 
|   88                                                 Handle<Map> target, |   88                                                 Handle<Map> target, | 
|   89                                                 SimpleTransitionFlag flag) { |   89                                                 SimpleTransitionFlag flag) { | 
|   90   if (!map->HasTransitionArray()) { |   90   if (!map->HasTransitionArray()) { | 
|   91     return TransitionArray::NewWith(map, name, target, flag); |   91     return TransitionArray::NewWith(map, name, target, flag); | 
|   92   } |   92   } | 
|   93  |   93  | 
|   94   int number_of_transitions = map->transitions()->number_of_transitions(); |   94   int number_of_transitions = map->transitions()->number_of_transitions(); | 
|   95   int new_nof = number_of_transitions; |   95   int new_nof = number_of_transitions; | 
|   96  |   96  | 
 |   97   bool is_special_transition = flag == SPECIAL_TRANSITION; | 
 |   98   DCHECK_EQ(is_special_transition, IsSpecialTransition(*name)); | 
 |   99   PropertyDetails details = is_special_transition | 
 |  100                                 ? PropertyDetails(NONE, NORMAL, 0) | 
 |  101                                 : GetTargetDetails(*name, *target); | 
 |  102  | 
|   97   int insertion_index = kNotFound; |  103   int insertion_index = kNotFound; | 
|   98   int index = map->transitions()->Search(*name, &insertion_index); |  104   int index = | 
|   99  |  105       is_special_transition | 
 |  106           ? map->transitions()->SearchSpecial(Symbol::cast(*name), | 
 |  107                                               &insertion_index) | 
 |  108           : map->transitions()->Search(details.type(), *name, | 
 |  109                                        details.attributes(), &insertion_index); | 
|  100   if (index == kNotFound) { |  110   if (index == kNotFound) { | 
|  101     ++new_nof; |  111     ++new_nof; | 
|  102   } else { |  112   } else { | 
|  103     insertion_index = index; |  113     insertion_index = index; | 
|  104   } |  114   } | 
|  105   DCHECK(insertion_index >= 0 && insertion_index <= number_of_transitions); |  115   DCHECK(insertion_index >= 0 && insertion_index <= number_of_transitions); | 
|  106  |  116  | 
|  107   CHECK(new_nof <= kMaxNumberOfTransitions); |  117   CHECK(new_nof <= kMaxNumberOfTransitions); | 
|  108  |  118  | 
|  109   if (new_nof <= map->transitions()->number_of_transitions_storage()) { |  119   if (new_nof <= map->transitions()->number_of_transitions_storage()) { | 
|  110     DisallowHeapAllocation no_gc; |  120     DisallowHeapAllocation no_gc; | 
|  111     TransitionArray* array = map->transitions(); |  121     TransitionArray* array = map->transitions(); | 
|  112  |  122  | 
|  113     if (index != kNotFound) { |  123     if (index != kNotFound) { | 
|  114       array->SetTarget(index, *target); |  124       array->SetTarget(index, *target); | 
|  115       return handle(array); |  125       return handle(array); | 
|  116     } |  126     } | 
|  117  |  127  | 
|  118     array->SetNumberOfTransitions(new_nof); |  128     array->SetNumberOfTransitions(new_nof); | 
|  119     for (index = number_of_transitions; index > insertion_index; --index) { |  129     for (index = number_of_transitions; index > insertion_index; --index) { | 
|  120       Name* key = array->GetKey(index - 1); |  130       Name* key = array->GetKey(index - 1); | 
|  121       DCHECK(key->Hash() > name->Hash()); |  | 
|  122       array->SetKey(index, key); |  131       array->SetKey(index, key); | 
|  123       array->SetTarget(index, array->GetTarget(index - 1)); |  132       array->SetTarget(index, array->GetTarget(index - 1)); | 
|  124     } |  133     } | 
|  125     array->SetKey(index, *name); |  134     array->SetKey(index, *name); | 
|  126     array->SetTarget(index, *target); |  135     array->SetTarget(index, *target); | 
 |  136     SLOW_DCHECK(array->IsSortedNoDuplicates()); | 
|  127     return handle(array); |  137     return handle(array); | 
|  128   } |  138   } | 
|  129  |  139  | 
|  130   Handle<TransitionArray> result = Allocate( |  140   Handle<TransitionArray> result = Allocate( | 
|  131       map->GetIsolate(), new_nof, |  141       map->GetIsolate(), new_nof, | 
|  132       Map::SlackForArraySize(number_of_transitions, kMaxNumberOfTransitions)); |  142       Map::SlackForArraySize(number_of_transitions, kMaxNumberOfTransitions)); | 
|  133  |  143  | 
|  134   // The map's transition array may grown smaller during the allocation above as |  144   // The map's transition array may grown smaller during the allocation above as | 
|  135   // it was weakly traversed, though it is guaranteed not to disappear. Trim the |  145   // it was weakly traversed, though it is guaranteed not to disappear. Trim the | 
|  136   // result copy if needed, and recompute variables. |  146   // result copy if needed, and recompute variables. | 
|  137   DCHECK(map->HasTransitionArray()); |  147   DCHECK(map->HasTransitionArray()); | 
|  138   DisallowHeapAllocation no_gc; |  148   DisallowHeapAllocation no_gc; | 
|  139   TransitionArray* array = map->transitions(); |  149   TransitionArray* array = map->transitions(); | 
|  140   if (array->number_of_transitions() != number_of_transitions) { |  150   if (array->number_of_transitions() != number_of_transitions) { | 
|  141     DCHECK(array->number_of_transitions() < number_of_transitions); |  151     DCHECK(array->number_of_transitions() < number_of_transitions); | 
|  142  |  152  | 
|  143     number_of_transitions = array->number_of_transitions(); |  153     number_of_transitions = array->number_of_transitions(); | 
|  144     new_nof = number_of_transitions; |  154     new_nof = number_of_transitions; | 
|  145  |  155  | 
|  146     insertion_index = kNotFound; |  156     insertion_index = kNotFound; | 
|  147     index = array->Search(*name, &insertion_index); |  157     index = is_special_transition ? map->transitions()->SearchSpecial( | 
 |  158                                         Symbol::cast(*name), &insertion_index) | 
 |  159                                   : map->transitions()->Search( | 
 |  160                                         details.type(), *name, | 
 |  161                                         details.attributes(), &insertion_index); | 
|  148     if (index == kNotFound) { |  162     if (index == kNotFound) { | 
|  149       ++new_nof; |  163       ++new_nof; | 
|  150     } else { |  164     } else { | 
|  151       insertion_index = index; |  165       insertion_index = index; | 
|  152     } |  166     } | 
|  153     DCHECK(insertion_index >= 0 && insertion_index <= number_of_transitions); |  167     DCHECK(insertion_index >= 0 && insertion_index <= number_of_transitions); | 
|  154  |  168  | 
|  155     result->Shrink(ToKeyIndex(new_nof)); |  169     result->Shrink(ToKeyIndex(new_nof)); | 
|  156     result->SetNumberOfTransitions(new_nof); |  170     result->SetNumberOfTransitions(new_nof); | 
|  157   } |  171   } | 
|  158  |  172  | 
|  159   if (array->HasPrototypeTransitions()) { |  173   if (array->HasPrototypeTransitions()) { | 
|  160     result->SetPrototypeTransitions(array->GetPrototypeTransitions()); |  174     result->SetPrototypeTransitions(array->GetPrototypeTransitions()); | 
|  161   } |  175   } | 
|  162  |  176  | 
|  163   DCHECK_NE(kNotFound, insertion_index); |  177   DCHECK_NE(kNotFound, insertion_index); | 
|  164   for (int i = 0; i < insertion_index; ++i) { |  178   for (int i = 0; i < insertion_index; ++i) { | 
|  165     result->NoIncrementalWriteBarrierCopyFrom(array, i, i); |  179     result->NoIncrementalWriteBarrierCopyFrom(array, i, i); | 
|  166   } |  180   } | 
|  167   result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target); |  181   result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target); | 
|  168   for (int i = insertion_index; i < number_of_transitions; ++i) { |  182   for (int i = insertion_index; i < number_of_transitions; ++i) { | 
|  169     result->NoIncrementalWriteBarrierCopyFrom(array, i, i + 1); |  183     result->NoIncrementalWriteBarrierCopyFrom(array, i, i + 1); | 
|  170   } |  184   } | 
|  171  |  185  | 
|  172   result->set_back_pointer_storage(array->back_pointer_storage()); |  186   result->set_back_pointer_storage(array->back_pointer_storage()); | 
 |  187   SLOW_DCHECK(result->IsSortedNoDuplicates()); | 
|  173   return result; |  188   return result; | 
|  174 } |  189 } | 
|  175  |  190  | 
|  176  |  191  | 
 |  192 int TransitionArray::SearchDetails(int transition, PropertyType type, | 
 |  193                                    PropertyAttributes attributes, | 
 |  194                                    int* out_insertion_index) { | 
 |  195   int nof_transitions = number_of_transitions(); | 
 |  196   DCHECK(transition < nof_transitions); | 
 |  197   Name* key = GetKey(transition); | 
 |  198   bool is_data = type == FIELD || type == CONSTANT; | 
 |  199   for (; transition < nof_transitions && GetKey(transition) == key; | 
 |  200        transition++) { | 
 |  201     Map* target = GetTarget(transition); | 
 |  202     PropertyDetails target_details = GetTargetDetails(key, target); | 
 |  203  | 
 |  204     bool target_is_data = | 
 |  205         target_details.type() == FIELD || target_details.type() == CONSTANT; | 
 |  206  | 
 |  207     int cmp = CompareDetails(is_data, attributes, target_is_data, | 
 |  208                              target_details.attributes()); | 
 |  209     if (cmp == 0) { | 
 |  210       return transition; | 
 |  211     } else if (cmp < 0) { | 
 |  212       break; | 
 |  213     } | 
 |  214   } | 
 |  215   if (out_insertion_index != NULL) *out_insertion_index = transition; | 
 |  216   return kNotFound; | 
 |  217 } | 
 |  218  | 
 |  219  | 
 |  220 int TransitionArray::Search(PropertyType type, Name* name, | 
 |  221                             PropertyAttributes attributes, | 
 |  222                             int* out_insertion_index) { | 
 |  223   int transition = SearchName(name, out_insertion_index); | 
 |  224   if (transition == kNotFound) { | 
 |  225     return kNotFound; | 
 |  226   } | 
 |  227   return SearchDetails(transition, type, attributes, out_insertion_index); | 
 |  228 } | 
|  177 } }  // namespace v8::internal |  229 } }  // namespace v8::internal | 
| OLD | NEW |