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 "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #include "accessors.h" | 7 #include "accessors.h" |
8 #include "api.h" | 8 #include "api.h" |
9 #include "bootstrapper.h" | 9 #include "bootstrapper.h" |
10 #include "codegen.h" | 10 #include "codegen.h" |
(...skipping 5819 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5830 static bool SafeIsNativeContext(HeapObject* obj) { | 5830 static bool SafeIsNativeContext(HeapObject* obj) { |
5831 return obj->map() == obj->GetHeap()->raw_unchecked_native_context_map(); | 5831 return obj->map() == obj->GetHeap()->raw_unchecked_native_context_map(); |
5832 } | 5832 } |
5833 | 5833 |
5834 | 5834 |
5835 void PathTracer::MarkRecursively(Object** p, MarkVisitor* mark_visitor) { | 5835 void PathTracer::MarkRecursively(Object** p, MarkVisitor* mark_visitor) { |
5836 if (!(*p)->IsHeapObject()) return; | 5836 if (!(*p)->IsHeapObject()) return; |
5837 | 5837 |
5838 HeapObject* obj = HeapObject::cast(*p); | 5838 HeapObject* obj = HeapObject::cast(*p); |
5839 | 5839 |
5840 Object* map = obj->map(); | 5840 MapWord map_word = obj->map_word(); |
5841 | 5841 if (!map_word.ToMap()->IsHeapObject()) return; // visited before |
5842 if (!map->IsHeapObject()) return; // visited before | |
5843 | 5842 |
5844 if (found_target_in_trace_) return; // stop if target found | 5843 if (found_target_in_trace_) return; // stop if target found |
5845 object_stack_.Add(obj); | 5844 object_stack_.Add(obj); |
5846 if (((search_target_ == kAnyGlobalObject) && obj->IsJSGlobalObject()) || | 5845 if (((search_target_ == kAnyGlobalObject) && obj->IsJSGlobalObject()) || |
5847 (obj == search_target_)) { | 5846 (obj == search_target_)) { |
5848 found_target_in_trace_ = true; | 5847 found_target_in_trace_ = true; |
5849 found_target_ = true; | 5848 found_target_ = true; |
5850 return; | 5849 return; |
5851 } | 5850 } |
5852 | 5851 |
5853 bool is_native_context = SafeIsNativeContext(obj); | 5852 bool is_native_context = SafeIsNativeContext(obj); |
5854 | 5853 |
5855 // not visited yet | 5854 // not visited yet |
5856 Map* map_p = reinterpret_cast<Map*>(HeapObject::cast(map)); | 5855 Map* map = Map::cast(map_word.ToMap()); |
5857 | 5856 |
5858 Address map_addr = map_p->address(); | 5857 MapWord marked_map_word = |
5859 | 5858 MapWord::FromRawValue(obj->map_word().ToRawValue() + kMarkTag); |
5860 obj->set_map_no_write_barrier(reinterpret_cast<Map*>(map_addr + kMarkTag)); | 5859 obj->set_map_word(marked_map_word); |
5861 | 5860 |
5862 // Scan the object body. | 5861 // Scan the object body. |
5863 if (is_native_context && (visit_mode_ == VISIT_ONLY_STRONG)) { | 5862 if (is_native_context && (visit_mode_ == VISIT_ONLY_STRONG)) { |
5864 // This is specialized to scan Context's properly. | 5863 // This is specialized to scan Context's properly. |
5865 Object** start = reinterpret_cast<Object**>(obj->address() + | 5864 Object** start = reinterpret_cast<Object**>(obj->address() + |
5866 Context::kHeaderSize); | 5865 Context::kHeaderSize); |
5867 Object** end = reinterpret_cast<Object**>(obj->address() + | 5866 Object** end = reinterpret_cast<Object**>(obj->address() + |
5868 Context::kHeaderSize + Context::FIRST_WEAK_SLOT * kPointerSize); | 5867 Context::kHeaderSize + Context::FIRST_WEAK_SLOT * kPointerSize); |
5869 mark_visitor->VisitPointers(start, end); | 5868 mark_visitor->VisitPointers(start, end); |
5870 } else { | 5869 } else { |
5871 obj->IterateBody(map_p->instance_type(), | 5870 obj->IterateBody(map->instance_type(), obj->SizeFromMap(map), mark_visitor); |
5872 obj->SizeFromMap(map_p), | |
5873 mark_visitor); | |
5874 } | 5871 } |
5875 | 5872 |
5876 // Scan the map after the body because the body is a lot more interesting | 5873 // Scan the map after the body because the body is a lot more interesting |
5877 // when doing leak detection. | 5874 // when doing leak detection. |
5878 MarkRecursively(&map, mark_visitor); | 5875 MarkRecursively(reinterpret_cast<Object**>(&map), mark_visitor); |
5879 | 5876 |
5880 if (!found_target_in_trace_) // don't pop if found the target | 5877 if (!found_target_in_trace_) { // don't pop if found the target |
5881 object_stack_.RemoveLast(); | 5878 object_stack_.RemoveLast(); |
| 5879 } |
5882 } | 5880 } |
5883 | 5881 |
5884 | 5882 |
5885 void PathTracer::UnmarkRecursively(Object** p, UnmarkVisitor* unmark_visitor) { | 5883 void PathTracer::UnmarkRecursively(Object** p, UnmarkVisitor* unmark_visitor) { |
5886 if (!(*p)->IsHeapObject()) return; | 5884 if (!(*p)->IsHeapObject()) return; |
5887 | 5885 |
5888 HeapObject* obj = HeapObject::cast(*p); | 5886 HeapObject* obj = HeapObject::cast(*p); |
5889 | 5887 |
5890 Object* map = obj->map(); | 5888 MapWord map_word = obj->map_word(); |
| 5889 if (map_word.ToMap()->IsHeapObject()) return; // unmarked already |
5891 | 5890 |
5892 if (map->IsHeapObject()) return; // unmarked already | 5891 MapWord unmarked_map_word = |
| 5892 MapWord::FromRawValue(map_word.ToRawValue() - kMarkTag); |
| 5893 obj->set_map_word(unmarked_map_word); |
5893 | 5894 |
5894 Address map_addr = reinterpret_cast<Address>(map); | 5895 Map* map = Map::cast(unmarked_map_word.ToMap()); |
5895 | 5896 |
5896 map_addr -= kMarkTag; | 5897 UnmarkRecursively(reinterpret_cast<Object**>(&map), unmark_visitor); |
5897 | 5898 |
5898 ASSERT_TAG_ALIGNED(map_addr); | 5899 obj->IterateBody(map->instance_type(), obj->SizeFromMap(map), unmark_visitor); |
5899 | |
5900 HeapObject* map_p = HeapObject::FromAddress(map_addr); | |
5901 | |
5902 obj->set_map_no_write_barrier(reinterpret_cast<Map*>(map_p)); | |
5903 | |
5904 UnmarkRecursively(reinterpret_cast<Object**>(&map_p), unmark_visitor); | |
5905 | |
5906 obj->IterateBody(Map::cast(map_p)->instance_type(), | |
5907 obj->SizeFromMap(Map::cast(map_p)), | |
5908 unmark_visitor); | |
5909 } | 5900 } |
5910 | 5901 |
5911 | 5902 |
5912 void PathTracer::ProcessResults() { | 5903 void PathTracer::ProcessResults() { |
5913 if (found_target_) { | 5904 if (found_target_) { |
5914 PrintF("=====================================\n"); | 5905 PrintF("=====================================\n"); |
5915 PrintF("==== Path to object ====\n"); | 5906 PrintF("==== Path to object ====\n"); |
5916 PrintF("=====================================\n\n"); | 5907 PrintF("=====================================\n\n"); |
5917 | 5908 |
5918 ASSERT(!object_stack_.is_empty()); | 5909 ASSERT(!object_stack_.is_empty()); |
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6417 static_cast<int>(object_sizes_last_time_[index])); | 6408 static_cast<int>(object_sizes_last_time_[index])); |
6418 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) | 6409 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) |
6419 #undef ADJUST_LAST_TIME_OBJECT_COUNT | 6410 #undef ADJUST_LAST_TIME_OBJECT_COUNT |
6420 | 6411 |
6421 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); | 6412 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); |
6422 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); | 6413 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); |
6423 ClearObjectStats(); | 6414 ClearObjectStats(); |
6424 } | 6415 } |
6425 | 6416 |
6426 } } // namespace v8::internal | 6417 } } // namespace v8::internal |
OLD | NEW |