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