# HG changeset patch # User jmasa # Date 1323487714 28800 # Node ID 6d7d0790074d4cf83064573ac8d3942dda4a0a16 # Parent e9b91fd07263189b5548e66726ae2537139d889d 7119584: UseParallelGC barrier task can be overwritten. Summary: Provoke a GC for a metadata allocation failure. Reviewed-by: johnc, iveresov diff -r e9b91fd07263 -r 6d7d0790074d src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp Fri Dec 09 06:46:57 2011 -0800 +++ b/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp Fri Dec 09 19:28:34 2011 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,6 +53,9 @@ case noop_task: result = "noop task"; break; + case idle_task: + result = "idle task"; + break; } return result; }; @@ -782,6 +785,12 @@ void GCTaskManager::execute_and_wait(GCTaskQueue* list) { WaitForBarrierGCTask* fin = WaitForBarrierGCTask::create(); list->enqueue(fin); + // The barrier task will be read by one of the GC + // workers once it is added to the list of tasks. + // Be sure that is globally visible before the + // GC worker reads it (which is after the task is added + // to the list of tasks below). + OrderAccess::storestore(); add_list(list); fin->wait_for(true /* reset */); // We have to release the barrier tasks! @@ -833,11 +842,15 @@ IdleGCTask* IdleGCTask::create() { IdleGCTask* result = new IdleGCTask(false); + assert(UseDynamicNumberOfGCThreads, + "Should only be used with dynamic GC thread"); return result; } IdleGCTask* IdleGCTask::create_on_c_heap() { IdleGCTask* result = new(ResourceObj::C_HEAP) IdleGCTask(true); + assert(UseDynamicNumberOfGCThreads, + "Should only be used with dynamic GC thread"); return result; } diff -r e9b91fd07263 -r 6d7d0790074d src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp Fri Dec 09 06:46:57 2011 -0800 +++ b/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp Fri Dec 09 19:28:34 2011 -0800 @@ -1,6 +1,6 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -129,6 +129,8 @@ for (; /* break */; ) { // This will block until there is a task to be gotten. GCTask* task = manager()->get_task(which()); + // Record if this is an idle task for later use. + bool is_idle_task = task->is_idle_task(); // In case the update is costly if (PrintGCTaskTimeStamps) { timer.update(); @@ -137,9 +139,13 @@ jlong entry_time = timer.ticks(); char* name = task->name(); + // If this is the barrier task, it can be destroyed + // by the GC task manager once the do_it() executes. task->do_it(manager(), which()); - if (!task->is_idle_task()) { + // Use the saved value of is_idle_task because references + // using "task" are not reliable for the barrier task. + if (!is_idle_task) { manager()->note_completion(which()); if (PrintGCTaskTimeStamps) {