| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 3282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3293 | 3293 |
| 3294 // Copy the characters into the new object. | 3294 // Copy the characters into the new object. |
| 3295 SeqAsciiString* string_result = SeqAsciiString::cast(result); | 3295 SeqAsciiString* string_result = SeqAsciiString::cast(result); |
| 3296 for (int i = 0; i < string.length(); i++) { | 3296 for (int i = 0; i < string.length(); i++) { |
| 3297 string_result->SeqAsciiStringSet(i, string[i]); | 3297 string_result->SeqAsciiStringSet(i, string[i]); |
| 3298 } | 3298 } |
| 3299 return result; | 3299 return result; |
| 3300 } | 3300 } |
| 3301 | 3301 |
| 3302 | 3302 |
| 3303 MaybeObject* Heap::AllocateStringFromUtf8(Vector<const char> string, | 3303 MaybeObject* Heap::AllocateStringFromUtf8Slow(Vector<const char> string, |
| 3304 PretenureFlag pretenure) { | 3304 PretenureFlag pretenure) { |
| 3305 // V8 only supports characters in the Basic Multilingual Plane. | 3305 // V8 only supports characters in the Basic Multilingual Plane. |
| 3306 const uc32 kMaxSupportedChar = 0xFFFF; | 3306 const uc32 kMaxSupportedChar = 0xFFFF; |
| 3307 // Count the number of characters in the UTF-8 string and check if | 3307 // Count the number of characters in the UTF-8 string and check if |
| 3308 // it is an ASCII string. | 3308 // it is an ASCII string. |
| 3309 Access<ScannerConstants::Utf8Decoder> | 3309 Access<ScannerConstants::Utf8Decoder> |
| 3310 decoder(isolate_->scanner_constants()->utf8_decoder()); | 3310 decoder(isolate_->scanner_constants()->utf8_decoder()); |
| 3311 decoder->Reset(string.start(), string.length()); | 3311 decoder->Reset(string.start(), string.length()); |
| 3312 int chars = 0; | 3312 int chars = 0; |
| 3313 bool is_ascii = true; | |
| 3314 while (decoder->has_more()) { | 3313 while (decoder->has_more()) { |
| 3315 uc32 r = decoder->GetNext(); | 3314 decoder->GetNext(); |
| 3316 if (r > String::kMaxAsciiCharCode) is_ascii = false; | |
| 3317 chars++; | 3315 chars++; |
| 3318 } | 3316 } |
| 3319 | 3317 |
| 3320 // If the string is ascii, we do not need to convert the characters | |
| 3321 // since UTF8 is backwards compatible with ascii. | |
| 3322 if (is_ascii) return AllocateStringFromAscii(string, pretenure); | |
| 3323 | |
| 3324 Object* result; | 3318 Object* result; |
| 3325 { MaybeObject* maybe_result = AllocateRawTwoByteString(chars, pretenure); | 3319 { MaybeObject* maybe_result = AllocateRawTwoByteString(chars, pretenure); |
| 3326 if (!maybe_result->ToObject(&result)) return maybe_result; | 3320 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3327 } | 3321 } |
| 3328 | 3322 |
| 3329 // Convert and copy the characters into the new object. | 3323 // Convert and copy the characters into the new object. |
| 3330 String* string_result = String::cast(result); | 3324 String* string_result = String::cast(result); |
| 3331 decoder->Reset(string.start(), string.length()); | 3325 decoder->Reset(string.start(), string.length()); |
| 3332 for (int i = 0; i < chars; i++) { | 3326 for (int i = 0; i < chars; i++) { |
| 3333 uc32 r = decoder->GetNext(); | 3327 uc32 r = decoder->GetNext(); |
| (...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3763 } | 3757 } |
| 3764 Struct::cast(result)->InitializeBody(size); | 3758 Struct::cast(result)->InitializeBody(size); |
| 3765 return result; | 3759 return result; |
| 3766 } | 3760 } |
| 3767 | 3761 |
| 3768 | 3762 |
| 3769 bool Heap::IdleNotification() { | 3763 bool Heap::IdleNotification() { |
| 3770 static const int kIdlesBeforeScavenge = 4; | 3764 static const int kIdlesBeforeScavenge = 4; |
| 3771 static const int kIdlesBeforeMarkSweep = 7; | 3765 static const int kIdlesBeforeMarkSweep = 7; |
| 3772 static const int kIdlesBeforeMarkCompact = 8; | 3766 static const int kIdlesBeforeMarkCompact = 8; |
| 3767 static const int kMaxIdleCount = kIdlesBeforeMarkCompact + 1; |
| 3768 static const int kGCsBetweenCleanup = 4; |
| 3769 |
| 3773 if (!last_idle_notification_gc_count_init_) { | 3770 if (!last_idle_notification_gc_count_init_) { |
| 3774 last_idle_notification_gc_count_ = gc_count_; | 3771 last_idle_notification_gc_count_ = gc_count_; |
| 3775 last_idle_notification_gc_count_init_ = true; | 3772 last_idle_notification_gc_count_init_ = true; |
| 3776 } | 3773 } |
| 3777 | 3774 |
| 3778 bool uncommit = true; | 3775 bool uncommit = true; |
| 3779 bool finished = false; | 3776 bool finished = false; |
| 3780 | 3777 |
| 3781 if (last_idle_notification_gc_count_ == gc_count_) { | 3778 // Reset the number of idle notifications received when a number of |
| 3782 number_idle_notifications_++; | 3779 // GCs have taken place. This allows another round of cleanup based |
| 3780 // on idle notifications if enough work has been carried out to |
| 3781 // provoke a number of garbage collections. |
| 3782 if (gc_count_ < last_idle_notification_gc_count_ + kGCsBetweenCleanup) { |
| 3783 number_idle_notifications_ = |
| 3784 Min(number_idle_notifications_ + 1, kMaxIdleCount); |
| 3783 } else { | 3785 } else { |
| 3784 number_idle_notifications_ = 0; | 3786 number_idle_notifications_ = 0; |
| 3785 last_idle_notification_gc_count_ = gc_count_; | 3787 last_idle_notification_gc_count_ = gc_count_; |
| 3786 } | 3788 } |
| 3787 | 3789 |
| 3788 if (number_idle_notifications_ == kIdlesBeforeScavenge) { | 3790 if (number_idle_notifications_ == kIdlesBeforeScavenge) { |
| 3789 if (contexts_disposed_ > 0) { | 3791 if (contexts_disposed_ > 0) { |
| 3790 HistogramTimerScope scope(isolate_->counters()->gc_context()); | 3792 HistogramTimerScope scope(isolate_->counters()->gc_context()); |
| 3791 CollectAllGarbage(false); | 3793 CollectAllGarbage(false); |
| 3792 } else { | 3794 } else { |
| 3793 CollectGarbage(NEW_SPACE); | 3795 CollectGarbage(NEW_SPACE); |
| 3794 } | 3796 } |
| 3795 new_space_.Shrink(); | 3797 new_space_.Shrink(); |
| 3796 last_idle_notification_gc_count_ = gc_count_; | 3798 last_idle_notification_gc_count_ = gc_count_; |
| 3797 | |
| 3798 } else if (number_idle_notifications_ == kIdlesBeforeMarkSweep) { | 3799 } else if (number_idle_notifications_ == kIdlesBeforeMarkSweep) { |
| 3799 // Before doing the mark-sweep collections we clear the | 3800 // Before doing the mark-sweep collections we clear the |
| 3800 // compilation cache to avoid hanging on to source code and | 3801 // compilation cache to avoid hanging on to source code and |
| 3801 // generated code for cached functions. | 3802 // generated code for cached functions. |
| 3802 isolate_->compilation_cache()->Clear(); | 3803 isolate_->compilation_cache()->Clear(); |
| 3803 | 3804 |
| 3804 CollectAllGarbage(false); | 3805 CollectAllGarbage(false); |
| 3805 new_space_.Shrink(); | 3806 new_space_.Shrink(); |
| 3806 last_idle_notification_gc_count_ = gc_count_; | 3807 last_idle_notification_gc_count_ = gc_count_; |
| 3807 | 3808 |
| 3808 } else if (number_idle_notifications_ == kIdlesBeforeMarkCompact) { | 3809 } else if (number_idle_notifications_ == kIdlesBeforeMarkCompact) { |
| 3809 CollectAllGarbage(true); | 3810 CollectAllGarbage(true); |
| 3810 new_space_.Shrink(); | 3811 new_space_.Shrink(); |
| 3811 last_idle_notification_gc_count_ = gc_count_; | 3812 last_idle_notification_gc_count_ = gc_count_; |
| 3812 number_idle_notifications_ = 0; | 3813 number_idle_notifications_ = 0; |
| 3813 finished = true; | 3814 finished = true; |
| 3814 | |
| 3815 } else if (contexts_disposed_ > 0) { | 3815 } else if (contexts_disposed_ > 0) { |
| 3816 if (FLAG_expose_gc) { | 3816 if (FLAG_expose_gc) { |
| 3817 contexts_disposed_ = 0; | 3817 contexts_disposed_ = 0; |
| 3818 } else { | 3818 } else { |
| 3819 HistogramTimerScope scope(isolate_->counters()->gc_context()); | 3819 HistogramTimerScope scope(isolate_->counters()->gc_context()); |
| 3820 CollectAllGarbage(false); | 3820 CollectAllGarbage(false); |
| 3821 last_idle_notification_gc_count_ = gc_count_; | 3821 last_idle_notification_gc_count_ = gc_count_; |
| 3822 } | 3822 } |
| 3823 // If this is the first idle notification, we reset the | 3823 // If this is the first idle notification, we reset the |
| 3824 // notification count to avoid letting idle notifications for | 3824 // notification count to avoid letting idle notifications for |
| 3825 // context disposal garbage collections start a potentially too | 3825 // context disposal garbage collections start a potentially too |
| 3826 // aggressive idle GC cycle. | 3826 // aggressive idle GC cycle. |
| 3827 if (number_idle_notifications_ <= 1) { | 3827 if (number_idle_notifications_ <= 1) { |
| 3828 number_idle_notifications_ = 0; | 3828 number_idle_notifications_ = 0; |
| 3829 uncommit = false; | 3829 uncommit = false; |
| 3830 } | 3830 } |
| 3831 } else if (number_idle_notifications_ > kIdlesBeforeMarkCompact) { |
| 3832 // If we have received more than kIdlesBeforeMarkCompact idle |
| 3833 // notifications we do not perform any cleanup because we don't |
| 3834 // expect to gain much by doing so. |
| 3835 finished = true; |
| 3831 } | 3836 } |
| 3832 | 3837 |
| 3833 // Make sure that we have no pending context disposals and | 3838 // Make sure that we have no pending context disposals and |
| 3834 // conditionally uncommit from space. | 3839 // conditionally uncommit from space. |
| 3835 ASSERT(contexts_disposed_ == 0); | 3840 ASSERT(contexts_disposed_ == 0); |
| 3836 if (uncommit) UncommitFromSpace(); | 3841 if (uncommit) UncommitFromSpace(); |
| 3837 return finished; | 3842 return finished; |
| 3838 } | 3843 } |
| 3839 | 3844 |
| 3840 | 3845 |
| (...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4488 *stats->cell_space_capacity = cell_space_->Capacity(); | 4493 *stats->cell_space_capacity = cell_space_->Capacity(); |
| 4489 *stats->lo_space_size = lo_space_->Size(); | 4494 *stats->lo_space_size = lo_space_->Size(); |
| 4490 isolate_->global_handles()->RecordStats(stats); | 4495 isolate_->global_handles()->RecordStats(stats); |
| 4491 *stats->memory_allocator_size = isolate()->memory_allocator()->Size(); | 4496 *stats->memory_allocator_size = isolate()->memory_allocator()->Size(); |
| 4492 *stats->memory_allocator_capacity = | 4497 *stats->memory_allocator_capacity = |
| 4493 isolate()->memory_allocator()->Size() + | 4498 isolate()->memory_allocator()->Size() + |
| 4494 isolate()->memory_allocator()->Available(); | 4499 isolate()->memory_allocator()->Available(); |
| 4495 *stats->os_error = OS::GetLastError(); | 4500 *stats->os_error = OS::GetLastError(); |
| 4496 isolate()->memory_allocator()->Available(); | 4501 isolate()->memory_allocator()->Available(); |
| 4497 if (take_snapshot) { | 4502 if (take_snapshot) { |
| 4498 HeapIterator iterator(HeapIterator::kPreciseFiltering); | 4503 HeapIterator iterator(HeapIterator::kFilterFreeListNodes); |
| 4499 for (HeapObject* obj = iterator.next(); | 4504 for (HeapObject* obj = iterator.next(); |
| 4500 obj != NULL; | 4505 obj != NULL; |
| 4501 obj = iterator.next()) { | 4506 obj = iterator.next()) { |
| 4502 InstanceType type = obj->map()->instance_type(); | 4507 InstanceType type = obj->map()->instance_type(); |
| 4503 ASSERT(0 <= type && type <= LAST_TYPE); | 4508 ASSERT(0 <= type && type <= LAST_TYPE); |
| 4504 stats->objects_per_type[type]++; | 4509 stats->objects_per_type[type]++; |
| 4505 stats->size_per_type[type] += obj->Size(); | 4510 stats->size_per_type[type] += obj->Size(); |
| 4506 } | 4511 } |
| 4507 } | 4512 } |
| 4508 } | 4513 } |
| (...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5112 iterator_ = new LargeObjectIterator(HEAP->lo_space(), size_func_); | 5117 iterator_ = new LargeObjectIterator(HEAP->lo_space(), size_func_); |
| 5113 break; | 5118 break; |
| 5114 } | 5119 } |
| 5115 | 5120 |
| 5116 // Return the newly allocated iterator; | 5121 // Return the newly allocated iterator; |
| 5117 ASSERT(iterator_ != NULL); | 5122 ASSERT(iterator_ != NULL); |
| 5118 return iterator_; | 5123 return iterator_; |
| 5119 } | 5124 } |
| 5120 | 5125 |
| 5121 | 5126 |
| 5122 class FreeListNodesFilter { | 5127 class HeapObjectsFilter { |
| 5128 public: |
| 5129 virtual ~HeapObjectsFilter() {} |
| 5130 virtual bool SkipObject(HeapObject* object) = 0; |
| 5131 }; |
| 5132 |
| 5133 |
| 5134 class FreeListNodesFilter : public HeapObjectsFilter { |
| 5123 public: | 5135 public: |
| 5124 FreeListNodesFilter() { | 5136 FreeListNodesFilter() { |
| 5125 MarkFreeListNodes(); | 5137 MarkFreeListNodes(); |
| 5126 } | 5138 } |
| 5127 | 5139 |
| 5128 inline bool IsFreeListNode(HeapObject* object) { | 5140 bool SkipObject(HeapObject* object) { |
| 5129 if (object->IsMarked()) { | 5141 if (object->IsMarked()) { |
| 5130 object->ClearMark(); | 5142 object->ClearMark(); |
| 5131 return true; | 5143 return true; |
| 5132 } else { | 5144 } else { |
| 5133 return false; | 5145 return false; |
| 5134 } | 5146 } |
| 5135 } | 5147 } |
| 5136 | 5148 |
| 5137 private: | 5149 private: |
| 5138 void MarkFreeListNodes() { | 5150 void MarkFreeListNodes() { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 5151 obj != NULL; | 5163 obj != NULL; |
| 5152 obj = iter.next_object()) { | 5164 obj = iter.next_object()) { |
| 5153 if (FreeListNode::IsFreeListNode(obj)) obj->SetMark(); | 5165 if (FreeListNode::IsFreeListNode(obj)) obj->SetMark(); |
| 5154 } | 5166 } |
| 5155 } | 5167 } |
| 5156 | 5168 |
| 5157 AssertNoAllocation no_alloc; | 5169 AssertNoAllocation no_alloc; |
| 5158 }; | 5170 }; |
| 5159 | 5171 |
| 5160 | 5172 |
| 5173 class UnreachableObjectsFilter : public HeapObjectsFilter { |
| 5174 public: |
| 5175 UnreachableObjectsFilter() { |
| 5176 MarkUnreachableObjects(); |
| 5177 } |
| 5178 |
| 5179 bool SkipObject(HeapObject* object) { |
| 5180 if (object->IsMarked()) { |
| 5181 object->ClearMark(); |
| 5182 return true; |
| 5183 } else { |
| 5184 return false; |
| 5185 } |
| 5186 } |
| 5187 |
| 5188 private: |
| 5189 class UnmarkingVisitor : public ObjectVisitor { |
| 5190 public: |
| 5191 UnmarkingVisitor() : list_(10) {} |
| 5192 |
| 5193 void VisitPointers(Object** start, Object** end) { |
| 5194 for (Object** p = start; p < end; p++) { |
| 5195 if (!(*p)->IsHeapObject()) continue; |
| 5196 HeapObject* obj = HeapObject::cast(*p); |
| 5197 if (obj->IsMarked()) { |
| 5198 obj->ClearMark(); |
| 5199 list_.Add(obj); |
| 5200 } |
| 5201 } |
| 5202 } |
| 5203 |
| 5204 bool can_process() { return !list_.is_empty(); } |
| 5205 |
| 5206 void ProcessNext() { |
| 5207 HeapObject* obj = list_.RemoveLast(); |
| 5208 obj->Iterate(this); |
| 5209 } |
| 5210 |
| 5211 private: |
| 5212 List<HeapObject*> list_; |
| 5213 }; |
| 5214 |
| 5215 void MarkUnreachableObjects() { |
| 5216 HeapIterator iterator; |
| 5217 for (HeapObject* obj = iterator.next(); |
| 5218 obj != NULL; |
| 5219 obj = iterator.next()) { |
| 5220 obj->SetMark(); |
| 5221 } |
| 5222 UnmarkingVisitor visitor; |
| 5223 HEAP->IterateRoots(&visitor, VISIT_ONLY_STRONG); |
| 5224 while (visitor.can_process()) |
| 5225 visitor.ProcessNext(); |
| 5226 } |
| 5227 |
| 5228 AssertNoAllocation no_alloc; |
| 5229 }; |
| 5230 |
| 5231 |
| 5161 HeapIterator::HeapIterator() | 5232 HeapIterator::HeapIterator() |
| 5162 : filtering_(HeapIterator::kNoFiltering), | 5233 : filtering_(HeapIterator::kNoFiltering), |
| 5163 filter_(NULL) { | 5234 filter_(NULL) { |
| 5164 Init(); | 5235 Init(); |
| 5165 } | 5236 } |
| 5166 | 5237 |
| 5167 | 5238 |
| 5168 HeapIterator::HeapIterator(HeapIterator::FreeListNodesFiltering filtering) | 5239 HeapIterator::HeapIterator(HeapIterator::HeapObjectsFiltering filtering) |
| 5169 : filtering_(filtering), | 5240 : filtering_(filtering), |
| 5170 filter_(NULL) { | 5241 filter_(NULL) { |
| 5171 Init(); | 5242 Init(); |
| 5172 } | 5243 } |
| 5173 | 5244 |
| 5174 | 5245 |
| 5175 HeapIterator::~HeapIterator() { | 5246 HeapIterator::~HeapIterator() { |
| 5176 Shutdown(); | 5247 Shutdown(); |
| 5177 } | 5248 } |
| 5178 | 5249 |
| 5179 | 5250 |
| 5180 void HeapIterator::Init() { | 5251 void HeapIterator::Init() { |
| 5181 // Start the iteration. | 5252 // Start the iteration. |
| 5182 if (filtering_ == kPreciseFiltering) { | 5253 space_iterator_ = filtering_ == kNoFiltering ? new SpaceIterator : |
| 5183 filter_ = new FreeListNodesFilter; | 5254 new SpaceIterator(MarkCompactCollector::SizeOfMarkedObject); |
| 5184 space_iterator_ = | 5255 switch (filtering_) { |
| 5185 new SpaceIterator(MarkCompactCollector::SizeOfMarkedObject); | 5256 case kFilterFreeListNodes: |
| 5186 } else { | 5257 filter_ = new FreeListNodesFilter; |
| 5187 space_iterator_ = new SpaceIterator; | 5258 break; |
| 5259 case kFilterUnreachable: |
| 5260 filter_ = new UnreachableObjectsFilter; |
| 5261 break; |
| 5262 default: |
| 5263 break; |
| 5188 } | 5264 } |
| 5189 object_iterator_ = space_iterator_->next(); | 5265 object_iterator_ = space_iterator_->next(); |
| 5190 } | 5266 } |
| 5191 | 5267 |
| 5192 | 5268 |
| 5193 void HeapIterator::Shutdown() { | 5269 void HeapIterator::Shutdown() { |
| 5194 #ifdef DEBUG | 5270 #ifdef DEBUG |
| 5195 // Assert that in precise mode we have iterated through all | 5271 // Assert that in filtering mode we have iterated through all |
| 5196 // objects. Otherwise, heap will be left in an inconsistent state. | 5272 // objects. Otherwise, heap will be left in an inconsistent state. |
| 5197 if (filtering_ == kPreciseFiltering) { | 5273 if (filtering_ != kNoFiltering) { |
| 5198 ASSERT(object_iterator_ == NULL); | 5274 ASSERT(object_iterator_ == NULL); |
| 5199 } | 5275 } |
| 5200 #endif | 5276 #endif |
| 5201 // Make sure the last iterator is deallocated. | 5277 // Make sure the last iterator is deallocated. |
| 5202 delete space_iterator_; | 5278 delete space_iterator_; |
| 5203 space_iterator_ = NULL; | 5279 space_iterator_ = NULL; |
| 5204 object_iterator_ = NULL; | 5280 object_iterator_ = NULL; |
| 5205 delete filter_; | 5281 delete filter_; |
| 5206 filter_ = NULL; | 5282 filter_ = NULL; |
| 5207 } | 5283 } |
| 5208 | 5284 |
| 5209 | 5285 |
| 5210 HeapObject* HeapIterator::next() { | 5286 HeapObject* HeapIterator::next() { |
| 5211 if (filter_ == NULL) return NextObject(); | 5287 if (filter_ == NULL) return NextObject(); |
| 5212 | 5288 |
| 5213 HeapObject* obj = NextObject(); | 5289 HeapObject* obj = NextObject(); |
| 5214 while (obj != NULL && filter_->IsFreeListNode(obj)) obj = NextObject(); | 5290 while (obj != NULL && filter_->SkipObject(obj)) obj = NextObject(); |
| 5215 return obj; | 5291 return obj; |
| 5216 } | 5292 } |
| 5217 | 5293 |
| 5218 | 5294 |
| 5219 HeapObject* HeapIterator::NextObject() { | 5295 HeapObject* HeapIterator::NextObject() { |
| 5220 // No iterator means we are done. | 5296 // No iterator means we are done. |
| 5221 if (object_iterator_ == NULL) return NULL; | 5297 if (object_iterator_ == NULL) return NULL; |
| 5222 | 5298 |
| 5223 if (HeapObject* obj = object_iterator_->next_object()) { | 5299 if (HeapObject* obj = object_iterator_->next_object()) { |
| 5224 // If the current iterator has more objects we are fine. | 5300 // If the current iterator has more objects we are fine. |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5499 } | 5575 } |
| 5500 | 5576 |
| 5501 | 5577 |
| 5502 void ExternalStringTable::TearDown() { | 5578 void ExternalStringTable::TearDown() { |
| 5503 new_space_strings_.Free(); | 5579 new_space_strings_.Free(); |
| 5504 old_space_strings_.Free(); | 5580 old_space_strings_.Free(); |
| 5505 } | 5581 } |
| 5506 | 5582 |
| 5507 | 5583 |
| 5508 } } // namespace v8::internal | 5584 } } // namespace v8::internal |
| OLD | NEW |