| OLD | NEW | 
|      1 // Copyright 2012 the V8 project authors. All rights reserved. |      1 // Copyright 2012 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 1528 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   1539       if (!maybe_obj->ToObject(&obj)) return maybe_obj; |   1539       if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 
|   1540     } |   1540     } | 
|   1541     return AddSlowProperty(name, value, attributes); |   1541     return AddSlowProperty(name, value, attributes); | 
|   1542   } |   1542   } | 
|   1543  |   1543  | 
|   1544   DescriptorArray* old_descriptors = map()->instance_descriptors(); |   1544   DescriptorArray* old_descriptors = map()->instance_descriptors(); | 
|   1545   // Compute the new index for new field. |   1545   // Compute the new index for new field. | 
|   1546   int index = map()->NextFreePropertyIndex(); |   1546   int index = map()->NextFreePropertyIndex(); | 
|   1547  |   1547  | 
|   1548   // Allocate new instance descriptors with (name, index) added |   1548   // Allocate new instance descriptors with (name, index) added | 
|   1549   FieldDescriptor new_field(name, index, attributes); |   1549   FieldDescriptor new_field(name, index, attributes, 0); | 
|   1550   DescriptorArray* new_descriptors; |   1550   DescriptorArray* new_descriptors; | 
|   1551   { MaybeObject* maybe_new_descriptors = |   1551   { MaybeObject* maybe_new_descriptors = | 
|   1552         old_descriptors->CopyInsert(&new_field); |   1552         old_descriptors->CopyInsert(&new_field); | 
|   1553     if (!maybe_new_descriptors->To(&new_descriptors)) { |   1553     if (!maybe_new_descriptors->To(&new_descriptors)) { | 
|   1554       return maybe_new_descriptors; |   1554       return maybe_new_descriptors; | 
|   1555     } |   1555     } | 
|   1556   } |   1556   } | 
|   1557  |   1557  | 
|   1558   // Only allow map transition if the object isn't the global object and there |   1558   // Only allow map transition if the object isn't the global object. | 
|   1559   // is not a transition for the name, or there's a transition for the name but |  | 
|   1560   // it's unrelated to properties. |  | 
|   1561   int descriptor_index = old_descriptors->SearchWithCache(name); |  | 
|   1562  |  | 
|   1563   // Element transitions are stored in the descriptor for property "", which is |  | 
|   1564   // not a identifier and should have forced a switch to slow properties above. |  | 
|   1565   bool can_insert_transition = descriptor_index == DescriptorArray::kNotFound; |  | 
|   1566   bool allow_map_transition = |   1559   bool allow_map_transition = | 
|   1567       can_insert_transition && |  | 
|   1568       (isolate->context()->global_context()->object_function()->map() != map()); |   1560       (isolate->context()->global_context()->object_function()->map() != map()); | 
|   1569  |   1561  | 
 |   1562   ASSERT(old_descriptors->Search(name) == DescriptorArray::kNotFound); | 
