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 1586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1597 if (!maybe_values->ToObject(&values)) return maybe_values; | 1597 if (!maybe_values->ToObject(&values)) return maybe_values; |
1598 } | 1598 } |
1599 set_properties(FixedArray::cast(values)); | 1599 set_properties(FixedArray::cast(values)); |
1600 new_map->set_unused_property_fields(kFieldsAdded - 1); | 1600 new_map->set_unused_property_fields(kFieldsAdded - 1); |
1601 } else { | 1601 } else { |
1602 new_map->set_unused_property_fields(map()->unused_property_fields() - 1); | 1602 new_map->set_unused_property_fields(map()->unused_property_fields() - 1); |
1603 } | 1603 } |
1604 // We have now allocated all the necessary objects. | 1604 // We have now allocated all the necessary objects. |
1605 // All the changes can be applied at once, so they are atomic. | 1605 // All the changes can be applied at once, so they are atomic. |
1606 map()->set_instance_descriptors(old_descriptors); | 1606 map()->set_instance_descriptors(old_descriptors); |
| 1607 new_map->SetBackPointer(map()); |
1607 new_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); | 1608 new_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); |
1608 set_map(new_map); | 1609 set_map(new_map); |
1609 return FastPropertyAtPut(index, value); | 1610 return FastPropertyAtPut(index, value); |
1610 } | 1611 } |
1611 | 1612 |
1612 | 1613 |
1613 MaybeObject* JSObject::AddConstantFunctionProperty( | 1614 MaybeObject* JSObject::AddConstantFunctionProperty( |
1614 String* name, | 1615 String* name, |
1615 JSFunction* function, | 1616 JSFunction* function, |
1616 PropertyAttributes attributes) { | 1617 PropertyAttributes attributes) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1657 } | 1658 } |
1658 ConstTransitionDescriptor mark(name, Map::cast(new_map)); | 1659 ConstTransitionDescriptor mark(name, Map::cast(new_map)); |
1659 { MaybeObject* maybe_new_descriptors = | 1660 { MaybeObject* maybe_new_descriptors = |
1660 old_map->instance_descriptors()->CopyInsert(&mark, KEEP_TRANSITIONS); | 1661 old_map->instance_descriptors()->CopyInsert(&mark, KEEP_TRANSITIONS); |
1661 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { | 1662 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { |
1662 // We have accomplished the main goal, so return success. | 1663 // We have accomplished the main goal, so return success. |
1663 return function; | 1664 return function; |
1664 } | 1665 } |
1665 } | 1666 } |
1666 old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); | 1667 old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); |
| 1668 Map::cast(new_map)->SetBackPointer(old_map); |
1667 | 1669 |
1668 return function; | 1670 return function; |
1669 } | 1671 } |
1670 | 1672 |
1671 | 1673 |
1672 // Add property in slow mode | 1674 // Add property in slow mode |
1673 MaybeObject* JSObject::AddSlowProperty(String* name, | 1675 MaybeObject* JSObject::AddSlowProperty(String* name, |
1674 Object* value, | 1676 Object* value, |
1675 PropertyAttributes attributes) { | 1677 PropertyAttributes attributes) { |
1676 ASSERT(!HasFastProperties()); | 1678 ASSERT(!HasFastProperties()); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1817 map(), | 1819 map(), |
1818 attributes); | 1820 attributes); |
1819 Object* new_descriptors; | 1821 Object* new_descriptors; |
1820 { MaybeObject* maybe_new_descriptors = old_map->instance_descriptors()-> | 1822 { MaybeObject* maybe_new_descriptors = old_map->instance_descriptors()-> |
1821 CopyInsert(&transition, KEEP_TRANSITIONS); | 1823 CopyInsert(&transition, KEEP_TRANSITIONS); |
1822 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { | 1824 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { |
1823 return result; // Yes, return _result_. | 1825 return result; // Yes, return _result_. |
1824 } | 1826 } |
1825 } | 1827 } |
1826 old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); | 1828 old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); |
| 1829 map()->SetBackPointer(old_map); |
1827 return result; | 1830 return result; |
1828 } | 1831 } |
1829 | 1832 |
1830 | 1833 |
1831 MaybeObject* JSObject::ConvertDescriptorToField(String* name, | 1834 MaybeObject* JSObject::ConvertDescriptorToField(String* name, |
1832 Object* new_value, | 1835 Object* new_value, |
1833 PropertyAttributes attributes) { | 1836 PropertyAttributes attributes) { |
1834 if (map()->unused_property_fields() == 0 && | 1837 if (map()->unused_property_fields() == 0 && |
1835 properties()->length() > MaxFastProperties()) { | 1838 properties()->length() > MaxFastProperties()) { |
1836 Object* obj; | 1839 Object* obj; |
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2401 | 2404 |
2402 ElementsTransitionDescriptor desc(elements_transition_sentinel_name(), | 2405 ElementsTransitionDescriptor desc(elements_transition_sentinel_name(), |
2403 new_contents); | 2406 new_contents); |
2404 Object* new_descriptors; | 2407 Object* new_descriptors; |
2405 MaybeObject* maybe_new_descriptors = | 2408 MaybeObject* maybe_new_descriptors = |
2406 instance_descriptors()->CopyInsert(&desc, KEEP_TRANSITIONS); | 2409 instance_descriptors()->CopyInsert(&desc, KEEP_TRANSITIONS); |
2407 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { | 2410 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { |
2408 return maybe_new_descriptors; | 2411 return maybe_new_descriptors; |
2409 } | 2412 } |
2410 set_instance_descriptors(DescriptorArray::cast(new_descriptors)); | 2413 set_instance_descriptors(DescriptorArray::cast(new_descriptors)); |
| 2414 transitioned_map->SetBackPointer(this); |
2411 return this; | 2415 return this; |
2412 } | 2416 } |
2413 | 2417 |
2414 | 2418 |
2415 Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object, | 2419 Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object, |
2416 ElementsKind to_kind) { | 2420 ElementsKind to_kind) { |
2417 Isolate* isolate = object->GetIsolate(); | 2421 Isolate* isolate = object->GetIsolate(); |
2418 CALL_HEAP_FUNCTION(isolate, | 2422 CALL_HEAP_FUNCTION(isolate, |
2419 object->GetElementsTransitionMap(isolate, to_kind), | 2423 object->GetElementsTransitionMap(isolate, to_kind), |
2420 Map); | 2424 Map); |
(...skipping 2225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4646 DescriptorArray* descriptors1; | 4650 DescriptorArray* descriptors1; |
4647 { MaybeObject* maybe_descriptors1 = | 4651 { MaybeObject* maybe_descriptors1 = |
4648 map1->instance_descriptors()->CopyInsert(&callbacks_descr1, | 4652 map1->instance_descriptors()->CopyInsert(&callbacks_descr1, |
4649 KEEP_TRANSITIONS); | 4653 KEEP_TRANSITIONS); |
4650 if (!maybe_descriptors1->To(&descriptors1)) return maybe_descriptors1; | 4654 if (!maybe_descriptors1->To(&descriptors1)) return maybe_descriptors1; |
4651 } | 4655 } |
4652 | 4656 |
4653 // step 6: everything went well so far, so we make our changes visible | 4657 // step 6: everything went well so far, so we make our changes visible |
4654 obj->set_map(map2); | 4658 obj->set_map(map2); |
4655 map1->set_instance_descriptors(descriptors1); | 4659 map1->set_instance_descriptors(descriptors1); |
| 4660 map2->SetBackPointer(map1); |
4656 return obj; | 4661 return obj; |
4657 } | 4662 } |
4658 | 4663 |
4659 | 4664 |
4660 static bool TransitionToSameAccessor(Object* map, | 4665 static bool TransitionToSameAccessor(Object* map, |
4661 String* name, | 4666 String* name, |
4662 AccessorComponent component, | 4667 AccessorComponent component, |
4663 Object* accessor, | 4668 Object* accessor, |
4664 PropertyAttributes attributes ) { | 4669 PropertyAttributes attributes ) { |
4665 DescriptorArray* descs = Map::cast(map)->instance_descriptors(); | 4670 DescriptorArray* descs = Map::cast(map)->instance_descriptors(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4698 // step 3: create a new map with the new descriptors | 4703 // step 3: create a new map with the new descriptors |
4699 Map* map3; | 4704 Map* map3; |
4700 { MaybeObject* maybe_map3 = map2->CopyDropDescriptors(); | 4705 { MaybeObject* maybe_map3 = map2->CopyDropDescriptors(); |
4701 if (!maybe_map3->To(&map3)) return maybe_map3; | 4706 if (!maybe_map3->To(&map3)) return maybe_map3; |
4702 } | 4707 } |
4703 map3->set_instance_descriptors(descriptors3); | 4708 map3->set_instance_descriptors(descriptors3); |
4704 | 4709 |
4705 // step 4: everything went well so far, so we make our changes visible | 4710 // step 4: everything went well so far, so we make our changes visible |
4706 obj->set_map(map3); | 4711 obj->set_map(map3); |
4707 accessors2->set(component, map3); | 4712 accessors2->set(component, map3); |
| 4713 map3->SetBackPointer(map2); |
4708 return obj; | 4714 return obj; |
4709 } | 4715 } |
4710 | 4716 |
4711 | 4717 |
4712 MaybeObject* JSObject::DefineFastAccessor(String* name, | 4718 MaybeObject* JSObject::DefineFastAccessor(String* name, |
4713 AccessorComponent component, | 4719 AccessorComponent component, |
4714 Object* accessor, | 4720 Object* accessor, |
4715 PropertyAttributes attributes) { | 4721 PropertyAttributes attributes) { |
4716 ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined()); | 4722 ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined()); |
4717 LookupResult result(GetIsolate()); | 4723 LookupResult result(GetIsolate()); |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5130 } | 5136 } |
5131 | 5137 |
5132 DescriptorArray* descriptor_array_; | 5138 DescriptorArray* descriptor_array_; |
5133 }; | 5139 }; |
5134 | 5140 |
5135 | 5141 |
5136 // An iterator over all prototype transitions, reusing the map field of the | 5142 // An iterator over all prototype transitions, reusing the map field of the |
5137 // underlying array while it is running. | 5143 // underlying array while it is running. |
5138 class IntrusivePrototypeTransitionIterator { | 5144 class IntrusivePrototypeTransitionIterator { |
5139 public: | 5145 public: |
5140 explicit IntrusivePrototypeTransitionIterator(FixedArray* proto_trans) | 5146 explicit IntrusivePrototypeTransitionIterator(HeapObject* proto_trans) |
5141 : proto_trans_(proto_trans) { } | 5147 : proto_trans_(proto_trans) { } |
5142 | 5148 |
5143 void Start() { | 5149 void Start() { |
5144 ASSERT(!IsIterating()); | 5150 ASSERT(!IsIterating()); |
5145 if (HasTransitions()) *Header() = Smi::FromInt(0); | 5151 if (HasTransitions()) *Header() = Smi::FromInt(0); |
5146 } | 5152 } |
5147 | 5153 |
5148 bool IsIterating() { | 5154 bool IsIterating() { |
5149 return HasTransitions() && (*Header())->IsSmi(); | 5155 return HasTransitions() && (*Header())->IsSmi(); |
5150 } | 5156 } |
5151 | 5157 |
5152 Map* Next() { | 5158 Map* Next() { |
5153 ASSERT(IsIterating()); | 5159 ASSERT(IsIterating()); |
5154 int transitionNumber = Smi::cast(*Header())->value(); | 5160 int transitionNumber = Smi::cast(*Header())->value(); |
5155 if (transitionNumber < NumberOfTransitions()) { | 5161 if (transitionNumber < NumberOfTransitions()) { |
5156 *Header() = Smi::FromInt(transitionNumber + 1); | 5162 *Header() = Smi::FromInt(transitionNumber + 1); |
5157 return GetTransition(transitionNumber); | 5163 return GetTransition(transitionNumber); |
5158 } | 5164 } |
5159 *Header() = proto_trans_->GetHeap()->fixed_array_map(); | 5165 *Header() = proto_trans_->GetHeap()->fixed_array_map(); |
5160 return NULL; | 5166 return NULL; |
5161 } | 5167 } |
5162 | 5168 |
5163 private: | 5169 private: |
5164 bool HasTransitions() { | 5170 bool HasTransitions() { |
5165 return proto_trans_->length() >= Map::kProtoTransitionHeaderSize; | 5171 return proto_trans_->map()->IsSmi() || proto_trans_->IsFixedArray(); |
5166 } | 5172 } |
5167 | 5173 |
5168 Object** Header() { | 5174 Object** Header() { |
5169 return HeapObject::RawField(proto_trans_, FixedArray::kMapOffset); | 5175 return HeapObject::RawField(proto_trans_, FixedArray::kMapOffset); |
5170 } | 5176 } |
5171 | 5177 |
5172 int NumberOfTransitions() { | 5178 int NumberOfTransitions() { |
5173 Object* num = proto_trans_->get(Map::kProtoTransitionNumberOfEntriesOffset); | 5179 ASSERT(HasTransitions()); |
| 5180 FixedArray* proto_trans = reinterpret_cast<FixedArray*>(proto_trans_); |
| 5181 Object* num = proto_trans->get(Map::kProtoTransitionNumberOfEntriesOffset); |
5174 return Smi::cast(num)->value(); | 5182 return Smi::cast(num)->value(); |
5175 } | 5183 } |
5176 | 5184 |
5177 Map* GetTransition(int transitionNumber) { | 5185 Map* GetTransition(int transitionNumber) { |
5178 return Map::cast(proto_trans_->get(IndexFor(transitionNumber))); | 5186 ASSERT(HasTransitions()); |
| 5187 FixedArray* proto_trans = reinterpret_cast<FixedArray*>(proto_trans_); |
| 5188 return Map::cast(proto_trans->get(IndexFor(transitionNumber))); |
5179 } | 5189 } |
5180 | 5190 |
5181 int IndexFor(int transitionNumber) { | 5191 int IndexFor(int transitionNumber) { |
5182 return Map::kProtoTransitionHeaderSize + | 5192 return Map::kProtoTransitionHeaderSize + |
5183 Map::kProtoTransitionMapOffset + | 5193 Map::kProtoTransitionMapOffset + |
5184 transitionNumber * Map::kProtoTransitionElementsPerEntry; | 5194 transitionNumber * Map::kProtoTransitionElementsPerEntry; |
5185 } | 5195 } |
5186 | 5196 |
5187 FixedArray* proto_trans_; | 5197 HeapObject* proto_trans_; |
5188 }; | 5198 }; |
5189 | 5199 |
5190 | 5200 |
5191 // To traverse the transition tree iteratively, we have to store two kinds of | 5201 // To traverse the transition tree iteratively, we have to store two kinds of |
5192 // information in a map: The parent map in the traversal and which children of a | 5202 // information in a map: The parent map in the traversal and which children of a |
5193 // node have already been visited. To do this without additional memory, we | 5203 // node have already been visited. To do this without additional memory, we |
5194 // temporarily reuse two maps with known values: | 5204 // temporarily reuse two maps with known values: |
5195 // | 5205 // |
5196 // (1) The map of the map temporarily holds the parent, and is restored to the | 5206 // (1) The map of the map temporarily holds the parent, and is restored to the |
5197 // meta map afterwards. | 5207 // meta map afterwards. |
(...skipping 2141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7339 | 7349 |
7340 | 7350 |
7341 void String::PrintOn(FILE* file) { | 7351 void String::PrintOn(FILE* file) { |
7342 int length = this->length(); | 7352 int length = this->length(); |
7343 for (int i = 0; i < length; i++) { | 7353 for (int i = 0; i < length; i++) { |
7344 fprintf(file, "%c", Get(i)); | 7354 fprintf(file, "%c", Get(i)); |
7345 } | 7355 } |
7346 } | 7356 } |
7347 | 7357 |
7348 | 7358 |
7349 void Map::CreateOneBackPointer(Object* transition_target) { | 7359 // Clear a possible back pointer in case the transition leads to a dead map. |
7350 if (!transition_target->IsMap()) return; | 7360 // Return true in case a back pointer has been cleared and false otherwise. |
7351 Map* target = Map::cast(transition_target); | 7361 // Set *keep_entry to true when a live map transition has been found. |
7352 #ifdef DEBUG | 7362 static bool ClearBackPointer(Heap* heap, Object* target, bool* keep_entry) { |
7353 // Verify target. | 7363 if (!target->IsMap()) return false; |
7354 Object* source_prototype = prototype(); | 7364 Map* map = Map::cast(target); |
7355 Object* target_prototype = target->prototype(); | 7365 if (Marking::MarkBitFrom(map).Get()) { |
7356 ASSERT(source_prototype->IsJSReceiver() || | 7366 *keep_entry = true; |
7357 source_prototype->IsMap() || | 7367 return false; |
7358 source_prototype->IsNull()); | 7368 } else { |
7359 ASSERT(target_prototype->IsJSReceiver() || | 7369 map->SetBackPointer(heap->undefined_value(), SKIP_WRITE_BARRIER); |
7360 target_prototype->IsNull()); | 7370 return true; |
7361 ASSERT(source_prototype->IsMap() || | |
7362 source_prototype == target_prototype); | |
7363 #endif | |
7364 // Point target back to source. set_prototype() will not let us set | |
7365 // the prototype to a map, as we do here. | |
7366 *RawField(target, kPrototypeOffset) = this; | |
7367 } | |
7368 | |
7369 | |
7370 void Map::CreateBackPointers() { | |
7371 DescriptorArray* descriptors = instance_descriptors(); | |
7372 for (int i = 0; i < descriptors->number_of_descriptors(); i++) { | |
7373 switch (descriptors->GetType(i)) { | |
7374 case MAP_TRANSITION: | |
7375 case CONSTANT_TRANSITION: | |
7376 CreateOneBackPointer(descriptors->GetValue(i)); | |
7377 break; | |
7378 case ELEMENTS_TRANSITION: { | |
7379 Object* object = descriptors->GetValue(i); | |
7380 if (object->IsMap()) { | |
7381 CreateOneBackPointer(object); | |
7382 } else { | |
7383 FixedArray* array = FixedArray::cast(object); | |
7384 for (int i = 0; i < array->length(); ++i) { | |
7385 CreateOneBackPointer(array->get(i)); | |
7386 } | |
7387 } | |
7388 break; | |
7389 } | |
7390 case CALLBACKS: { | |
7391 Object* object = descriptors->GetValue(i); | |
7392 if (object->IsAccessorPair()) { | |
7393 AccessorPair* accessors = AccessorPair::cast(object); | |
7394 CreateOneBackPointer(accessors->getter()); | |
7395 CreateOneBackPointer(accessors->setter()); | |
7396 } | |
7397 break; | |
7398 } | |
7399 case NORMAL: | |
7400 case FIELD: | |
7401 case CONSTANT_FUNCTION: | |
7402 case HANDLER: | |
7403 case INTERCEPTOR: | |
7404 case NULL_DESCRIPTOR: | |
7405 break; | |
7406 } | |
7407 } | 7371 } |
7408 } | 7372 } |
7409 | 7373 |
7410 | 7374 |
7411 bool Map::RestoreOneBackPointer(Object* object, | 7375 void Map::ClearNonLiveTransitions(Heap* heap) { |
7412 Object* real_prototype, | |
7413 bool* keep_entry) { | |
7414 if (!object->IsMap()) return false; | |
7415 Map* map = Map::cast(object); | |
7416 if (Marking::MarkBitFrom(map).Get()) { | |
7417 *keep_entry = true; | |
7418 return false; | |
7419 } | |
7420 ASSERT(map->prototype() == this || map->prototype() == real_prototype); | |
7421 // Getter prototype() is read-only, set_prototype() has side effects. | |
7422 *RawField(map, Map::kPrototypeOffset) = real_prototype; | |
7423 return true; | |
7424 } | |
7425 | |
7426 | |
7427 void Map::ClearNonLiveTransitions(Heap* heap, Object* real_prototype) { | |
7428 DescriptorArray* d = DescriptorArray::cast( | 7376 DescriptorArray* d = DescriptorArray::cast( |
7429 *RawField(this, Map::kInstanceDescriptorsOrBitField3Offset)); | 7377 *RawField(this, Map::kInstanceDescriptorsOrBitField3Offset)); |
7430 if (d->IsEmpty()) return; | 7378 if (d->IsEmpty()) return; |
7431 Smi* NullDescriptorDetails = | 7379 Smi* NullDescriptorDetails = |
7432 PropertyDetails(NONE, NULL_DESCRIPTOR).AsSmi(); | 7380 PropertyDetails(NONE, NULL_DESCRIPTOR).AsSmi(); |
7433 FixedArray* contents = FixedArray::cast( | 7381 FixedArray* contents = FixedArray::cast( |
7434 d->get(DescriptorArray::kContentArrayIndex)); | 7382 d->get(DescriptorArray::kContentArrayIndex)); |
7435 ASSERT(contents->length() >= 2); | 7383 ASSERT(contents->length() >= 2); |
7436 for (int i = 0; i < contents->length(); i += 2) { | 7384 for (int i = 0; i < contents->length(); i += 2) { |
7437 // If the pair (value, details) is a map transition, check if the target is | 7385 // If the pair (value, details) is a map transition, check if the target is |
7438 // live. If not, null the descriptor. Also drop the back pointer for that | 7386 // live. If not, null the descriptor. Also drop the back pointer for that |
7439 // map transition, so that this map is not reached again by following a back | 7387 // map transition, so that this map is not reached again by following a back |
7440 // pointer from a non-live object. | 7388 // pointer from that non-live map. |
7441 bool keep_entry = false; | 7389 bool keep_entry = false; |
7442 PropertyDetails details(Smi::cast(contents->get(i + 1))); | 7390 PropertyDetails details(Smi::cast(contents->get(i + 1))); |
7443 switch (details.type()) { | 7391 switch (details.type()) { |
7444 case MAP_TRANSITION: | 7392 case MAP_TRANSITION: |
7445 case CONSTANT_TRANSITION: | 7393 case CONSTANT_TRANSITION: |
7446 RestoreOneBackPointer(contents->get(i), real_prototype, &keep_entry); | 7394 ClearBackPointer(heap, contents->get(i), &keep_entry); |
7447 break; | 7395 break; |
7448 case ELEMENTS_TRANSITION: { | 7396 case ELEMENTS_TRANSITION: { |
7449 Object* object = contents->get(i); | 7397 Object* object = contents->get(i); |
7450 if (object->IsMap()) { | 7398 if (object->IsMap()) { |
7451 RestoreOneBackPointer(object, real_prototype, &keep_entry); | 7399 ClearBackPointer(heap, object, &keep_entry); |
7452 } else { | 7400 } else { |
7453 FixedArray* array = FixedArray::cast(object); | 7401 FixedArray* array = FixedArray::cast(object); |
7454 for (int j = 0; j < array->length(); ++j) { | 7402 for (int j = 0; j < array->length(); ++j) { |
7455 if (RestoreOneBackPointer(array->get(j), | 7403 if (ClearBackPointer(heap, array->get(j), &keep_entry)) { |
7456 real_prototype, | |
7457 &keep_entry)) { | |
7458 array->set_undefined(j); | 7404 array->set_undefined(j); |
7459 } | 7405 } |
7460 } | 7406 } |
7461 } | 7407 } |
7462 break; | 7408 break; |
7463 } | 7409 } |
7464 case CALLBACKS: { | 7410 case CALLBACKS: { |
7465 Object* object = contents->get(i); | 7411 Object* object = contents->get(i); |
7466 if (object->IsAccessorPair()) { | 7412 if (object->IsAccessorPair()) { |
7467 AccessorPair* accessors = AccessorPair::cast(object); | 7413 AccessorPair* accessors = AccessorPair::cast(object); |
7468 if (RestoreOneBackPointer(accessors->getter(), | 7414 if (ClearBackPointer(heap, accessors->getter(), &keep_entry)) { |
7469 real_prototype, | |
7470 &keep_entry)) { | |
7471 accessors->set_getter(heap->the_hole_value()); | 7415 accessors->set_getter(heap->the_hole_value()); |
7472 } | 7416 } |
7473 if (RestoreOneBackPointer(accessors->setter(), | 7417 if (ClearBackPointer(heap, accessors->setter(), &keep_entry)) { |
7474 real_prototype, | |
7475 &keep_entry)) { | |
7476 accessors->set_setter(heap->the_hole_value()); | 7418 accessors->set_setter(heap->the_hole_value()); |
7477 } | 7419 } |
7478 } else { | 7420 } else { |
7479 keep_entry = true; | 7421 keep_entry = true; |
7480 } | 7422 } |
7481 break; | 7423 break; |
7482 } | 7424 } |
7483 case NORMAL: | 7425 case NORMAL: |
7484 case FIELD: | 7426 case FIELD: |
7485 case CONSTANT_FUNCTION: | 7427 case CONSTANT_FUNCTION: |
(...skipping 5677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13163 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 13105 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
13164 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 13106 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
13165 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 13107 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
13166 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 13108 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
13167 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 13109 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
13168 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 13110 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
13169 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 13111 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
13170 } | 13112 } |
13171 | 13113 |
13172 } } // namespace v8::internal | 13114 } } // namespace v8::internal |
OLD | NEW |