OLD | NEW |
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/heap-snapshot-generator-inl.h" | 7 #include "src/heap-snapshot-generator-inl.h" |
8 | 8 |
9 #include "src/allocation-tracker.h" | 9 #include "src/allocation-tracker.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 | 181 |
182 | 182 |
183 HeapSnapshot::HeapSnapshot(HeapProfiler* profiler, | 183 HeapSnapshot::HeapSnapshot(HeapProfiler* profiler, |
184 const char* title, | 184 const char* title, |
185 unsigned uid) | 185 unsigned uid) |
186 : profiler_(profiler), | 186 : profiler_(profiler), |
187 title_(title), | 187 title_(title), |
188 uid_(uid), | 188 uid_(uid), |
189 root_index_(HeapEntry::kNoEntry), | 189 root_index_(HeapEntry::kNoEntry), |
190 gc_roots_index_(HeapEntry::kNoEntry), | 190 gc_roots_index_(HeapEntry::kNoEntry), |
191 natives_root_index_(HeapEntry::kNoEntry), | |
192 max_snapshot_js_object_id_(0) { | 191 max_snapshot_js_object_id_(0) { |
193 STATIC_ASSERT( | 192 STATIC_ASSERT( |
194 sizeof(HeapGraphEdge) == | 193 sizeof(HeapGraphEdge) == |
195 SnapshotSizeConstants<kPointerSize>::kExpectedHeapGraphEdgeSize); | 194 SnapshotSizeConstants<kPointerSize>::kExpectedHeapGraphEdgeSize); |
196 STATIC_ASSERT( | 195 STATIC_ASSERT( |
197 sizeof(HeapEntry) == | 196 sizeof(HeapEntry) == |
198 SnapshotSizeConstants<kPointerSize>::kExpectedHeapEntrySize); | 197 SnapshotSizeConstants<kPointerSize>::kExpectedHeapEntrySize); |
199 USE(SnapshotSizeConstants<4>::kExpectedHeapGraphEdgeSize); | 198 USE(SnapshotSizeConstants<4>::kExpectedHeapGraphEdgeSize); |
200 USE(SnapshotSizeConstants<4>::kExpectedHeapEntrySize); | 199 USE(SnapshotSizeConstants<4>::kExpectedHeapEntrySize); |
201 USE(SnapshotSizeConstants<8>::kExpectedHeapGraphEdgeSize); | 200 USE(SnapshotSizeConstants<8>::kExpectedHeapGraphEdgeSize); |
202 USE(SnapshotSizeConstants<8>::kExpectedHeapEntrySize); | 201 USE(SnapshotSizeConstants<8>::kExpectedHeapEntrySize); |
203 for (int i = 0; i < VisitorSynchronization::kNumberOfSyncTags; ++i) { | 202 for (int i = 0; i < VisitorSynchronization::kNumberOfSyncTags; ++i) { |
204 gc_subroot_indexes_[i] = HeapEntry::kNoEntry; | 203 gc_subroot_indexes_[i] = HeapEntry::kNoEntry; |
205 } | 204 } |
206 } | 205 } |
207 | 206 |
208 | 207 |
209 void HeapSnapshot::Delete() { | 208 void HeapSnapshot::Delete() { |
210 profiler_->RemoveSnapshot(this); | 209 profiler_->RemoveSnapshot(this); |
211 delete this; | 210 delete this; |
212 } | 211 } |
213 | 212 |
214 | 213 |
215 void HeapSnapshot::RememberLastJSObjectId() { | 214 void HeapSnapshot::RememberLastJSObjectId() { |
216 max_snapshot_js_object_id_ = profiler_->heap_object_map()->last_assigned_id(); | 215 max_snapshot_js_object_id_ = profiler_->heap_object_map()->last_assigned_id(); |
217 } | 216 } |
218 | 217 |
219 | 218 |
| 219 void HeapSnapshot::AddSyntheticRootEntries() { |
| 220 AddRootEntry(); |
| 221 AddGcRootsEntry(); |
| 222 SnapshotObjectId id = HeapObjectsMap::kGcRootsFirstSubrootId; |
| 223 for (int tag = 0; tag < VisitorSynchronization::kNumberOfSyncTags; tag++) { |
| 224 AddGcSubrootEntry(tag, id); |
| 225 id += HeapObjectsMap::kObjectIdStep; |
| 226 } |
| 227 DCHECK(HeapObjectsMap::kFirstAvailableObjectId == id); |
| 228 } |
| 229 |
| 230 |
220 HeapEntry* HeapSnapshot::AddRootEntry() { | 231 HeapEntry* HeapSnapshot::AddRootEntry() { |
221 DCHECK(root_index_ == HeapEntry::kNoEntry); | 232 DCHECK(root_index_ == HeapEntry::kNoEntry); |
222 DCHECK(entries_.is_empty()); // Root entry must be the first one. | 233 DCHECK(entries_.is_empty()); // Root entry must be the first one. |
223 HeapEntry* entry = AddEntry(HeapEntry::kSynthetic, | 234 HeapEntry* entry = AddEntry(HeapEntry::kSynthetic, |
224 "", | 235 "", |
225 HeapObjectsMap::kInternalRootObjectId, | 236 HeapObjectsMap::kInternalRootObjectId, |
226 0, | 237 0, |
227 0); | 238 0); |
228 root_index_ = entry->index(); | 239 root_index_ = entry->index(); |
229 DCHECK(root_index_ == 0); | 240 DCHECK(root_index_ == 0); |
230 return entry; | 241 return entry; |
231 } | 242 } |
232 | 243 |
233 | 244 |
234 HeapEntry* HeapSnapshot::AddGcRootsEntry() { | 245 HeapEntry* HeapSnapshot::AddGcRootsEntry() { |
235 DCHECK(gc_roots_index_ == HeapEntry::kNoEntry); | 246 DCHECK(gc_roots_index_ == HeapEntry::kNoEntry); |
236 HeapEntry* entry = AddEntry(HeapEntry::kSynthetic, | 247 HeapEntry* entry = AddEntry(HeapEntry::kSynthetic, |
237 "(GC roots)", | 248 "(GC roots)", |
238 HeapObjectsMap::kGcRootsObjectId, | 249 HeapObjectsMap::kGcRootsObjectId, |
239 0, | 250 0, |
240 0); | 251 0); |
241 gc_roots_index_ = entry->index(); | 252 gc_roots_index_ = entry->index(); |
242 return entry; | 253 return entry; |
243 } | 254 } |
244 | 255 |
245 | 256 |
246 HeapEntry* HeapSnapshot::AddGcSubrootEntry(int tag) { | 257 HeapEntry* HeapSnapshot::AddGcSubrootEntry(int tag, SnapshotObjectId id) { |
247 DCHECK(gc_subroot_indexes_[tag] == HeapEntry::kNoEntry); | 258 DCHECK(gc_subroot_indexes_[tag] == HeapEntry::kNoEntry); |
248 DCHECK(0 <= tag && tag < VisitorSynchronization::kNumberOfSyncTags); | 259 DCHECK(0 <= tag && tag < VisitorSynchronization::kNumberOfSyncTags); |
249 HeapEntry* entry = AddEntry( | 260 HeapEntry* entry = AddEntry(HeapEntry::kSynthetic, |
250 HeapEntry::kSynthetic, | 261 VisitorSynchronization::kTagNames[tag], id, 0, 0); |
251 VisitorSynchronization::kTagNames[tag], | |
252 HeapObjectsMap::GetNthGcSubrootId(tag), | |
253 0, | |
254 0); | |
255 gc_subroot_indexes_[tag] = entry->index(); | 262 gc_subroot_indexes_[tag] = entry->index(); |
256 return entry; | 263 return entry; |
257 } | 264 } |
258 | 265 |
259 | 266 |
260 HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type, | 267 HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type, |
261 const char* name, | 268 const char* name, |
262 SnapshotObjectId id, | 269 SnapshotObjectId id, |
263 size_t size, | 270 size_t size, |
264 unsigned trace_node_id) { | 271 unsigned trace_node_id) { |
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
764 | 771 |
765 void HeapObjectsSet::SetTag(Object* obj, const char* tag) { | 772 void HeapObjectsSet::SetTag(Object* obj, const char* tag) { |
766 if (!obj->IsHeapObject()) return; | 773 if (!obj->IsHeapObject()) return; |
767 HeapObject* object = HeapObject::cast(obj); | 774 HeapObject* object = HeapObject::cast(obj); |
768 HashMap::Entry* cache_entry = | 775 HashMap::Entry* cache_entry = |
769 entries_.Lookup(object, HeapEntriesMap::Hash(object), true); | 776 entries_.Lookup(object, HeapEntriesMap::Hash(object), true); |
770 cache_entry->value = const_cast<char*>(tag); | 777 cache_entry->value = const_cast<char*>(tag); |
771 } | 778 } |
772 | 779 |
773 | 780 |
774 HeapObject* const V8HeapExplorer::kInternalRootObject = | |
775 reinterpret_cast<HeapObject*>( | |
776 static_cast<intptr_t>(HeapObjectsMap::kInternalRootObjectId)); | |
777 HeapObject* const V8HeapExplorer::kGcRootsObject = | |
778 reinterpret_cast<HeapObject*>( | |
779 static_cast<intptr_t>(HeapObjectsMap::kGcRootsObjectId)); | |
780 HeapObject* const V8HeapExplorer::kFirstGcSubrootObject = | |
781 reinterpret_cast<HeapObject*>( | |
782 static_cast<intptr_t>(HeapObjectsMap::kGcRootsFirstSubrootId)); | |
783 HeapObject* const V8HeapExplorer::kLastGcSubrootObject = | |
784 reinterpret_cast<HeapObject*>( | |
785 static_cast<intptr_t>(HeapObjectsMap::kFirstAvailableObjectId)); | |
786 | |
787 | |
788 V8HeapExplorer::V8HeapExplorer( | 781 V8HeapExplorer::V8HeapExplorer( |
789 HeapSnapshot* snapshot, | 782 HeapSnapshot* snapshot, |
790 SnapshottingProgressReportingInterface* progress, | 783 SnapshottingProgressReportingInterface* progress, |
791 v8::HeapProfiler::ObjectNameResolver* resolver) | 784 v8::HeapProfiler::ObjectNameResolver* resolver) |
792 : heap_(snapshot->profiler()->heap_object_map()->heap()), | 785 : heap_(snapshot->profiler()->heap_object_map()->heap()), |
793 snapshot_(snapshot), | 786 snapshot_(snapshot), |
794 names_(snapshot_->profiler()->names()), | 787 names_(snapshot_->profiler()->names()), |
795 heap_object_map_(snapshot_->profiler()->heap_object_map()), | 788 heap_object_map_(snapshot_->profiler()->heap_object_map()), |
796 progress_(progress), | 789 progress_(progress), |
797 filler_(NULL), | 790 filler_(NULL), |
798 global_object_name_resolver_(resolver) { | 791 global_object_name_resolver_(resolver) { |
799 } | 792 } |
800 | 793 |
801 | 794 |
802 V8HeapExplorer::~V8HeapExplorer() { | 795 V8HeapExplorer::~V8HeapExplorer() { |
803 } | 796 } |
804 | 797 |
805 | 798 |
806 HeapEntry* V8HeapExplorer::AllocateEntry(HeapThing ptr) { | 799 HeapEntry* V8HeapExplorer::AllocateEntry(HeapThing ptr) { |
807 return AddEntry(reinterpret_cast<HeapObject*>(ptr)); | 800 return AddEntry(reinterpret_cast<HeapObject*>(ptr)); |
808 } | 801 } |
809 | 802 |
810 | 803 |
811 HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) { | 804 HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) { |
812 if (object == kInternalRootObject) { | 805 if (object->IsJSFunction()) { |
813 snapshot_->AddRootEntry(); | |
814 return snapshot_->root(); | |
815 } else if (object == kGcRootsObject) { | |
816 HeapEntry* entry = snapshot_->AddGcRootsEntry(); | |
817 return entry; | |
818 } else if (object >= kFirstGcSubrootObject && object < kLastGcSubrootObject) { | |
819 HeapEntry* entry = snapshot_->AddGcSubrootEntry(GetGcSubrootOrder(object)); | |
820 return entry; | |
821 } else if (object->IsJSFunction()) { | |
822 JSFunction* func = JSFunction::cast(object); | 806 JSFunction* func = JSFunction::cast(object); |
823 SharedFunctionInfo* shared = func->shared(); | 807 SharedFunctionInfo* shared = func->shared(); |
824 const char* name = shared->bound() ? "native_bind" : | 808 const char* name = shared->bound() ? "native_bind" : |
825 names_->GetName(String::cast(shared->name())); | 809 names_->GetName(String::cast(shared->name())); |
826 return AddEntry(object, HeapEntry::kClosure, name); | 810 return AddEntry(object, HeapEntry::kClosure, name); |
827 } else if (object->IsJSRegExp()) { | 811 } else if (object->IsJSRegExp()) { |
828 JSRegExp* re = JSRegExp::cast(object); | 812 JSRegExp* re = JSRegExp::cast(object); |
829 return AddEntry(object, | 813 return AddEntry(object, |
830 HeapEntry::kRegExp, | 814 HeapEntry::kRegExp, |
831 names_->GetName(re->Pattern())); | 815 names_->GetName(re->Pattern())); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
958 child_entry); | 942 child_entry); |
959 } | 943 } |
960 | 944 |
961 private: | 945 private: |
962 HeapSnapshot* snapshot_; | 946 HeapSnapshot* snapshot_; |
963 StringsStorage* names_; | 947 StringsStorage* names_; |
964 HeapEntriesMap* entries_; | 948 HeapEntriesMap* entries_; |
965 }; | 949 }; |
966 | 950 |
967 | 951 |
968 class GcSubrootsEnumerator : public ObjectVisitor { | |
969 public: | |
970 GcSubrootsEnumerator( | |
971 SnapshotFiller* filler, V8HeapExplorer* explorer) | |
972 : filler_(filler), | |
973 explorer_(explorer), | |
974 previous_object_count_(0), | |
975 object_count_(0) { | |
976 } | |
977 void VisitPointers(Object** start, Object** end) { | |
978 object_count_ += end - start; | |
979 } | |
980 void Synchronize(VisitorSynchronization::SyncTag tag) { | |
981 // Skip empty subroots. | |
982 if (previous_object_count_ != object_count_) { | |
983 previous_object_count_ = object_count_; | |
984 filler_->AddEntry(V8HeapExplorer::GetNthGcSubrootObject(tag), explorer_); | |
985 } | |
986 } | |
987 private: | |
988 SnapshotFiller* filler_; | |
989 V8HeapExplorer* explorer_; | |
990 intptr_t previous_object_count_; | |
991 intptr_t object_count_; | |
992 }; | |
993 | |
994 | |
995 void V8HeapExplorer::AddRootEntries(SnapshotFiller* filler) { | |
996 filler->AddEntry(kInternalRootObject, this); | |
997 filler->AddEntry(kGcRootsObject, this); | |
998 GcSubrootsEnumerator enumerator(filler, this); | |
999 heap_->IterateRoots(&enumerator, VISIT_ALL); | |
1000 } | |
1001 | |
1002 | |
1003 const char* V8HeapExplorer::GetSystemEntryName(HeapObject* object) { | 952 const char* V8HeapExplorer::GetSystemEntryName(HeapObject* object) { |
1004 switch (object->map()->instance_type()) { | 953 switch (object->map()->instance_type()) { |
1005 case MAP_TYPE: | 954 case MAP_TYPE: |
1006 switch (Map::cast(object)->instance_type()) { | 955 switch (Map::cast(object)->instance_type()) { |
1007 #define MAKE_STRING_MAP_CASE(instance_type, size, name, Name) \ | 956 #define MAKE_STRING_MAP_CASE(instance_type, size, name, Name) \ |
1008 case instance_type: return "system / Map (" #Name ")"; | 957 case instance_type: return "system / Map (" #Name ")"; |
1009 STRING_TYPE_LIST(MAKE_STRING_MAP_CASE) | 958 STRING_TYPE_LIST(MAKE_STRING_MAP_CASE) |
1010 #undef MAKE_STRING_MAP_CASE | 959 #undef MAKE_STRING_MAP_CASE |
1011 default: return "system / Map"; | 960 default: return "system / Map"; |
1012 } | 961 } |
(...skipping 835 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1848 } else { | 1797 } else { |
1849 for (Object** p = start; p < end; p++) strong_references_.Add(*p); | 1798 for (Object** p = start; p < end; p++) strong_references_.Add(*p); |
1850 } | 1799 } |
1851 } | 1800 } |
1852 | 1801 |
1853 void SetCollectingAllReferences() { collecting_all_references_ = true; } | 1802 void SetCollectingAllReferences() { collecting_all_references_ = true; } |
1854 | 1803 |
1855 void FillReferences(V8HeapExplorer* explorer) { | 1804 void FillReferences(V8HeapExplorer* explorer) { |
1856 DCHECK(strong_references_.length() <= all_references_.length()); | 1805 DCHECK(strong_references_.length() <= all_references_.length()); |
1857 Builtins* builtins = heap_->isolate()->builtins(); | 1806 Builtins* builtins = heap_->isolate()->builtins(); |
1858 for (int i = 0; i < reference_tags_.length(); ++i) { | |
1859 explorer->SetGcRootsReference(reference_tags_[i].tag); | |
1860 } | |
1861 int strong_index = 0, all_index = 0, tags_index = 0, builtin_index = 0; | 1807 int strong_index = 0, all_index = 0, tags_index = 0, builtin_index = 0; |
1862 while (all_index < all_references_.length()) { | 1808 while (all_index < all_references_.length()) { |
1863 bool is_strong = strong_index < strong_references_.length() | 1809 bool is_strong = strong_index < strong_references_.length() |
1864 && strong_references_[strong_index] == all_references_[all_index]; | 1810 && strong_references_[strong_index] == all_references_[all_index]; |
1865 explorer->SetGcSubrootReference(reference_tags_[tags_index].tag, | 1811 explorer->SetGcSubrootReference(reference_tags_[tags_index].tag, |
1866 !is_strong, | 1812 !is_strong, |
1867 all_references_[all_index]); | 1813 all_references_[all_index]); |
1868 if (reference_tags_[tags_index].tag == | 1814 if (reference_tags_[tags_index].tag == |
1869 VisitorSynchronization::kBuiltins) { | 1815 VisitorSynchronization::kBuiltins) { |
1870 DCHECK(all_references_[all_index]->IsCode()); | 1816 DCHECK(all_references_[all_index]->IsCode()); |
(...skipping 22 matching lines...) Expand all Loading... |
1893 int previous_reference_count_; | 1839 int previous_reference_count_; |
1894 List<IndexTag> reference_tags_; | 1840 List<IndexTag> reference_tags_; |
1895 Heap* heap_; | 1841 Heap* heap_; |
1896 }; | 1842 }; |
1897 | 1843 |
1898 | 1844 |
1899 bool V8HeapExplorer::IterateAndExtractReferences( | 1845 bool V8HeapExplorer::IterateAndExtractReferences( |
1900 SnapshotFiller* filler) { | 1846 SnapshotFiller* filler) { |
1901 filler_ = filler; | 1847 filler_ = filler; |
1902 | 1848 |
| 1849 // Create references to the synthetic roots. |
| 1850 SetRootGcRootsReference(); |
| 1851 for (int tag = 0; tag < VisitorSynchronization::kNumberOfSyncTags; tag++) { |
| 1852 SetGcRootsReference(static_cast<VisitorSynchronization::SyncTag>(tag)); |
| 1853 } |
| 1854 |
1903 // Make sure builtin code objects get their builtin tags | 1855 // Make sure builtin code objects get their builtin tags |
1904 // first. Otherwise a particular JSFunction object could set | 1856 // first. Otherwise a particular JSFunction object could set |
1905 // its custom name to a generic builtin. | 1857 // its custom name to a generic builtin. |
1906 SetRootGcRootsReference(); | |
1907 RootsReferencesExtractor extractor(heap_); | 1858 RootsReferencesExtractor extractor(heap_); |
1908 heap_->IterateRoots(&extractor, VISIT_ONLY_STRONG); | 1859 heap_->IterateRoots(&extractor, VISIT_ONLY_STRONG); |
1909 extractor.SetCollectingAllReferences(); | 1860 extractor.SetCollectingAllReferences(); |
1910 heap_->IterateRoots(&extractor, VISIT_ALL); | 1861 heap_->IterateRoots(&extractor, VISIT_ALL); |
1911 extractor.FillReferences(this); | 1862 extractor.FillReferences(this); |
1912 | 1863 |
1913 // We have to do two passes as sometimes FixedArrays are used | 1864 // We have to do two passes as sometimes FixedArrays are used |
1914 // to weakly hold their items, and it's impossible to distinguish | 1865 // to weakly hold their items, and it's impossible to distinguish |
1915 // between these cases without processing the array owner first. | 1866 // between these cases without processing the array owner first. |
1916 bool interrupted = | 1867 bool interrupted = |
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2612 Heap* debug_heap = heap_; | 2563 Heap* debug_heap = heap_; |
2613 debug_heap->Verify(); | 2564 debug_heap->Verify(); |
2614 #endif | 2565 #endif |
2615 | 2566 |
2616 SetProgressTotal(2); // 2 passes. | 2567 SetProgressTotal(2); // 2 passes. |
2617 | 2568 |
2618 #ifdef VERIFY_HEAP | 2569 #ifdef VERIFY_HEAP |
2619 debug_heap->Verify(); | 2570 debug_heap->Verify(); |
2620 #endif | 2571 #endif |
2621 | 2572 |
| 2573 snapshot_->AddSyntheticRootEntries(); |
| 2574 |
2622 if (!FillReferences()) return false; | 2575 if (!FillReferences()) return false; |
2623 | 2576 |
2624 snapshot_->FillChildren(); | 2577 snapshot_->FillChildren(); |
2625 snapshot_->RememberLastJSObjectId(); | 2578 snapshot_->RememberLastJSObjectId(); |
2626 | 2579 |
2627 progress_counter_ = progress_total_; | 2580 progress_counter_ = progress_total_; |
2628 if (!ProgressReport(true)) return false; | 2581 if (!ProgressReport(true)) return false; |
2629 return true; | 2582 return true; |
2630 } | 2583 } |
2631 | 2584 |
(...skipping 20 matching lines...) Expand all Loading... |
2652 HeapIterator iterator(heap_, HeapIterator::kFilterUnreachable); | 2605 HeapIterator iterator(heap_, HeapIterator::kFilterUnreachable); |
2653 progress_total_ = iterations_count * ( | 2606 progress_total_ = iterations_count * ( |
2654 v8_heap_explorer_.EstimateObjectsCount(&iterator) + | 2607 v8_heap_explorer_.EstimateObjectsCount(&iterator) + |
2655 dom_explorer_.EstimateObjectsCount()); | 2608 dom_explorer_.EstimateObjectsCount()); |
2656 progress_counter_ = 0; | 2609 progress_counter_ = 0; |
2657 } | 2610 } |
2658 | 2611 |
2659 | 2612 |
2660 bool HeapSnapshotGenerator::FillReferences() { | 2613 bool HeapSnapshotGenerator::FillReferences() { |
2661 SnapshotFiller filler(snapshot_, &entries_); | 2614 SnapshotFiller filler(snapshot_, &entries_); |
2662 v8_heap_explorer_.AddRootEntries(&filler); | |
2663 return v8_heap_explorer_.IterateAndExtractReferences(&filler) | 2615 return v8_heap_explorer_.IterateAndExtractReferences(&filler) |
2664 && dom_explorer_.IterateAndExtractReferences(&filler); | 2616 && dom_explorer_.IterateAndExtractReferences(&filler); |
2665 } | 2617 } |
2666 | 2618 |
2667 | 2619 |
2668 template<int bytes> struct MaxDecimalDigitsIn; | 2620 template<int bytes> struct MaxDecimalDigitsIn; |
2669 template<> struct MaxDecimalDigitsIn<4> { | 2621 template<> struct MaxDecimalDigitsIn<4> { |
2670 static const int kSigned = 11; | 2622 static const int kSigned = 11; |
2671 static const int kUnsigned = 10; | 2623 static const int kUnsigned = 10; |
2672 }; | 2624 }; |
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3185 writer_->AddString("\"<dummy>\""); | 3137 writer_->AddString("\"<dummy>\""); |
3186 for (int i = 1; i < sorted_strings.length(); ++i) { | 3138 for (int i = 1; i < sorted_strings.length(); ++i) { |
3187 writer_->AddCharacter(','); | 3139 writer_->AddCharacter(','); |
3188 SerializeString(sorted_strings[i]); | 3140 SerializeString(sorted_strings[i]); |
3189 if (writer_->aborted()) return; | 3141 if (writer_->aborted()) return; |
3190 } | 3142 } |
3191 } | 3143 } |
3192 | 3144 |
3193 | 3145 |
3194 } } // namespace v8::internal | 3146 } } // namespace v8::internal |
OLD | NEW |