| 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 |