|   1570   ASSERT(index < map()->inobject_properties() || |   1563   ASSERT(index < map()->inobject_properties() || | 
|   1571          (index - map()->inobject_properties()) < properties()->length() || |   1564          (index - map()->inobject_properties()) < properties()->length() || | 
|   1572          map()->unused_property_fields() == 0); |   1565          map()->unused_property_fields() == 0); | 
|   1573   // Allocate a new map for the object. |   1566   // Allocate a new map for the object. | 
|   1574   Object* r; |   1567   Object* r; | 
|   1575   { MaybeObject* maybe_r = map()->CopyDropDescriptors(); |   1568   { MaybeObject* maybe_r = map()->CopyDropDescriptors(); | 
|   1576     if (!maybe_r->ToObject(&r)) return maybe_r; |   1569     if (!maybe_r->ToObject(&r)) return maybe_r; | 
|   1577   } |   1570   } | 
|   1578   Map* new_map = Map::cast(r); |   1571   Map* new_map = Map::cast(r); | 
|   1579  |   1572  | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   1615   set_map(new_map); |   1608   set_map(new_map); | 
|   1616   return FastPropertyAtPut(index, value); |   1609   return FastPropertyAtPut(index, value); | 
|   1617 } |   1610 } | 
|   1618  |   1611  | 
|   1619  |   1612  | 
|   1620 MaybeObject* JSObject::AddConstantFunctionProperty( |   1613 MaybeObject* JSObject::AddConstantFunctionProperty( | 
|   1621     String* name, |   1614     String* name, | 
|   1622     JSFunction* function, |   1615     JSFunction* function, | 
|   1623     PropertyAttributes attributes) { |   1616     PropertyAttributes attributes) { | 
|   1624   // Allocate new instance descriptors with (name, function) added |   1617   // Allocate new instance descriptors with (name, function) added | 
|   1625   ConstantFunctionDescriptor d(name, function, attributes); |   1618   ConstantFunctionDescriptor d(name, function, attributes, 0); | 
|   1626   DescriptorArray* new_descriptors; |   1619   DescriptorArray* new_descriptors; | 
|   1627   { MaybeObject* maybe_new_descriptors = |   1620   { MaybeObject* maybe_new_descriptors = | 
|   1628         map()->instance_descriptors()->CopyInsert(&d); |   1621         map()->instance_descriptors()->CopyInsert(&d); | 
|   1629     if (!maybe_new_descriptors->To(&new_descriptors)) { |   1622     if (!maybe_new_descriptors->To(&new_descriptors)) { | 
|   1630       return maybe_new_descriptors; |   1623       return maybe_new_descriptors; | 
|   1631     } |   1624     } | 
|   1632   } |   1625   } | 
|   1633  |   1626  | 
|   1634   // Allocate a new map for the object. |   1627   // Allocate a new map for the object. | 
|   1635   Map* new_map; |   1628   Map* new_map; | 
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   1858       TooManyFastProperties(properties()->length(), MAY_BE_STORE_FROM_KEYED)) { |   1851       TooManyFastProperties(properties()->length(), MAY_BE_STORE_FROM_KEYED)) { | 
|   1859     Object* obj; |   1852     Object* obj; | 
|   1860     { MaybeObject* maybe_obj = |   1853     { MaybeObject* maybe_obj = | 
|   1861           NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |   1854           NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 
|   1862       if (!maybe_obj->ToObject(&obj)) return maybe_obj; |   1855       if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 
|   1863     } |   1856     } | 
|   1864     return ReplaceSlowProperty(name, new_value, attributes); |   1857     return ReplaceSlowProperty(name, new_value, attributes); | 
|   1865   } |   1858   } | 
|   1866  |   1859  | 
|   1867   int index = map()->NextFreePropertyIndex(); |   1860   int index = map()->NextFreePropertyIndex(); | 
|   1868   FieldDescriptor new_field(name, index, attributes); |   1861   FieldDescriptor new_field(name, index, attributes, 0); | 
|   1869   // Make a new DescriptorArray replacing an entry with FieldDescriptor. |   1862   // Make a new DescriptorArray replacing an entry with FieldDescriptor. | 
|   1870   Object* descriptors_unchecked; |   1863   Object* descriptors_unchecked; | 
|   1871   { MaybeObject* maybe_descriptors_unchecked = |   1864   { MaybeObject* maybe_descriptors_unchecked = | 
|   1872         map()->instance_descriptors()->CopyInsert(&new_field); |   1865         map()->instance_descriptors()->CopyInsert(&new_field); | 
|   1873     if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) { |   1866     if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) { | 
|   1874       return maybe_descriptors_unchecked; |   1867       return maybe_descriptors_unchecked; | 
|   1875     } |   1868     } | 
|   1876   } |   1869   } | 
|   1877   DescriptorArray* new_descriptors = |   1870   DescriptorArray* new_descriptors = | 
|   1878       DescriptorArray::cast(descriptors_unchecked); |   1871       DescriptorArray::cast(descriptors_unchecked); | 
| (...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   2931         } |   2924         } | 
|   2932         return self->SetPropertyWithCallback(transition, |   2925         return self->SetPropertyWithCallback(transition, | 
|   2933                                              *name, |   2926                                              *name, | 
|   2934                                              *value, |   2927                                              *value, | 
|   2935                                              result->holder(), |   2928                                              result->holder(), | 
|   2936                                              strict_mode); |   2929                                              strict_mode); | 
|   2937       } |   2930       } | 
|   2938  |   2931  | 
|   2939       Map* transition_map = Map::cast(transition); |   2932       Map* transition_map = Map::cast(transition); | 
|   2940       DescriptorArray* descriptors = transition_map->instance_descriptors(); |   2933       DescriptorArray* descriptors = transition_map->instance_descriptors(); | 
|   2941       int descriptor = descriptors->SearchWithCache(*name); |   2934       int descriptor = descriptors->LastAdded(); | 
|   2942       PropertyDetails details = descriptors->GetDetails(descriptor); |   2935       PropertyDetails details = descriptors->GetDetails(descriptor); | 
|   2943       ASSERT(details.type() == FIELD || details.type() == CONSTANT_FUNCTION); |   2936       ASSERT(details.type() == FIELD || details.type() == CONSTANT_FUNCTION); | 
|   2944  |   2937  | 
|   2945       if (details.type() == FIELD) { |   2938       if (details.type() == FIELD) { | 
|   2946         if (attributes == details.attributes()) { |   2939         if (attributes == details.attributes()) { | 
|   2947           int field_index = descriptors->GetFieldIndex(descriptor); |   2940           int field_index = descriptors->GetFieldIndex(descriptor); | 
|   2948           return self->AddFastPropertyUsingMap(transition_map, |   2941           return self->AddFastPropertyUsingMap(transition_map, | 
|   2949                                                *name, |   2942                                                *name, | 
|   2950                                                *value, |   2943                                                *value, | 
|   2951                                                field_index); |   2944                                                field_index); | 
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   3055       return ConvertDescriptorToField(name, value, attributes); |   3048       return ConvertDescriptorToField(name, value, attributes); | 
|   3056     case TRANSITION: { |   3049     case TRANSITION: { | 
|   3057       Object* transition = result.GetTransitionValue(); |   3050       Object* transition = result.GetTransitionValue(); | 
|   3058  |   3051  | 
|   3059       if (transition->IsAccessorPair()) { |   3052       if (transition->IsAccessorPair()) { | 
|   3060         return ConvertDescriptorToField(name, value, attributes); |   3053         return ConvertDescriptorToField(name, value, attributes); | 
|   3061       } |   3054       } | 
|   3062  |   3055  | 
|   3063       Map* transition_map = Map::cast(transition); |   3056       Map* transition_map = Map::cast(transition); | 
|   3064       DescriptorArray* descriptors = transition_map->instance_descriptors(); |   3057       DescriptorArray* descriptors = transition_map->instance_descriptors(); | 
|   3065       int descriptor = descriptors->Search(name); |   3058       int descriptor = descriptors->LastAdded(); | 
|   3066       PropertyDetails details = descriptors->GetDetails(descriptor); |   3059       PropertyDetails details = descriptors->GetDetails(descriptor); | 
|   3067       ASSERT(details.type() == FIELD || details.type() == CONSTANT_FUNCTION); |   3060       ASSERT(details.type() == FIELD || details.type() == CONSTANT_FUNCTION); | 
|   3068  |   3061  | 
|   3069       if (details.type() == FIELD) { |   3062       if (details.type() == FIELD) { | 
|   3070         if (attributes == details.attributes()) { |   3063         if (attributes == details.attributes()) { | 
|   3071           int field_index = descriptors->GetFieldIndex(descriptor); |   3064           int field_index = descriptors->GetFieldIndex(descriptor); | 
|   3072           return AddFastPropertyUsingMap(transition_map, |   3065           return AddFastPropertyUsingMap(transition_map, | 
|   3073                                          name, |   3066                                          name, | 
|   3074                                          value, |   3067                                          value, | 
|   3075                                          field_index); |   3068                                          field_index); | 
| (...skipping 1527 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   4603   // step 1: create a new getter/setter pair with only the accessor in it |   4596   // step 1: create a new getter/setter pair with only the accessor in it | 
|   4604   Heap* heap = obj->GetHeap(); |   4597   Heap* heap = obj->GetHeap(); | 
|   4605   AccessorPair* accessors2; |   4598   AccessorPair* accessors2; | 
|   4606   { MaybeObject* maybe_accessors2 = heap->AllocateAccessorPair(); |   4599   { MaybeObject* maybe_accessors2 = heap->AllocateAccessorPair(); | 
|   4607     if (!maybe_accessors2->To(&accessors2)) return maybe_accessors2; |   4600     if (!maybe_accessors2->To(&accessors2)) return maybe_accessors2; | 
|   4608   } |   4601   } | 
|   4609   accessors2->set(component, accessor); |   4602   accessors2->set(component, accessor); | 
|   4610  |   4603  | 
|   4611   // step 2: create a copy of the descriptors, incl. the new getter/setter pair |   4604   // step 2: create a copy of the descriptors, incl. the new getter/setter pair | 
|   4612   Map* map1 = obj->map(); |   4605   Map* map1 = obj->map(); | 
|   4613   CallbacksDescriptor callbacks_descr2(name, accessors2, attributes); |   4606   CallbacksDescriptor callbacks_descr2(name, accessors2, attributes, 0); | 
|   4614   DescriptorArray* descriptors2; |   4607   DescriptorArray* descriptors2; | 
|   4615   { MaybeObject* maybe_descriptors2 = |   4608   { MaybeObject* maybe_descriptors2 = | 
|   4616         map1->instance_descriptors()->CopyInsert(&callbacks_descr2); |   4609         map1->instance_descriptors()->CopyInsert(&callbacks_descr2); | 
|   4617     if (!maybe_descriptors2->To(&descriptors2)) return maybe_descriptors2; |   4610     if (!maybe_descriptors2->To(&descriptors2)) return maybe_descriptors2; | 
|   4618   } |   4611   } | 
|   4619  |   4612  | 
|   4620   // step 3: create a new map with the new descriptors |   4613   // step 3: create a new map with the new descriptors | 
|   4621   Map* map2; |   4614   Map* map2; | 
|   4622   { MaybeObject* maybe_map2 = map1->CopyDropDescriptors(); |   4615   { MaybeObject* maybe_map2 = map1->CopyDropDescriptors(); | 
|   4623     if (!maybe_map2->To(&map2)) return maybe_map2; |   4616     if (!maybe_map2->To(&map2)) return maybe_map2; | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
|   4650   return obj; |   4643   return obj; | 
|   4651 } |   4644 } | 
|   4652  |   4645  | 
|   4653  |   4646  | 
|   4654 static bool TransitionToSameAccessor(Object* map, |   4647 static bool TransitionToSameAccessor(Object* map, | 
|   4655                                      String* name, |   4648                                      String* name, | 
|   4656                                      AccessorComponent component, |   4649                                      AccessorComponent component, | 
|   4657                                      Object* accessor, |   4650                                      Object* accessor, | 
|   4658                                      PropertyAttributes attributes ) { |   4651                                      PropertyAttributes attributes ) { | 
|   4659   DescriptorArray* descs = Map::cast(map)->instance_descriptors(); |   4652   DescriptorArray* descs = Map::cast(map)->instance_descriptors(); | 
|   4660   int number = descs->SearchWithCache(name); |   4653   int number = descs->LastAdded(); | 
|   4661   ASSERT(number != DescriptorArray::kNotFound); |   4654   ASSERT(number != DescriptorArray::kNotFound); | 
|   4662   Object* target_accessor = |   4655   Object* target_accessor = | 
|   4663       AccessorPair::cast(descs->GetCallbacksObject(number))->get(component); |   4656       AccessorPair::cast(descs->GetCallbacksObject(number))->get(component); | 
|   4664   PropertyAttributes target_attributes = descs->GetDetails(number).attributes(); |   4657   PropertyAttributes target_attributes = descs->GetDetails(number).attributes(); | 
|   4665   return target_accessor == accessor && target_attributes == attributes; |   4658   return target_accessor == accessor && target_attributes == attributes; | 
|   4666 } |   4659 } | 
|   4667  |   4660  | 
|   4668  |   4661  | 
|   4669 static MaybeObject* NewCallbackTransition(JSObject* obj, |   4662 static MaybeObject* NewCallbackTransition(JSObject* obj, | 
|   4670                                           String* name, |   4663                                           String* name, | 
|   4671                                           AccessorComponent component, |   4664                                           AccessorComponent component, | 
|   4672                                           Object* accessor, |   4665                                           Object* accessor, | 
|   4673                                           PropertyAttributes attributes, |   4666                                           PropertyAttributes attributes, | 
|   4674                                           AccessorPair* accessors2) { |   4667                                           AccessorPair* accessors2) { | 
|   4675   // step 1: copy the old getter/setter pair and set the new accessor |   4668   // step 1: copy the old getter/setter pair and set the new accessor | 
|   4676   AccessorPair* accessors3; |   4669   AccessorPair* accessors3; | 
|   4677   { MaybeObject* maybe_accessors3 = accessors2->CopyWithoutTransitions(); |   4670   { MaybeObject* maybe_accessors3 = accessors2->CopyWithoutTransitions(); | 
|   4678     if (!maybe_accessors3->To(&accessors3)) return maybe_accessors3; |   4671     if (!maybe_accessors3->To(&accessors3)) return maybe_accessors3; | 
|   4679   } |   4672   } | 
|   4680   accessors3->set(component, accessor); |   4673   accessors3->set(component, accessor); | 
|   4681  |   4674  | 
|   4682   // step 2: create a copy of the descriptors, incl. the new getter/setter pair |   4675   // step 2: create a copy of the descriptors, incl. the new getter/setter pair | 
|   4683   Map* map2 = obj->map(); |   4676   Map* map2 = obj->map(); | 
|   4684   CallbacksDescriptor callbacks_descr3(name, accessors3, attributes); |   4677   CallbacksDescriptor callbacks_descr3(name, accessors3, attributes, 0); | 
|   4685   DescriptorArray* descriptors3; |   4678   DescriptorArray* descriptors3; | 
|   4686   { MaybeObject* maybe_descriptors3 = |   4679   { MaybeObject* maybe_descriptors3 = | 
|   4687         map2->instance_descriptors()->CopyInsert(&callbacks_descr3); |   4680         map2->instance_descriptors()->CopyInsert(&callbacks_descr3); | 
|   4688     if (!maybe_descriptors3->To(&descriptors3)) return maybe_descriptors3; |   4681     if (!maybe_descriptors3->To(&descriptors3)) return maybe_descriptors3; | 
|   4689   } |   4682   } | 
|   4690  |   4683  | 
|   4691   // step 3: create a new map with the new descriptors |   4684   // step 3: create a new map with the new descriptors | 
|   4692   Map* map3; |   4685   Map* map3; | 
|   4693   { MaybeObject* maybe_map3 = map2->CopyDropDescriptors(); |   4686   { MaybeObject* maybe_map3 = map2->CopyDropDescriptors(); | 
|   4694     if (!maybe_map3->To(&map3)) return maybe_map3; |   4687     if (!maybe_map3->To(&map3)) return maybe_map3; | 
| (...skipping 1115 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   5810   FixedArray* result; |   5803   FixedArray* result; | 
|   5811   if (number_of_descriptors == 0 && shared_mode == MAY_BE_SHARED) { |   5804   if (number_of_descriptors == 0 && shared_mode == MAY_BE_SHARED) { | 
|   5812     return heap->empty_descriptor_array(); |   5805     return heap->empty_descriptor_array(); | 
|   5813   } |   5806   } | 
|   5814   // Allocate the array of keys. |   5807   // Allocate the array of keys. | 
|   5815   { MaybeObject* maybe_array = |   5808   { MaybeObject* maybe_array = | 
|   5816         heap->AllocateFixedArray(ToKeyIndex(number_of_descriptors)); |   5809         heap->AllocateFixedArray(ToKeyIndex(number_of_descriptors)); | 
|   5817     if (!maybe_array->To(&result)) return maybe_array; |   5810     if (!maybe_array->To(&result)) return maybe_array; | 
|   5818   } |   5811   } | 
|   5819  |   5812  | 
|   5820   result->set(kEnumerationIndexIndex, |   5813   result->set(kLastAddedIndex, Smi::FromInt(-1)); | 
|   5821               Smi::FromInt(PropertyDetails::kInitialIndex)); |  | 
|   5822   result->set(kTransitionsIndex, Smi::FromInt(0)); |   5814   result->set(kTransitionsIndex, Smi::FromInt(0)); | 
|   5823   return result; |   5815   return result; | 
|   5824 } |   5816 } | 
|   5825  |   5817  | 
|   5826  |   5818  | 
|   5827 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage, |   5819 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage, | 
|   5828                                    FixedArray* new_cache, |   5820                                    FixedArray* new_cache, | 
|   5829                                    Object* new_index_cache) { |   5821                                    Object* new_index_cache) { | 
|   5830   ASSERT(bridge_storage->length() >= kEnumCacheBridgeLength); |   5822   ASSERT(bridge_storage->length() >= kEnumCacheBridgeLength); | 
|   5831   ASSERT(new_index_cache->IsSmi() || new_index_cache->IsFixedArray()); |   5823   ASSERT(new_index_cache->IsSmi() || new_index_cache->IsFixedArray()); | 
|   5832   if (HasEnumCache()) { |   5824   if (HasEnumCache()) { | 
|   5833     FixedArray::cast(get(kEnumerationIndexIndex))-> |   5825     FixedArray::cast(get(kLastAddedIndex))-> | 
|   5834       set(kEnumCacheBridgeCacheIndex, new_cache); |   5826       set(kEnumCacheBridgeCacheIndex, new_cache); | 
|   5835     FixedArray::cast(get(kEnumerationIndexIndex))-> |   5827     FixedArray::cast(get(kLastAddedIndex))-> | 
|   5836       set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache); |   5828       set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache); | 
|   5837   } else { |   5829   } else { | 
|   5838     if (IsEmpty()) return;  // Do nothing for empty descriptor array. |   5830     if (IsEmpty()) return;  // Do nothing for empty descriptor array. | 
|   5839     FixedArray::cast(bridge_storage)-> |   5831     FixedArray::cast(bridge_storage)-> | 
|   5840       set(kEnumCacheBridgeCacheIndex, new_cache); |   5832       set(kEnumCacheBridgeCacheIndex, new_cache); | 
|   5841     FixedArray::cast(bridge_storage)-> |   5833     FixedArray::cast(bridge_storage)-> | 
|   5842       set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache); |   5834       set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache); | 
|   5843     NoWriteBarrierSet(FixedArray::cast(bridge_storage), |   5835     NoWriteBarrierSet(FixedArray::cast(bridge_storage), | 
|   5844                       kEnumCacheBridgeEnumIndex, |   5836                       kEnumCacheBridgeLastAdded, | 
|   5845                       get(kEnumerationIndexIndex)); |   5837                       get(kLastAddedIndex)); | 
|   5846     set(kEnumerationIndexIndex, bridge_storage); |   5838     set(kLastAddedIndex, bridge_storage); | 
|   5847   } |   5839   } | 
|   5848 } |   5840 } | 
|   5849  |   5841  | 
|   5850  |   5842  | 
|   5851 static bool InsertionPointFound(String* key1, String* key2) { |   5843 static bool InsertionPointFound(String* key1, String* key2) { | 
|   5852   return key1->Hash() > key2->Hash() || key1 == key2; |   5844   return key1->Hash() > key2->Hash() || key1 == key2; | 
|   5853 } |   5845 } | 
|   5854  |   5846  | 
|   5855  |   5847  | 
|   5856 void DescriptorArray::CopyFrom(Handle<DescriptorArray> dst, |   5848 void DescriptorArray::CopyFrom(Handle<DescriptorArray> dst, | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   5903  |   5895  | 
|   5904   DescriptorArray* new_descriptors; |   5896   DescriptorArray* new_descriptors; | 
|   5905   { MaybeObject* maybe_result = Allocate(new_size, MAY_BE_SHARED); |   5897   { MaybeObject* maybe_result = Allocate(new_size, MAY_BE_SHARED); | 
|   5906     if (!maybe_result->To(&new_descriptors)) return maybe_result; |   5898     if (!maybe_result->To(&new_descriptors)) return maybe_result; | 
|   5907   } |   5899   } | 
|   5908  |   5900  | 
|   5909   FixedArray::WhitenessWitness witness(new_descriptors); |   5901   FixedArray::WhitenessWitness witness(new_descriptors); | 
|   5910  |   5902  | 
|   5911   // Set the enumeration index in the descriptors and set the enumeration index |   5903   // Set the enumeration index in the descriptors and set the enumeration index | 
|   5912   // in the result. |   5904   // in the result. | 
|   5913   int enumeration_index = NextEnumerationIndex(); |  | 
|   5914   if (keep_enumeration_index) { |   5905   if (keep_enumeration_index) { | 
|   5915     descriptor->SetEnumerationIndex(GetDetails(index).index()); |   5906     descriptor->SetEnumerationIndex(GetDetails(index).index()); | 
|   5916   } else { |   5907   } else { | 
|   5917     descriptor->SetEnumerationIndex(enumeration_index); |   5908     descriptor->SetEnumerationIndex(NextEnumerationIndex()); | 
|   5918     ++enumeration_index; |  | 
|   5919   } |   5909   } | 
|   5920   new_descriptors->SetNextEnumerationIndex(enumeration_index); |  | 
|   5921  |   5910  | 
|   5922   // Copy the descriptors, inserting or replacing a descriptor. |   5911   // Copy the descriptors, inserting or replacing a descriptor. | 
|   5923   int to_index = 0; |   5912   int to_index = 0; | 
|   5924   int insertion_index = -1; |   5913   int insertion_index = -1; | 
|   5925   int from_index = 0; |   5914   int from_index = 0; | 
|   5926   while (from_index < number_of_descriptors()) { |   5915   while (from_index < number_of_descriptors()) { | 
|   5927     if (insertion_index < 0 && |   5916     if (insertion_index < 0 && | 
|   5928         InsertionPointFound(GetKey(from_index), descriptor->GetKey())) { |   5917         InsertionPointFound(GetKey(from_index), descriptor->GetKey())) { | 
|   5929       insertion_index = to_index++; |   5918       insertion_index = to_index++; | 
|   5930       if (replacing) from_index++; |   5919       if (replacing) from_index++; | 
|   5931     } else { |   5920     } else { | 
|   5932       MaybeObject* copy_result = |   5921       MaybeObject* copy_result = | 
|   5933           new_descriptors->CopyFrom(to_index++, this, from_index, witness); |   5922           new_descriptors->CopyFrom(to_index++, this, from_index, witness); | 
|   5934       if (copy_result->IsFailure()) return copy_result; |   5923       if (copy_result->IsFailure()) return copy_result; | 
|   5935       from_index++; |   5924       from_index++; | 
|   5936     } |   5925     } | 
|   5937   } |   5926   } | 
|   5938   if (insertion_index < 0) insertion_index = to_index++; |   5927   if (insertion_index < 0) insertion_index = to_index++; | 
|   5939  |   5928  | 
|   5940   ASSERT(insertion_index < new_descriptors->number_of_descriptors()); |   5929   ASSERT(insertion_index < new_descriptors->number_of_descriptors()); | 
|   5941   new_descriptors->Set(insertion_index, descriptor, witness); |   5930   new_descriptors->Set(insertion_index, descriptor, witness); | 
 |   5931   if (!replacing) { | 
 |   5932     new_descriptors->SetLastAdded(insertion_index); | 
 |   5933   } else { | 
 |   5934     new_descriptors->SetLastAdded(LastAdded()); | 
 |   5935   } | 
|   5942  |   5936  | 
|   5943   ASSERT(to_index == new_descriptors->number_of_descriptors()); |   5937   ASSERT(to_index == new_descriptors->number_of_descriptors()); | 
|   5944   SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); |   5938   SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); | 
|   5945  |   5939  | 
|   5946   return new_descriptors; |   5940   return new_descriptors; | 
|   5947 } |   5941 } | 
|   5948  |   5942  | 
|   5949  |   5943  | 
|   5950 MaybeObject* DescriptorArray::Copy(SharedMode shared_mode) { |   5944 MaybeObject* DescriptorArray::Copy(SharedMode shared_mode) { | 
|   5951   // Allocate the new descriptor array. |   5945   // Allocate the new descriptor array. | 
|   5952   int number_of_descriptors = this->number_of_descriptors(); |   5946   int number_of_descriptors = this->number_of_descriptors(); | 
|   5953   DescriptorArray* new_descriptors; |   5947   DescriptorArray* new_descriptors; | 
|   5954   { MaybeObject* maybe_result = Allocate(number_of_descriptors, |   5948   { MaybeObject* maybe_result = Allocate(number_of_descriptors, | 
|   5955                                          shared_mode); |   5949                                          shared_mode); | 
|   5956     if (!maybe_result->To(&new_descriptors)) return maybe_result; |   5950     if (!maybe_result->To(&new_descriptors)) return maybe_result; | 
|   5957   } |   5951   } | 
|   5958  |   5952  | 
|   5959   // Copy the content. |   5953   // Copy the content. | 
|   5960   if (number_of_descriptors > 0) { |   5954   if (number_of_descriptors > 0) { | 
|   5961     FixedArray::WhitenessWitness witness(new_descriptors); |   5955     FixedArray::WhitenessWitness witness(new_descriptors); | 
|   5962     for (int i = 0; i < number_of_descriptors; i++) { |   5956     for (int i = 0; i < number_of_descriptors; i++) { | 
|   5963       MaybeObject* copy_result = |   5957       MaybeObject* copy_result = | 
|   5964           new_descriptors->CopyFrom(i, this, i, witness); |   5958           new_descriptors->CopyFrom(i, this, i, witness); | 
|   5965       if (copy_result->IsFailure()) return copy_result; |   5959       if (copy_result->IsFailure()) return copy_result; | 
|   5966     } |   5960     } | 
 |   5961     new_descriptors->SetLastAdded(LastAdded()); | 
|   5967   } |   5962   } | 
|   5968   new_descriptors->SetNextEnumerationIndex(NextEnumerationIndex()); |   5963  | 
|   5969   return new_descriptors; |   5964   return new_descriptors; | 
|   5970 } |   5965 } | 
|   5971  |   5966  | 
|   5972 // We need the whiteness witness since sort will reshuffle the entries in the |   5967 // We need the whiteness witness since sort will reshuffle the entries in the | 
|   5973 // descriptor array. If the descriptor array were to be black, the shuffling |   5968 // descriptor array. If the descriptor array were to be black, the shuffling | 
|   5974 // would move a slot that was already recorded as pointing into an evacuation |   5969 // would move a slot that was already recorded as pointing into an evacuation | 
|   5975 // candidate. This would result in missing updates upon evacuation. |   5970 // candidate. This would result in missing updates upon evacuation. | 
|   5976 void DescriptorArray::SortUnchecked(const WhitenessWitness& witness) { |   5971 void DescriptorArray::SortUnchecked(const WhitenessWitness& witness) { | 
|   5977   // In-place heap sort. |   5972   // In-place heap sort. | 
|   5978   int len = number_of_descriptors(); |   5973   int len = number_of_descriptors(); | 
 |   5974   // Nothing to sort. | 
 |   5975   if (len == 0) return; | 
|   5979  |   5976  | 
|   5980   // Bottom-up max-heap construction. |   5977   // Bottom-up max-heap construction. | 
|   5981   // Index of the last node with children |   5978   // Index of the last node with children | 
|   5982   const int max_parent_index = (len / 2) - 1; |   5979   const int max_parent_index = (len / 2) - 1; | 
|   5983   for (int i = max_parent_index; i >= 0; --i) { |   5980   for (int i = max_parent_index; i >= 0; --i) { | 
|   5984     int parent_index = i; |   5981     int parent_index = i; | 
|   5985     const uint32_t parent_hash = GetKey(i)->Hash(); |   5982     const uint32_t parent_hash = GetKey(i)->Hash(); | 
|   5986     while (parent_index <= max_parent_index) { |   5983     while (parent_index <= max_parent_index) { | 
|   5987       int child_index = 2 * parent_index + 1; |   5984       int child_index = 2 * parent_index + 1; | 
|   5988       uint32_t child_hash = GetKey(child_index)->Hash(); |   5985       uint32_t child_hash = GetKey(child_index)->Hash(); | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
|   6016         if (right_child_hash > child_hash) { |   6013         if (right_child_hash > child_hash) { | 
|   6017           child_index++; |   6014           child_index++; | 
|   6018           child_hash = right_child_hash; |   6015           child_hash = right_child_hash; | 
|   6019         } |   6016         } | 
|   6020       } |   6017       } | 
|   6021       if (child_hash <= parent_hash) break; |   6018       if (child_hash <= parent_hash) break; | 
|   6022       NoIncrementalWriteBarrierSwapDescriptors(parent_index, child_index); |   6019       NoIncrementalWriteBarrierSwapDescriptors(parent_index, child_index); | 
|   6023       parent_index = child_index; |   6020       parent_index = child_index; | 
|   6024     } |   6021     } | 
|   6025   } |   6022   } | 
 |   6023  | 
 |   6024   int last_enum_index = -1; | 
 |   6025   int last_added = -1; | 
 |   6026   for (int i = 0; i < len; ++i) { | 
 |   6027     int current_enum = GetDetails(i).index(); | 
 |   6028     if (current_enum > last_enum_index) { | 
 |   6029       last_added = i; | 
 |   6030       last_enum_index = current_enum; | 
 |   6031     } | 
 |   6032   } | 
 |   6033   SetLastAdded(last_added); | 
 |   6034  | 
 |   6035   ASSERT(LastAdded() != -1); | 
|   6026 } |   6036 } | 
|   6027  |   6037  | 
|   6028  |   6038  | 
|   6029 void DescriptorArray::Sort(const WhitenessWitness& witness) { |   6039 void DescriptorArray::Sort(const WhitenessWitness& witness) { | 
|   6030   SortUnchecked(witness); |   6040   SortUnchecked(witness); | 
|   6031   SLOW_ASSERT(IsSortedNoDuplicates()); |   6041   SLOW_ASSERT(IsSortedNoDuplicates()); | 
|   6032 } |   6042 } | 
|   6033  |   6043  | 
|   6034  |   6044  | 
|   6035 MaybeObject* AccessorPair::CopyWithoutTransitions() { |   6045 MaybeObject* AccessorPair::CopyWithoutTransitions() { | 
| (...skipping 6677 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  12713         if (!maybe_key->ToObject(&key)) return maybe_key; |  12723         if (!maybe_key->ToObject(&key)) return maybe_key; | 
|  12714       } |  12724       } | 
|  12715       PropertyDetails details = DetailsAt(i); |  12725       PropertyDetails details = DetailsAt(i); | 
|  12716       PropertyType type = details.type(); |  12726       PropertyType type = details.type(); | 
|  12717  |  12727  | 
|  12718       if (value->IsJSFunction() && !heap->InNewSpace(value)) { |  12728       if (value->IsJSFunction() && !heap->InNewSpace(value)) { | 
|  12719         ConstantFunctionDescriptor d(String::cast(key), |  12729         ConstantFunctionDescriptor d(String::cast(key), | 
|  12720                                      JSFunction::cast(value), |  12730                                      JSFunction::cast(value), | 
|  12721                                      details.attributes(), |  12731                                      details.attributes(), | 
|  12722                                      details.index()); |  12732                                      details.index()); | 
|  12723         descriptors->Set(next_descriptor++, &d, witness); |  12733         descriptors->Set(next_descriptor, &d, witness); | 
|  12724       } else if (type == NORMAL) { |  12734       } else if (type == NORMAL) { | 
|  12725         if (current_offset < inobject_props) { |  12735         if (current_offset < inobject_props) { | 
|  12726           obj->InObjectPropertyAtPut(current_offset, |  12736           obj->InObjectPropertyAtPut(current_offset, | 
|  12727                                      value, |  12737                                      value, | 
|  12728                                      UPDATE_WRITE_BARRIER); |  12738                                      UPDATE_WRITE_BARRIER); | 
|  12729         } else { |  12739         } else { | 
|  12730           int offset = current_offset - inobject_props; |  12740           int offset = current_offset - inobject_props; | 
|  12731           FixedArray::cast(fields)->set(offset, value); |  12741           FixedArray::cast(fields)->set(offset, value); | 
|  12732         } |  12742         } | 
|  12733         FieldDescriptor d(String::cast(key), |  12743         FieldDescriptor d(String::cast(key), | 
|  12734                           current_offset++, |  12744                           current_offset++, | 
|  12735                           details.attributes(), |  12745                           details.attributes(), | 
|  12736                           details.index()); |  12746                           details.index()); | 
|  12737         descriptors->Set(next_descriptor++, &d, witness); |  12747         descriptors->Set(next_descriptor, &d, witness); | 
|  12738       } else if (type == CALLBACKS) { |  12748       } else if (type == CALLBACKS) { | 
|  12739         if (value->IsAccessorPair()) { |  12749         if (value->IsAccessorPair()) { | 
|  12740           MaybeObject* maybe_copy = |  12750           MaybeObject* maybe_copy = | 
|  12741               AccessorPair::cast(value)->CopyWithoutTransitions(); |  12751               AccessorPair::cast(value)->CopyWithoutTransitions(); | 
|  12742           if (!maybe_copy->To(&value)) return maybe_copy; |  12752           if (!maybe_copy->To(&value)) return maybe_copy; | 
|  12743         } |  12753         } | 
|  12744         CallbacksDescriptor d(String::cast(key), |  12754         CallbacksDescriptor d(String::cast(key), | 
|  12745                               value, |  12755                               value, | 
|  12746                               details.attributes(), |  12756                               details.attributes(), | 
|  12747                               details.index()); |  12757                               details.index()); | 
|  12748         descriptors->Set(next_descriptor++, &d, witness); |  12758         descriptors->Set(next_descriptor, &d, witness); | 
|  12749       } else { |  12759       } else { | 
|  12750         UNREACHABLE(); |  12760         UNREACHABLE(); | 
|  12751       } |  12761       } | 
 |  12762       ++next_descriptor; | 
|  12752     } |  12763     } | 
|  12753   } |  12764   } | 
|  12754   ASSERT(current_offset == number_of_fields); |  12765   ASSERT(current_offset == number_of_fields); | 
|  12755  |  12766  | 
|  12756   descriptors->Sort(witness); |  12767   descriptors->Sort(witness); | 
|  12757   // Allocate new map. |  12768   // Allocate new map. | 
|  12758   Object* new_map; |  12769   Object* new_map; | 
|  12759   { MaybeObject* maybe_new_map = obj->map()->CopyDropDescriptors(); |  12770   { MaybeObject* maybe_new_map = obj->map()->CopyDropDescriptors(); | 
|  12760     if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |  12771     if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; | 
|  12761   } |  12772   } | 
|  12762  |  12773  | 
|  12763   // Transform the object. |  12774   // Transform the object. | 
|  12764   obj->set_map(Map::cast(new_map)); |  12775   obj->set_map(Map::cast(new_map)); | 
|  12765   obj->map()->set_instance_descriptors(descriptors); |  12776   obj->map()->set_instance_descriptors(descriptors); | 
|  12766   obj->map()->set_unused_property_fields(unused_property_fields); |  12777   obj->map()->set_unused_property_fields(unused_property_fields); | 
|  12767  |  12778  | 
|  12768   obj->set_properties(FixedArray::cast(fields)); |  12779   obj->set_properties(FixedArray::cast(fields)); | 
|  12769   ASSERT(obj->IsJSObject()); |  12780   ASSERT(obj->IsJSObject()); | 
|  12770  |  12781  | 
|  12771   descriptors->SetNextEnumerationIndex(NextEnumerationIndex()); |  | 
|  12772   // Check that it really works. |  12782   // Check that it really works. | 
|  12773   ASSERT(obj->HasFastProperties()); |  12783   ASSERT(obj->HasFastProperties()); | 
|  12774  |  12784  | 
|  12775   return obj; |  12785   return obj; | 
|  12776 } |  12786 } | 
|  12777  |  12787  | 
|  12778  |  12788  | 
|  12779 bool ObjectHashSet::Contains(Object* key) { |  12789 bool ObjectHashSet::Contains(Object* key) { | 
|  12780   ASSERT(IsKey(key)); |  12790   ASSERT(IsKey(key)); | 
|  12781  |  12791  | 
| (...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  13273   set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |  13283   set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 
|  13274   set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |  13284   set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 
|  13275   set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |  13285   set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 
|  13276   set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |  13286   set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 
|  13277   set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |  13287   set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 
|  13278   set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |  13288   set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 
|  13279   set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |  13289   set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 
|  13280 } |  13290 } | 
|  13281  |  13291  | 
|  13282 } }  // namespace v8::internal |  13292 } }  // namespace v8::internal | 
| OLD | NEW |