Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/g1/sparsePRT.cpp @ 2173:97ba643ea3ed
7014261: G1: RSet-related failures
Summary: A race between the concurrent cleanup thread and the VM thread while it is processing the "expanded sparse table list" causes both threads to try to free the same sparse table entry and either causes one of the threads to fail or leaves the entry in an inconsistent state. The solution is purge all entries on the expanded list that correspond go regions that are being cleaned up.
Reviewed-by: brutisso, johnc
author | tonyp |
---|---|
date | Tue, 25 Jan 2011 17:58:19 -0500 |
parents | f95d63e2154a |
children | c3f1170908be |
comparison
equal
deleted
inserted
replaced
2172:a672e43650cc | 2173:97ba643ea3ed |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
413 } | 413 } |
414 } | 414 } |
415 return NULL; | 415 return NULL; |
416 } | 416 } |
417 | 417 |
418 void SparsePRT::reset_for_cleanup_tasks() { | |
419 _head_expanded_list = NULL; | |
420 } | |
421 | |
422 void SparsePRT::do_cleanup_work(SparsePRTCleanupTask* sprt_cleanup_task) { | |
423 if (should_be_on_expanded_list()) { | |
424 sprt_cleanup_task->add(this); | |
425 } | |
426 } | |
427 | |
428 void SparsePRT::finish_cleanup_task(SparsePRTCleanupTask* sprt_cleanup_task) { | |
429 assert(ParGCRareEvent_lock->owned_by_self(), "pre-condition"); | |
430 SparsePRT* head = sprt_cleanup_task->head(); | |
431 SparsePRT* tail = sprt_cleanup_task->tail(); | |
432 if (head != NULL) { | |
433 assert(tail != NULL, "if head is not NULL, so should tail"); | |
434 | |
435 tail->set_next_expanded(_head_expanded_list); | |
436 _head_expanded_list = head; | |
437 } else { | |
438 assert(tail == NULL, "if head is NULL, so should tail"); | |
439 } | |
440 } | |
441 | |
442 bool SparsePRT::should_be_on_expanded_list() { | |
443 if (_expanded) { | |
444 assert(_cur != _next, "if _expanded is true, cur should be != _next"); | |
445 } else { | |
446 assert(_cur == _next, "if _expanded is false, cur should be == _next"); | |
447 } | |
448 return expanded(); | |
449 } | |
418 | 450 |
419 void SparsePRT::cleanup_all() { | 451 void SparsePRT::cleanup_all() { |
420 // First clean up all expanded tables so they agree on next and cur. | 452 // First clean up all expanded tables so they agree on next and cur. |
421 SparsePRT* sprt = get_from_expanded_list(); | 453 SparsePRT* sprt = get_from_expanded_list(); |
422 while (sprt != NULL) { | 454 while (sprt != NULL) { |
482 _cur = new RSHashTable(InitialCapacity); | 514 _cur = new RSHashTable(InitialCapacity); |
483 } else { | 515 } else { |
484 _cur->clear(); | 516 _cur->clear(); |
485 } | 517 } |
486 _next = _cur; | 518 _next = _cur; |
519 _expanded = false; | |
487 } | 520 } |
488 | 521 |
489 void SparsePRT::cleanup() { | 522 void SparsePRT::cleanup() { |
490 // Make sure that the current and next tables agree. | 523 // Make sure that the current and next tables agree. |
491 if (_cur != _next) { | 524 if (_cur != _next) { |
516 if (last != _cur) { | 549 if (last != _cur) { |
517 delete last; | 550 delete last; |
518 } | 551 } |
519 add_to_expanded_list(this); | 552 add_to_expanded_list(this); |
520 } | 553 } |
554 | |
555 void SparsePRTCleanupTask::add(SparsePRT* sprt) { | |
556 assert(sprt->should_be_on_expanded_list(), "pre-condition"); | |
557 | |
558 sprt->set_next_expanded(NULL); | |
559 if (_tail != NULL) { | |
560 _tail->set_next_expanded(sprt); | |
561 } else { | |
562 _head = sprt; | |
563 } | |
564 _tail = sprt; | |
565 } |