< prev index next >

src/share/vm/gc/g1/g1ConcurrentMark.hpp

Print this page
rev 12666 : imported patch 8168467-use-taskentry-as-mark-stack-elem
rev 12667 : imported patch 8168467-kim-review

*** 50,63 **** class G1TaskQueueEntry VALUE_OBJ_CLASS_SPEC { private: void* _holder; static const uintptr_t ArraySliceBit = 1; public: G1TaskQueueEntry() : _holder(NULL) { } ! G1TaskQueueEntry(oop obj) : _holder(obj) { } ! G1TaskQueueEntry(HeapWord* addr) : _holder((void*)((uintptr_t)addr | ArraySliceBit)) { } G1TaskQueueEntry& operator=(const G1TaskQueueEntry& t) { _holder = t._holder; return *this; } --- 50,70 ---- class G1TaskQueueEntry VALUE_OBJ_CLASS_SPEC { private: void* _holder; static const uintptr_t ArraySliceBit = 1; + + G1TaskQueueEntry(oop obj) : _holder(obj) { + assert(_holder != NULL, "Not allowed to set NULL task queue element"); + } + G1TaskQueueEntry(HeapWord* addr) : _holder((void*)((uintptr_t)addr | ArraySliceBit)) { } public: + G1TaskQueueEntry(const G1TaskQueueEntry& other) { _holder = other._holder; } G1TaskQueueEntry() : _holder(NULL) { } ! ! static G1TaskQueueEntry from_slice(HeapWord* what) { return G1TaskQueueEntry(what); } ! static G1TaskQueueEntry from_oop(oop obj) { return G1TaskQueueEntry(obj); } G1TaskQueueEntry& operator=(const G1TaskQueueEntry& t) { _holder = t._holder; return *this; }
*** 72,82 **** return (oop)_holder; } HeapWord* slice() const { assert(is_array_slice(), "Trying to read oop " PTR_FORMAT " as array slice", p2i(_holder)); ! return (HeapWord*)((uintptr_t)_holder &~ ArraySliceBit); } bool is_oop() const { return !is_array_slice(); } bool is_array_slice() const { return ((uintptr_t)_holder & ArraySliceBit) != 0; } bool is_null() const { return _holder == NULL; } --- 79,89 ---- return (oop)_holder; } HeapWord* slice() const { assert(is_array_slice(), "Trying to read oop " PTR_FORMAT " as array slice", p2i(_holder)); ! return (HeapWord*)((uintptr_t)_holder & ~ArraySliceBit); } bool is_oop() const { return !is_array_slice(); } bool is_array_slice() const { return ((uintptr_t)_holder & ArraySliceBit) != 0; } bool is_null() const { return _holder == NULL; }
*** 214,260 **** class G1CMMarkStack VALUE_OBJ_CLASS_SPEC { public: // Number of oops that can fit in a single chunk. static const size_t EntriesPerChunk = 1024 - 1 /* One reference for the next pointer */; private: ! struct OopChunk { ! OopChunk* next; G1TaskQueueEntry data[EntriesPerChunk]; }; size_t _max_chunk_capacity; // Maximum number of OopChunk elements on the stack. ! OopChunk* _base; // Bottom address of allocated memory area. size_t _chunk_capacity; // Current maximum number of OopChunk elements. char _pad0[DEFAULT_CACHE_LINE_SIZE]; ! OopChunk* volatile _free_list; // Linked list of free chunks that can be allocated by users. ! char _pad1[DEFAULT_CACHE_LINE_SIZE - sizeof(OopChunk*)]; ! OopChunk* volatile _chunk_list; // List of chunks currently containing data. volatile size_t _chunks_in_chunk_list; ! char _pad2[DEFAULT_CACHE_LINE_SIZE - sizeof(OopChunk*) - sizeof(size_t)]; volatile size_t _hwm; // High water mark within the reserved space. char _pad4[DEFAULT_CACHE_LINE_SIZE - sizeof(size_t)]; // Allocate a new chunk from the reserved memory, using the high water mark. Returns // NULL if out of memory. ! OopChunk* allocate_new_chunk(); volatile bool _out_of_memory; // Atomically add the given chunk to the list. ! void add_chunk_to_list(OopChunk* volatile* list, OopChunk* elem); // Atomically remove and return a chunk from the given list. Returns NULL if the // list is empty. ! OopChunk* remove_chunk_from_list(OopChunk* volatile* list); ! void add_chunk_to_chunk_list(OopChunk* elem); ! void add_chunk_to_free_list(OopChunk* elem); ! OopChunk* remove_chunk_from_chunk_list(); ! OopChunk* remove_chunk_from_free_list(); bool _should_expand; // Resizes the mark stack to the given new capacity. Releases any previous // memory if successful. --- 221,267 ---- class G1CMMarkStack VALUE_OBJ_CLASS_SPEC { public: // Number of oops that can fit in a single chunk. static const size_t EntriesPerChunk = 1024 - 1 /* One reference for the next pointer */; private: ! struct TaskQueueEntryChunk { ! TaskQueueEntryChunk* next; G1TaskQueueEntry data[EntriesPerChunk]; }; size_t _max_chunk_capacity; // Maximum number of OopChunk elements on the stack. ! TaskQueueEntryChunk* _base; // Bottom address of allocated memory area. size_t _chunk_capacity; // Current maximum number of OopChunk elements. char _pad0[DEFAULT_CACHE_LINE_SIZE]; ! TaskQueueEntryChunk* volatile _free_list; // Linked list of free chunks that can be allocated by users. ! char _pad1[DEFAULT_CACHE_LINE_SIZE - sizeof(TaskQueueEntryChunk*)]; ! TaskQueueEntryChunk* volatile _chunk_list; // List of chunks currently containing data. volatile size_t _chunks_in_chunk_list; ! char _pad2[DEFAULT_CACHE_LINE_SIZE - sizeof(TaskQueueEntryChunk*) - sizeof(size_t)]; volatile size_t _hwm; // High water mark within the reserved space. char _pad4[DEFAULT_CACHE_LINE_SIZE - sizeof(size_t)]; // Allocate a new chunk from the reserved memory, using the high water mark. Returns // NULL if out of memory. ! TaskQueueEntryChunk* allocate_new_chunk(); volatile bool _out_of_memory; // Atomically add the given chunk to the list. ! void add_chunk_to_list(TaskQueueEntryChunk* volatile* list, TaskQueueEntryChunk* elem); // Atomically remove and return a chunk from the given list. Returns NULL if the // list is empty. ! TaskQueueEntryChunk* remove_chunk_from_list(TaskQueueEntryChunk* volatile* list); ! void add_chunk_to_chunk_list(TaskQueueEntryChunk* elem); ! void add_chunk_to_free_list(TaskQueueEntryChunk* elem); ! TaskQueueEntryChunk* remove_chunk_from_chunk_list(); ! TaskQueueEntryChunk* remove_chunk_from_free_list(); bool _should_expand; // Resizes the mark stack to the given new capacity. Releases any previous // memory if successful.
*** 268,286 **** static size_t capacity_alignment(); // Allocate and initialize the mark stack with the given number of oops. bool initialize(size_t initial_capacity, size_t max_capacity); ! // Pushes the given buffer containing at most OopsPerChunk elements on the mark ! // stack. If less than OopsPerChunk elements are to be pushed, the array must // be terminated with a NULL. // Returns whether the buffer contents were successfully pushed to the global mark // stack. bool par_push_chunk(G1TaskQueueEntry* buffer); // Pops a chunk from this mark stack, copying them into the given buffer. This ! // chunk may contain up to OopsPerChunk elements. If there are less, the last // element in the array is a NULL pointer. bool par_pop_chunk(G1TaskQueueEntry* buffer); // Return whether the chunk list is empty. Racy due to unsynchronized access to // _chunk_list. --- 275,293 ---- static size_t capacity_alignment(); // Allocate and initialize the mark stack with the given number of oops. bool initialize(size_t initial_capacity, size_t max_capacity); ! // Pushes the given buffer containing at most EntriesPerChunk elements on the mark ! // stack. If less than EntriesPerChunk elements are to be pushed, the array must // be terminated with a NULL. // Returns whether the buffer contents were successfully pushed to the global mark // stack. bool par_push_chunk(G1TaskQueueEntry* buffer); // Pops a chunk from this mark stack, copying them into the given buffer. This ! // chunk may contain up to EntriesPerChunk elements. If there are less, the last // element in the array is a NULL pointer. bool par_pop_chunk(G1TaskQueueEntry* buffer); // Return whether the chunk list is empty. Racy due to unsynchronized access to // _chunk_list.
*** 874,884 **** // Test whether obj might have already been passed over by the // mark bitmap scan, and so needs to be pushed onto the mark stack. bool is_below_finger(oop obj, HeapWord* global_finger) const; ! template<bool scan> void process_grey_object(G1TaskQueueEntry task_entry); public: // Apply the closure on the given area of the objArray. Return the number of words // scanned. inline size_t scan_objArray(objArrayOop obj, MemRegion mr); // It resets the task; it should be called right at the beginning of --- 881,891 ---- // Test whether obj might have already been passed over by the // mark bitmap scan, and so needs to be pushed onto the mark stack. bool is_below_finger(oop obj, HeapWord* global_finger) const; ! template<bool scan> void process_grey_task_entry(G1TaskQueueEntry task_entry); public: // Apply the closure on the given area of the objArray. Return the number of words // scanned. inline size_t scan_objArray(objArrayOop obj, MemRegion mr); // It resets the task; it should be called right at the beginning of
*** 939,949 **** // e.g. obj is below its containing region's NTAMS. // Precondition: obj is a valid heap object. inline void deal_with_reference(oop obj); // It scans an object and visits its children. ! inline void scan_object(G1TaskQueueEntry task_entry); // It pushes an object on the local queue. inline void push(G1TaskQueueEntry task_entry); // Move entries to the global stack. --- 946,956 ---- // e.g. obj is below its containing region's NTAMS. // Precondition: obj is a valid heap object. inline void deal_with_reference(oop obj); // It scans an object and visits its children. ! inline void scan_task_entry(G1TaskQueueEntry task_entry); // It pushes an object on the local queue. inline void push(G1TaskQueueEntry task_entry); // Move entries to the global stack.
< prev index next >