Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(902)

Side by Side Diff: src/objects.cc

Issue 440063002: Move ClearNonLiveReferences and friends into the gc. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/heap/mark-compact.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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/accessors.h" 7 #include "src/accessors.h"
8 #include "src/allocation-site-scopes.h" 8 #include "src/allocation-site-scopes.h"
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/arguments.h" 10 #include "src/arguments.h"
(...skipping 9515 matching lines...) Expand 10 before | Expand all | Expand 10 after
9526 9526
9527 9527
9528 void String::PrintOn(FILE* file) { 9528 void String::PrintOn(FILE* file) {
9529 int length = this->length(); 9529 int length = this->length();
9530 for (int i = 0; i < length; i++) { 9530 for (int i = 0; i < length; i++) {
9531 PrintF(file, "%c", Get(i)); 9531 PrintF(file, "%c", Get(i));
9532 } 9532 }
9533 } 9533 }
9534 9534
9535 9535
9536 static void TrimEnumCache(Heap* heap, Map* map, DescriptorArray* descriptors) {
9537 int live_enum = map->EnumLength();
9538 if (live_enum == kInvalidEnumCacheSentinel) {
9539 live_enum = map->NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_ENUM);
9540 }
9541 if (live_enum == 0) return descriptors->ClearEnumCache();
9542
9543 FixedArray* enum_cache = descriptors->GetEnumCache();
9544
9545 int to_trim = enum_cache->length() - live_enum;
9546 if (to_trim <= 0) return;
9547 heap->RightTrimFixedArray<Heap::FROM_GC>(
9548 descriptors->GetEnumCache(), to_trim);
9549
9550 if (!descriptors->HasEnumIndicesCache()) return;
9551 FixedArray* enum_indices_cache = descriptors->GetEnumIndicesCache();
9552 heap->RightTrimFixedArray<Heap::FROM_GC>(enum_indices_cache, to_trim);
9553 }
9554
9555
9556 static void TrimDescriptorArray(Heap* heap,
9557 Map* map,
9558 DescriptorArray* descriptors,
9559 int number_of_own_descriptors) {
9560 int number_of_descriptors = descriptors->number_of_descriptors_storage();
9561 int to_trim = number_of_descriptors - number_of_own_descriptors;
9562 if (to_trim == 0) return;
9563
9564 heap->RightTrimFixedArray<Heap::FROM_GC>(
9565 descriptors, to_trim * DescriptorArray::kDescriptorSize);
9566 descriptors->SetNumberOfDescriptors(number_of_own_descriptors);
9567
9568 if (descriptors->HasEnumCache()) TrimEnumCache(heap, map, descriptors);
9569 descriptors->Sort();
9570 }
9571
9572
9573 // Clear a possible back pointer in case the transition leads to a dead map.
9574 // Return true in case a back pointer has been cleared and false otherwise.
9575 static bool ClearBackPointer(Heap* heap, Map* target) {
9576 if (Marking::MarkBitFrom(target).Get()) return false;
9577 target->SetBackPointer(heap->undefined_value(), SKIP_WRITE_BARRIER);
9578 return true;
9579 }
9580
9581
9582 // TODO(mstarzinger): This method should be moved into MarkCompactCollector,
9583 // because it cannot be called from outside the GC and we already have methods
9584 // depending on the transitions layout in the GC anyways.
9585 void Map::ClearNonLiveTransitions(Heap* heap) {
9586 // If there are no transitions to be cleared, return.
9587 // TODO(verwaest) Should be an assert, otherwise back pointers are not
9588 // properly cleared.
9589 if (!HasTransitionArray()) return;
9590
9591 TransitionArray* t = transitions();
9592 MarkCompactCollector* collector = heap->mark_compact_collector();
9593
9594 int transition_index = 0;
9595
9596 DescriptorArray* descriptors = instance_descriptors();
9597 bool descriptors_owner_died = false;
9598
9599 // Compact all live descriptors to the left.
9600 for (int i = 0; i < t->number_of_transitions(); ++i) {
9601 Map* target = t->GetTarget(i);
9602 if (ClearBackPointer(heap, target)) {
9603 if (target->instance_descriptors() == descriptors) {
9604 descriptors_owner_died = true;
9605 }
9606 } else {
9607 if (i != transition_index) {
9608 Name* key = t->GetKey(i);
9609 t->SetKey(transition_index, key);
9610 Object** key_slot = t->GetKeySlot(transition_index);
9611 collector->RecordSlot(key_slot, key_slot, key);
9612 // Target slots do not need to be recorded since maps are not compacted.
9613 t->SetTarget(transition_index, t->GetTarget(i));
9614 }
9615 transition_index++;
9616 }
9617 }
9618
9619 // If there are no transitions to be cleared, return.
9620 // TODO(verwaest) Should be an assert, otherwise back pointers are not
9621 // properly cleared.
9622 if (transition_index == t->number_of_transitions()) return;
9623
9624 int number_of_own_descriptors = NumberOfOwnDescriptors();
9625
9626 if (descriptors_owner_died) {
9627 if (number_of_own_descriptors > 0) {
9628 TrimDescriptorArray(heap, this, descriptors, number_of_own_descriptors);
9629 DCHECK(descriptors->number_of_descriptors() == number_of_own_descriptors);
9630 set_owns_descriptors(true);
9631 } else {
9632 DCHECK(descriptors == GetHeap()->empty_descriptor_array());
9633 }
9634 }
9635
9636 // Note that we never eliminate a transition array, though we might right-trim
9637 // such that number_of_transitions() == 0. If this assumption changes,
9638 // TransitionArray::CopyInsert() will need to deal with the case that a
9639 // transition array disappeared during GC.
9640 int trim = t->number_of_transitions() - transition_index;
9641 if (trim > 0) {
9642 heap->RightTrimFixedArray<Heap::FROM_GC>(t, t->IsSimpleTransition()
9643 ? trim : trim * TransitionArray::kTransitionSize);
9644 }
9645 DCHECK(HasTransitionArray());
9646 }
9647
9648
9649 int Map::Hash() { 9536 int Map::Hash() {
9650 // For performance reasons we only hash the 3 most variable fields of a map: 9537 // For performance reasons we only hash the 3 most variable fields of a map:
9651 // constructor, prototype and bit_field2. 9538 // constructor, prototype and bit_field2.
9652 9539
9653 // Shift away the tag. 9540 // Shift away the tag.
9654 int hash = (static_cast<uint32_t>( 9541 int hash = (static_cast<uint32_t>(
9655 reinterpret_cast<uintptr_t>(constructor())) >> 2); 9542 reinterpret_cast<uintptr_t>(constructor())) >> 2);
9656 9543
9657 // XOR-ing the prototype and constructor directly yields too many zero bits 9544 // XOR-ing the prototype and constructor directly yields too many zero bits
9658 // when the two pointers are close (which is fairly common). 9545 // when the two pointers are close (which is fairly common).
(...skipping 7344 matching lines...) Expand 10 before | Expand all | Expand 10 after
17003 #define ERROR_MESSAGES_TEXTS(C, T) T, 16890 #define ERROR_MESSAGES_TEXTS(C, T) T,
17004 static const char* error_messages_[] = { 16891 static const char* error_messages_[] = {
17005 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16892 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
17006 }; 16893 };
17007 #undef ERROR_MESSAGES_TEXTS 16894 #undef ERROR_MESSAGES_TEXTS
17008 return error_messages_[reason]; 16895 return error_messages_[reason];
17009 } 16896 }
17010 16897
17011 16898
17012 } } // namespace v8::internal 16899 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap/mark-compact.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698