| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 size_func_ = size_f; | 75 size_func_ = size_f; |
| 76 Page* p = Page::FromAllocationTop(cur_addr_); | 76 Page* p = Page::FromAllocationTop(cur_addr_); |
| 77 cur_limit_ = (p == end_page_) ? end_addr_ : p->AllocationTop(); | 77 cur_limit_ = (p == end_page_) ? end_addr_ : p->AllocationTop(); |
| 78 | 78 |
| 79 #ifdef DEBUG | 79 #ifdef DEBUG |
| 80 Verify(); | 80 Verify(); |
| 81 #endif | 81 #endif |
| 82 } | 82 } |
| 83 | 83 |
| 84 | 84 |
| 85 bool HeapObjectIterator::HasNextInNextPage() { | 85 HeapObject* HeapObjectIterator::FromNextPage() { |
| 86 if (cur_addr_ == end_addr_) return false; | 86 if (cur_addr_ == end_addr_) return NULL; |
| 87 | 87 |
| 88 Page* cur_page = Page::FromAllocationTop(cur_addr_); | 88 Page* cur_page = Page::FromAllocationTop(cur_addr_); |
| 89 cur_page = cur_page->next_page(); | 89 cur_page = cur_page->next_page(); |
| 90 ASSERT(cur_page->is_valid()); | 90 ASSERT(cur_page->is_valid()); |
| 91 | 91 |
| 92 cur_addr_ = cur_page->ObjectAreaStart(); | 92 cur_addr_ = cur_page->ObjectAreaStart(); |
| 93 cur_limit_ = (cur_page == end_page_) ? end_addr_ : cur_page->AllocationTop(); | 93 cur_limit_ = (cur_page == end_page_) ? end_addr_ : cur_page->AllocationTop(); |
| 94 | 94 |
| 95 if (cur_addr_ == end_addr_) return false; | 95 if (cur_addr_ == end_addr_) return NULL; |
| 96 ASSERT(cur_addr_ < cur_limit_); | 96 ASSERT(cur_addr_ < cur_limit_); |
| 97 #ifdef DEBUG | 97 #ifdef DEBUG |
| 98 Verify(); | 98 Verify(); |
| 99 #endif | 99 #endif |
| 100 return true; | 100 return FromCurrentPage(); |
| 101 } | 101 } |
| 102 | 102 |
| 103 | 103 |
| 104 #ifdef DEBUG | 104 #ifdef DEBUG |
| 105 void HeapObjectIterator::Verify() { | 105 void HeapObjectIterator::Verify() { |
| 106 Page* p = Page::FromAllocationTop(cur_addr_); | 106 Page* p = Page::FromAllocationTop(cur_addr_); |
| 107 ASSERT(p == Page::FromAllocationTop(cur_limit_)); | 107 ASSERT(p == Page::FromAllocationTop(cur_limit_)); |
| 108 ASSERT(p->Offset(cur_addr_) <= p->Offset(cur_limit_)); | 108 ASSERT(p->Offset(cur_addr_) <= p->Offset(cur_limit_)); |
| 109 } | 109 } |
| 110 #endif | 110 #endif |
| (...skipping 1319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1430 } | 1430 } |
| 1431 | 1431 |
| 1432 // Because the copying collector does not touch garbage objects, we iterate | 1432 // Because the copying collector does not touch garbage objects, we iterate |
| 1433 // the new space before a collection to get a histogram of allocated objects. | 1433 // the new space before a collection to get a histogram of allocated objects. |
| 1434 // This only happens (1) when compiled with DEBUG and the --heap-stats flag is | 1434 // This only happens (1) when compiled with DEBUG and the --heap-stats flag is |
| 1435 // set, or when compiled with ENABLE_LOGGING_AND_PROFILING and the --log-gc | 1435 // set, or when compiled with ENABLE_LOGGING_AND_PROFILING and the --log-gc |
| 1436 // flag is set. | 1436 // flag is set. |
| 1437 void NewSpace::CollectStatistics() { | 1437 void NewSpace::CollectStatistics() { |
| 1438 ClearHistograms(); | 1438 ClearHistograms(); |
| 1439 SemiSpaceIterator it(this); | 1439 SemiSpaceIterator it(this); |
| 1440 while (it.has_next()) RecordAllocation(it.next()); | 1440 for (HeapObject* obj = it.next(); obj != NULL; obj = it.next()) |
| 1441 RecordAllocation(obj); |
| 1441 } | 1442 } |
| 1442 | 1443 |
| 1443 | 1444 |
| 1444 #ifdef ENABLE_LOGGING_AND_PROFILING | 1445 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 1445 static void DoReportStatistics(HistogramInfo* info, const char* description) { | 1446 static void DoReportStatistics(HistogramInfo* info, const char* description) { |
| 1446 LOG(HeapSampleBeginEvent("NewSpace", description)); | 1447 LOG(HeapSampleBeginEvent("NewSpace", description)); |
| 1447 // Lump all the string types together. | 1448 // Lump all the string types together. |
| 1448 int string_number = 0; | 1449 int string_number = 0; |
| 1449 int string_bytes = 0; | 1450 int string_bytes = 0; |
| 1450 #define INCREMENT(type, size, name, camel_name) \ | 1451 #define INCREMENT(type, size, name, camel_name) \ |
| (...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2047 } | 2048 } |
| 2048 EnterComment(comment_txt, flat_delta); | 2049 EnterComment(comment_txt, flat_delta); |
| 2049 } | 2050 } |
| 2050 | 2051 |
| 2051 | 2052 |
| 2052 // Collects code size statistics: | 2053 // Collects code size statistics: |
| 2053 // - by code kind | 2054 // - by code kind |
| 2054 // - by code comment | 2055 // - by code comment |
| 2055 void PagedSpace::CollectCodeStatistics() { | 2056 void PagedSpace::CollectCodeStatistics() { |
| 2056 HeapObjectIterator obj_it(this); | 2057 HeapObjectIterator obj_it(this); |
| 2057 while (obj_it.has_next()) { | 2058 for (HeapObject* obj = obj_it.next(); obj != NULL; obj = obj_it.next()) { |
| 2058 HeapObject* obj = obj_it.next(); | |
| 2059 if (obj->IsCode()) { | 2059 if (obj->IsCode()) { |
| 2060 Code* code = Code::cast(obj); | 2060 Code* code = Code::cast(obj); |
| 2061 code_kind_statistics[code->kind()] += code->Size(); | 2061 code_kind_statistics[code->kind()] += code->Size(); |
| 2062 RelocIterator it(code); | 2062 RelocIterator it(code); |
| 2063 int delta = 0; | 2063 int delta = 0; |
| 2064 const byte* prev_pc = code->instruction_start(); | 2064 const byte* prev_pc = code->instruction_start(); |
| 2065 while (!it.done()) { | 2065 while (!it.done()) { |
| 2066 if (it.rinfo()->rmode() == RelocInfo::COMMENT) { | 2066 if (it.rinfo()->rmode() == RelocInfo::COMMENT) { |
| 2067 delta += static_cast<int>(it.rinfo()->pc() - prev_pc); | 2067 delta += static_cast<int>(it.rinfo()->pc() - prev_pc); |
| 2068 CollectCommentStatistics(&it); | 2068 CollectCommentStatistics(&it); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2150 pct = (rset_marked_pointers + rset_marked_array_elements) == 0 ? 0 | 2150 pct = (rset_marked_pointers + rset_marked_array_elements) == 0 ? 0 |
| 2151 : (cross_gen_pointers + cross_gen_array_elements) * 100 / | 2151 : (cross_gen_pointers + cross_gen_array_elements) * 100 / |
| 2152 (rset_marked_pointers + rset_marked_array_elements); | 2152 (rset_marked_pointers + rset_marked_array_elements); |
| 2153 PrintF(" total rset pointers %d, true cross generation ones %d (%%%d)\n", | 2153 PrintF(" total rset pointers %d, true cross generation ones %d (%%%d)\n", |
| 2154 (rset_marked_pointers + rset_marked_array_elements), | 2154 (rset_marked_pointers + rset_marked_array_elements), |
| 2155 (cross_gen_pointers + cross_gen_array_elements), | 2155 (cross_gen_pointers + cross_gen_array_elements), |
| 2156 pct); | 2156 pct); |
| 2157 | 2157 |
| 2158 ClearHistograms(); | 2158 ClearHistograms(); |
| 2159 HeapObjectIterator obj_it(this); | 2159 HeapObjectIterator obj_it(this); |
| 2160 while (obj_it.has_next()) { CollectHistogramInfo(obj_it.next()); } | 2160 for (HeapObject* obj = obj_it.next(); obj != NULL; obj = obj_it.next()) |
| 2161 CollectHistogramInfo(obj); |
| 2161 ReportHistogram(true); | 2162 ReportHistogram(true); |
| 2162 } | 2163 } |
| 2163 | 2164 |
| 2164 | 2165 |
| 2165 // Dump the range of remembered set words between [start, end) corresponding | 2166 // Dump the range of remembered set words between [start, end) corresponding |
| 2166 // to the pointers starting at object_p. The allocation_top is an object | 2167 // to the pointers starting at object_p. The allocation_top is an object |
| 2167 // pointer which should not be read past. This is important for large object | 2168 // pointer which should not be read past. This is important for large object |
| 2168 // pages, where some bits in the remembered set range do not correspond to | 2169 // pages, where some bits in the remembered set range do not correspond to |
| 2169 // allocated addresses. | 2170 // allocated addresses. |
| 2170 static void PrintRSetRange(Address start, Address end, Object** object_p, | 2171 static void PrintRSetRange(Address start, Address end, Object** object_p, |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2386 } | 2387 } |
| 2387 } | 2388 } |
| 2388 | 2389 |
| 2389 pct = rset_marked_pointers == 0 ? | 2390 pct = rset_marked_pointers == 0 ? |
| 2390 0 : cross_gen_pointers * 100 / rset_marked_pointers; | 2391 0 : cross_gen_pointers * 100 / rset_marked_pointers; |
| 2391 PrintF(" rset-marked pointers %d, to-new-space %d (%%%d)\n", | 2392 PrintF(" rset-marked pointers %d, to-new-space %d (%%%d)\n", |
| 2392 rset_marked_pointers, cross_gen_pointers, pct); | 2393 rset_marked_pointers, cross_gen_pointers, pct); |
| 2393 | 2394 |
| 2394 ClearHistograms(); | 2395 ClearHistograms(); |
| 2395 HeapObjectIterator obj_it(this); | 2396 HeapObjectIterator obj_it(this); |
| 2396 while (obj_it.has_next()) { CollectHistogramInfo(obj_it.next()); } | 2397 for (HeapObject* obj = obj_it.next(); obj != NULL; obj = obj_it.next()) |
| 2398 CollectHistogramInfo(obj); |
| 2397 ReportHistogram(false); | 2399 ReportHistogram(false); |
| 2398 } | 2400 } |
| 2399 | 2401 |
| 2400 | 2402 |
| 2401 void FixedSpace::PrintRSet() { DoPrintRSet(name_); } | 2403 void FixedSpace::PrintRSet() { DoPrintRSet(name_); } |
| 2402 #endif | 2404 #endif |
| 2403 | 2405 |
| 2404 | 2406 |
| 2405 // ----------------------------------------------------------------------------- | 2407 // ----------------------------------------------------------------------------- |
| 2406 // MapSpace implementation | 2408 // MapSpace implementation |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2455 | 2457 |
| 2456 | 2458 |
| 2457 LargeObjectIterator::LargeObjectIterator(LargeObjectSpace* space, | 2459 LargeObjectIterator::LargeObjectIterator(LargeObjectSpace* space, |
| 2458 HeapObjectCallback size_func) { | 2460 HeapObjectCallback size_func) { |
| 2459 current_ = space->first_chunk_; | 2461 current_ = space->first_chunk_; |
| 2460 size_func_ = size_func; | 2462 size_func_ = size_func; |
| 2461 } | 2463 } |
| 2462 | 2464 |
| 2463 | 2465 |
| 2464 HeapObject* LargeObjectIterator::next() { | 2466 HeapObject* LargeObjectIterator::next() { |
| 2465 ASSERT(has_next()); | 2467 if (current_ == NULL) return NULL; |
| 2468 |
| 2466 HeapObject* object = current_->GetObject(); | 2469 HeapObject* object = current_->GetObject(); |
| 2467 current_ = current_->next(); | 2470 current_ = current_->next(); |
| 2468 return object; | 2471 return object; |
| 2469 } | 2472 } |
| 2470 | 2473 |
| 2471 | 2474 |
| 2472 // ----------------------------------------------------------------------------- | 2475 // ----------------------------------------------------------------------------- |
| 2473 // LargeObjectChunk | 2476 // LargeObjectChunk |
| 2474 | 2477 |
| 2475 LargeObjectChunk* LargeObjectChunk::New(int size_in_bytes, | 2478 LargeObjectChunk* LargeObjectChunk::New(int size_in_bytes, |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2632 } | 2635 } |
| 2633 } | 2636 } |
| 2634 return Failure::Exception(); | 2637 return Failure::Exception(); |
| 2635 } | 2638 } |
| 2636 | 2639 |
| 2637 | 2640 |
| 2638 void LargeObjectSpace::ClearRSet() { | 2641 void LargeObjectSpace::ClearRSet() { |
| 2639 ASSERT(Page::is_rset_in_use()); | 2642 ASSERT(Page::is_rset_in_use()); |
| 2640 | 2643 |
| 2641 LargeObjectIterator it(this); | 2644 LargeObjectIterator it(this); |
| 2642 while (it.has_next()) { | 2645 for (HeapObject* object = it.next(); object != NULL; object = it.next()) { |
| 2643 HeapObject* object = it.next(); | |
| 2644 // We only have code, sequential strings, or fixed arrays in large | 2646 // We only have code, sequential strings, or fixed arrays in large |
| 2645 // object space, and only fixed arrays need remembered set support. | 2647 // object space, and only fixed arrays need remembered set support. |
| 2646 if (object->IsFixedArray()) { | 2648 if (object->IsFixedArray()) { |
| 2647 // Clear the normal remembered set region of the page; | 2649 // Clear the normal remembered set region of the page; |
| 2648 Page* page = Page::FromAddress(object->address()); | 2650 Page* page = Page::FromAddress(object->address()); |
| 2649 page->ClearRSet(); | 2651 page->ClearRSet(); |
| 2650 | 2652 |
| 2651 // Clear the extra remembered set. | 2653 // Clear the extra remembered set. |
| 2652 int size = object->Size(); | 2654 int size = object->Size(); |
| 2653 int extra_rset_bytes = ExtraRSetBytesFor(size); | 2655 int extra_rset_bytes = ExtraRSetBytesFor(size); |
| 2654 memset(object->address() + size, 0, extra_rset_bytes); | 2656 memset(object->address() + size, 0, extra_rset_bytes); |
| 2655 } | 2657 } |
| 2656 } | 2658 } |
| 2657 } | 2659 } |
| 2658 | 2660 |
| 2659 | 2661 |
| 2660 void LargeObjectSpace::IterateRSet(ObjectSlotCallback copy_object_func) { | 2662 void LargeObjectSpace::IterateRSet(ObjectSlotCallback copy_object_func) { |
| 2661 ASSERT(Page::is_rset_in_use()); | 2663 ASSERT(Page::is_rset_in_use()); |
| 2662 | 2664 |
| 2663 static void* lo_rset_histogram = StatsTable::CreateHistogram( | 2665 static void* lo_rset_histogram = StatsTable::CreateHistogram( |
| 2664 "V8.RSetLO", | 2666 "V8.RSetLO", |
| 2665 0, | 2667 0, |
| 2666 // Keeping this histogram's buckets the same as the paged space histogram. | 2668 // Keeping this histogram's buckets the same as the paged space histogram. |
| 2667 Page::kObjectAreaSize / kPointerSize, | 2669 Page::kObjectAreaSize / kPointerSize, |
| 2668 30); | 2670 30); |
| 2669 | 2671 |
| 2670 LargeObjectIterator it(this); | 2672 LargeObjectIterator it(this); |
| 2671 while (it.has_next()) { | 2673 for (HeapObject* object = it.next(); object != NULL; object = it.next()) { |
| 2672 // We only have code, sequential strings, or fixed arrays in large | 2674 // We only have code, sequential strings, or fixed arrays in large |
| 2673 // object space, and only fixed arrays can possibly contain pointers to | 2675 // object space, and only fixed arrays can possibly contain pointers to |
| 2674 // the young generation. | 2676 // the young generation. |
| 2675 HeapObject* object = it.next(); | |
| 2676 if (object->IsFixedArray()) { | 2677 if (object->IsFixedArray()) { |
| 2677 // Iterate the normal page remembered set range. | 2678 // Iterate the normal page remembered set range. |
| 2678 Page* page = Page::FromAddress(object->address()); | 2679 Page* page = Page::FromAddress(object->address()); |
| 2679 Address object_end = object->address() + object->Size(); | 2680 Address object_end = object->address() + object->Size(); |
| 2680 int count = Heap::IterateRSetRange(page->ObjectAreaStart(), | 2681 int count = Heap::IterateRSetRange(page->ObjectAreaStart(), |
| 2681 Min(page->ObjectAreaEnd(), object_end), | 2682 Min(page->ObjectAreaEnd(), object_end), |
| 2682 page->RSetStart(), | 2683 page->RSetStart(), |
| 2683 copy_object_func); | 2684 copy_object_func); |
| 2684 | 2685 |
| 2685 // Iterate the extra array elements. | 2686 // Iterate the extra array elements. |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2791 } | 2792 } |
| 2792 } | 2793 } |
| 2793 } | 2794 } |
| 2794 } | 2795 } |
| 2795 } | 2796 } |
| 2796 } | 2797 } |
| 2797 | 2798 |
| 2798 | 2799 |
| 2799 void LargeObjectSpace::Print() { | 2800 void LargeObjectSpace::Print() { |
| 2800 LargeObjectIterator it(this); | 2801 LargeObjectIterator it(this); |
| 2801 while (it.has_next()) { | 2802 for (HeapObject* obj = it.next(); obj != NULL; obj = it.next()) { |
| 2802 it.next()->Print(); | 2803 obj->Print(); |
| 2803 } | 2804 } |
| 2804 } | 2805 } |
| 2805 | 2806 |
| 2806 | 2807 |
| 2807 void LargeObjectSpace::ReportStatistics() { | 2808 void LargeObjectSpace::ReportStatistics() { |
| 2808 PrintF(" size: %d\n", size_); | 2809 PrintF(" size: %d\n", size_); |
| 2809 int num_objects = 0; | 2810 int num_objects = 0; |
| 2810 ClearHistograms(); | 2811 ClearHistograms(); |
| 2811 LargeObjectIterator it(this); | 2812 LargeObjectIterator it(this); |
| 2812 while (it.has_next()) { | 2813 for (HeapObject* obj = it.next(); obj != NULL; obj = it.next()) { |
| 2813 num_objects++; | 2814 num_objects++; |
| 2814 CollectHistogramInfo(it.next()); | 2815 CollectHistogramInfo(obj); |
| 2815 } | 2816 } |
| 2816 | 2817 |
| 2817 PrintF(" number of objects %d\n", num_objects); | 2818 PrintF(" number of objects %d\n", num_objects); |
| 2818 if (num_objects > 0) ReportHistogram(false); | 2819 if (num_objects > 0) ReportHistogram(false); |
| 2819 } | 2820 } |
| 2820 | 2821 |
| 2821 | 2822 |
| 2822 void LargeObjectSpace::CollectCodeStatistics() { | 2823 void LargeObjectSpace::CollectCodeStatistics() { |
| 2823 LargeObjectIterator obj_it(this); | 2824 LargeObjectIterator obj_it(this); |
| 2824 while (obj_it.has_next()) { | 2825 for (HeapObject* obj = obj_it.next(); obj != NULL; obj = obj_it.next()) { |
| 2825 HeapObject* obj = obj_it.next(); | |
| 2826 if (obj->IsCode()) { | 2826 if (obj->IsCode()) { |
| 2827 Code* code = Code::cast(obj); | 2827 Code* code = Code::cast(obj); |
| 2828 code_kind_statistics[code->kind()] += code->Size(); | 2828 code_kind_statistics[code->kind()] += code->Size(); |
| 2829 } | 2829 } |
| 2830 } | 2830 } |
| 2831 } | 2831 } |
| 2832 | 2832 |
| 2833 | 2833 |
| 2834 void LargeObjectSpace::PrintRSet() { | 2834 void LargeObjectSpace::PrintRSet() { |
| 2835 LargeObjectIterator it(this); | 2835 LargeObjectIterator it(this); |
| 2836 while (it.has_next()) { | 2836 for (HeapObject* object = it.next(); object != NULL; object = it.next()) { |
| 2837 HeapObject* object = it.next(); | |
| 2838 if (object->IsFixedArray()) { | 2837 if (object->IsFixedArray()) { |
| 2839 Page* page = Page::FromAddress(object->address()); | 2838 Page* page = Page::FromAddress(object->address()); |
| 2840 | 2839 |
| 2841 Address allocation_top = object->address() + object->Size(); | 2840 Address allocation_top = object->address() + object->Size(); |
| 2842 PrintF("large page 0x%x:\n", page); | 2841 PrintF("large page 0x%x:\n", page); |
| 2843 PrintRSetRange(page->RSetStart(), page->RSetEnd(), | 2842 PrintRSetRange(page->RSetStart(), page->RSetEnd(), |
| 2844 reinterpret_cast<Object**>(object->address()), | 2843 reinterpret_cast<Object**>(object->address()), |
| 2845 allocation_top); | 2844 allocation_top); |
| 2846 int extra_array_bytes = object->Size() - Page::kObjectAreaSize; | 2845 int extra_array_bytes = object->Size() - Page::kObjectAreaSize; |
| 2847 int extra_rset_bits = RoundUp(extra_array_bytes / kPointerSize, | 2846 int extra_rset_bits = RoundUp(extra_array_bytes / kPointerSize, |
| 2848 kBitsPerInt); | 2847 kBitsPerInt); |
| 2849 PrintF("------------------------------------------------------------" | 2848 PrintF("------------------------------------------------------------" |
| 2850 "-----------\n"); | 2849 "-----------\n"); |
| 2851 PrintRSetRange(allocation_top, | 2850 PrintRSetRange(allocation_top, |
| 2852 allocation_top + extra_rset_bits / kBitsPerByte, | 2851 allocation_top + extra_rset_bits / kBitsPerByte, |
| 2853 reinterpret_cast<Object**>(object->address() | 2852 reinterpret_cast<Object**>(object->address() |
| 2854 + Page::kObjectAreaSize), | 2853 + Page::kObjectAreaSize), |
| 2855 allocation_top); | 2854 allocation_top); |
| 2856 PrintF("\n"); | 2855 PrintF("\n"); |
| 2857 } | 2856 } |
| 2858 } | 2857 } |
| 2859 } | 2858 } |
| 2860 #endif // DEBUG | 2859 #endif // DEBUG |
| 2861 | 2860 |
| 2862 } } // namespace v8::internal | 2861 } } // namespace v8::internal |
| OLD | NEW |