Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp @ 4137:04b9a2566eec
Merge with hsx23/hotspot.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sat, 17 Dec 2011 21:40:27 +0100 |
parents | fe189d4a44e9 bca17e38de00 |
children | 33df1aeaebbf |
comparison
equal
deleted
inserted
replaced
3737:9dc19b7d89a3 | 4137:04b9a2566eec |
---|---|
31 #include "memory/universe.hpp" | 31 #include "memory/universe.hpp" |
32 #include "oops/oop.inline.hpp" | 32 #include "oops/oop.inline.hpp" |
33 #include "runtime/java.hpp" | 33 #include "runtime/java.hpp" |
34 #include "runtime/mutexLocker.hpp" | 34 #include "runtime/mutexLocker.hpp" |
35 #include "runtime/virtualspace.hpp" | 35 #include "runtime/virtualspace.hpp" |
36 #include "runtime/vmThread.hpp" | |
36 | 37 |
37 void CardTableModRefBS::non_clean_card_iterate_parallel_work(Space* sp, MemRegion mr, | 38 void CardTableModRefBS::non_clean_card_iterate_parallel_work(Space* sp, MemRegion mr, |
38 OopsInGenClosure* cl, | 39 OopsInGenClosure* cl, |
39 CardTableRS* ct, | 40 CardTableRS* ct, |
40 int n_threads) { | 41 int n_threads) { |
41 assert(n_threads > 0, "Error: expected n_threads > 0"); | 42 assert(n_threads > 0, "Error: expected n_threads > 0"); |
42 assert((n_threads == 1 && ParallelGCThreads == 0) || | 43 assert((n_threads == 1 && ParallelGCThreads == 0) || |
43 n_threads <= (int)ParallelGCThreads, | 44 n_threads <= (int)ParallelGCThreads, |
44 "# worker threads != # requested!"); | 45 "# worker threads != # requested!"); |
46 assert(!Thread::current()->is_VM_thread() || (n_threads == 1), "There is only 1 VM thread"); | |
47 assert(UseDynamicNumberOfGCThreads || | |
48 !FLAG_IS_DEFAULT(ParallelGCThreads) || | |
49 n_threads == (int)ParallelGCThreads, | |
50 "# worker threads != # requested!"); | |
45 // Make sure the LNC array is valid for the space. | 51 // Make sure the LNC array is valid for the space. |
46 jbyte** lowest_non_clean; | 52 jbyte** lowest_non_clean; |
47 uintptr_t lowest_non_clean_base_chunk_index; | 53 uintptr_t lowest_non_clean_base_chunk_index; |
48 size_t lowest_non_clean_chunk_size; | 54 size_t lowest_non_clean_chunk_size; |
49 get_LNC_array_for_space(sp, lowest_non_clean, | 55 get_LNC_array_for_space(sp, lowest_non_clean, |
50 lowest_non_clean_base_chunk_index, | 56 lowest_non_clean_base_chunk_index, |
51 lowest_non_clean_chunk_size); | 57 lowest_non_clean_chunk_size); |
52 | 58 |
53 int n_strides = n_threads * ParGCStridesPerThread; | 59 int n_strides = n_threads * ParGCStridesPerThread; |
54 SequentialSubTasksDone* pst = sp->par_seq_tasks(); | 60 SequentialSubTasksDone* pst = sp->par_seq_tasks(); |
61 // Sets the condition for completion of the subtask (how many threads | |
62 // need to finish in order to be done). | |
55 pst->set_n_threads(n_threads); | 63 pst->set_n_threads(n_threads); |
56 pst->set_n_tasks(n_strides); | 64 pst->set_n_tasks(n_strides); |
57 | 65 |
58 int stride = 0; | 66 int stride = 0; |
59 while (!pst->is_task_claimed(/* reference */ stride)) { | 67 while (!pst->is_task_claimed(/* reference */ stride)) { |
346 "Bounds error."); | 354 "Bounds error."); |
347 // It is possible that a dirty card for the last object may have been | 355 // It is possible that a dirty card for the last object may have been |
348 // cleared before we had a chance to examine it. In that case, the value | 356 // cleared before we had a chance to examine it. In that case, the value |
349 // will have been logged in the LNC for that chunk. | 357 // will have been logged in the LNC for that chunk. |
350 // We need to examine as many chunks to the right as this object | 358 // We need to examine as many chunks to the right as this object |
351 // covers. | 359 // covers. However, we need to bound this checking to the largest |
352 const uintptr_t last_chunk_index_to_check = addr_to_chunk_index(last_block + last_block_size - 1) | 360 // entry in the LNC array: this is because the heap may expand |
353 - lowest_non_clean_base_chunk_index; | 361 // after the LNC array has been created but before we reach this point, |
354 DEBUG_ONLY(const uintptr_t last_chunk_index = addr_to_chunk_index(used.last()) | 362 // and the last block in our chunk may have been expanded to include |
355 - lowest_non_clean_base_chunk_index;) | 363 // the expansion delta (and possibly subsequently allocated from, so |
356 assert(last_chunk_index_to_check <= last_chunk_index, | 364 // it wouldn't be sufficient to check whether that last block was |
357 err_msg("Out of bounds: last_chunk_index_to_check " INTPTR_FORMAT | 365 // or was not an object at this point). |
358 " exceeds last_chunk_index " INTPTR_FORMAT, | 366 uintptr_t last_chunk_index_to_check = addr_to_chunk_index(last_block + last_block_size - 1) |
359 last_chunk_index_to_check, last_chunk_index)); | 367 - lowest_non_clean_base_chunk_index; |
368 const uintptr_t last_chunk_index = addr_to_chunk_index(used.last()) | |
369 - lowest_non_clean_base_chunk_index; | |
370 if (last_chunk_index_to_check > last_chunk_index) { | |
371 assert(last_block + last_block_size > used.end(), | |
372 err_msg("Inconsistency detected: last_block [" PTR_FORMAT "," PTR_FORMAT "]" | |
373 " does not exceed used.end() = " PTR_FORMAT "," | |
374 " yet last_chunk_index_to_check " INTPTR_FORMAT | |
375 " exceeds last_chunk_index " INTPTR_FORMAT, | |
376 last_chunk_index_to_check, last_chunk_index)); | |
377 assert(sp->used_region().end() > used.end(), | |
378 err_msg("Expansion did not happen: " | |
379 "[" PTR_FORMAT "," PTR_FORMAT ") -> [" PTR_FORMAT "," PTR_FORMAT ")", | |
380 sp->used_region().start(), sp->used_region().end(), used.start(), used.end())); | |
381 NOISY(tty->print_cr(" process_chunk_boundary: heap expanded; explicitly bounding last_chunk");) | |
382 last_chunk_index_to_check = last_chunk_index; | |
383 } | |
360 for (uintptr_t lnc_index = cur_chunk_index + 1; | 384 for (uintptr_t lnc_index = cur_chunk_index + 1; |
361 lnc_index <= last_chunk_index_to_check; | 385 lnc_index <= last_chunk_index_to_check; |
362 lnc_index++) { | 386 lnc_index++) { |
363 jbyte* lnc_card = lowest_non_clean[lnc_index]; | 387 jbyte* lnc_card = lowest_non_clean[lnc_index]; |
364 if (lnc_card != NULL) { | 388 if (lnc_card != NULL) { |