summaryrefslogtreecommitdiffstats
path: root/runtime/gc/collector
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2013-11-29 17:24:40 -0800
committerMathieu Chartier <mathieuc@google.com>2013-12-16 16:57:37 -0800
commit692fafd9778141fa6ef0048c9569abd7ee0253bf (patch)
tree63ce2c7d4be6af2524a5f442195c8c8b6f5cc955 /runtime/gc/collector
parent07dc96d370c4844c7a279c01cedf24a272b9f4f3 (diff)
downloadart-692fafd9778141fa6ef0048c9569abd7ee0253bf.zip
art-692fafd9778141fa6ef0048c9569abd7ee0253bf.tar.gz
art-692fafd9778141fa6ef0048c9569abd7ee0253bf.tar.bz2
Thread local bump pointer allocator.
Added a thread local allocator to the heap, each thread has three pointers which specify the thread local buffer: start, cur, and end. When the remaining space in the thread local buffer isn't large enough for the allocation, the allocator allocates a new thread local buffer using the bump pointer allocator. The bump pointer space had to be modified to accomodate thread local buffers. These buffers are called "blocks", where a block is a buffer which contains a set of adjacent objects. Blocks aren't necessarily full and may have wasted memory towards the end. Blocks have an 8 byte header which specifies their size and is required for traversing bump pointer spaces. Memory usage is in between full bump pointer and ROSAlloc since madvised memory limits wasted ram to an average of 1/2 page per block. Added a runtime option -XX:UseTLAB which specifies whether or not to use the thread local allocator. Its a NOP if the garbage collector is not the semispace collector. TODO: Smarter block accounting to prevent us reading objects until we either hit the end of the block or GetClass() == null which signifies that the block isn't 100% full. This would provide a slight speedup to BumpPointerSpace::Walk. Timings: -XX:HeapMinFree=4m -XX:HeapMaxFree=8m -Xmx48m ritzperf memalloc: Dalvik -Xgc:concurrent: 11678 Dalvik -Xgc:noconcurrent: 6697 -Xgc:MS: 5978 -Xgc:SS: 4271 -Xgc:CMS: 4150 -Xgc:SS -XX:UseTLAB: 3255 Bug: 9986565 Bug: 12042213 Change-Id: Ib7e1d4b199a8199f3b1de94b0a7b6e1730689cad
Diffstat (limited to 'runtime/gc/collector')
-rw-r--r--runtime/gc/collector/garbage_collector.cc2
-rw-r--r--runtime/gc/collector/semi_space.cc22
2 files changed, 4 insertions, 20 deletions
diff --git a/runtime/gc/collector/garbage_collector.cc b/runtime/gc/collector/garbage_collector.cc
index cf301fe..6baee54 100644
--- a/runtime/gc/collector/garbage_collector.cc
+++ b/runtime/gc/collector/garbage_collector.cc
@@ -83,9 +83,9 @@ void GarbageCollector::Run(bool clear_soft_references) {
uint64_t pause_start = NanoTime();
ATRACE_BEGIN("Application threads suspended");
thread_list->SuspendAll();
+ GetHeap()->RevokeAllThreadLocalBuffers();
MarkingPhase();
ReclaimPhase();
- GetHeap()->RevokeAllThreadLocalBuffers();
thread_list->ResumeAll();
ATRACE_END();
RegisterPause(NanoTime() - pause_start);
diff --git a/runtime/gc/collector/semi_space.cc b/runtime/gc/collector/semi_space.cc
index 923560e..f29eadb 100644
--- a/runtime/gc/collector/semi_space.cc
+++ b/runtime/gc/collector/semi_space.cc
@@ -14,22 +14,6 @@
* limitations under the License.
*/
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
#include "semi_space.h"
#include <functional>
@@ -337,7 +321,7 @@ Object* SemiSpace::MarkObject(Object* obj) {
if (forward_address == nullptr) {
// Otherwise, we need to move the object and add it to the markstack for processing.
size_t object_size = obj->SizeOf();
- size_t dummy = 0;
+ size_t bytes_allocated = 0;
if (kEnableSimplePromo && reinterpret_cast<byte*>(obj) < last_gc_to_space_end_) {
// If it's allocated before the last GC (older), move (pseudo-promote) it to
// the non-moving space (as sort of an old generation.)
@@ -346,7 +330,7 @@ Object* SemiSpace::MarkObject(Object* obj) {
forward_address = non_moving_space->Alloc(self_, object_size, &bytes_promoted);
if (forward_address == nullptr) {
// If out of space, fall back to the to-space.
- forward_address = to_space_->Alloc(self_, object_size, &dummy);
+ forward_address = to_space_->Alloc(self_, object_size, &bytes_allocated);
} else {
GetHeap()->num_bytes_allocated_.fetch_add(bytes_promoted);
bytes_promoted_ += bytes_promoted;
@@ -364,7 +348,7 @@ Object* SemiSpace::MarkObject(Object* obj) {
DCHECK(forward_address != nullptr);
} else {
// If it's allocated after the last GC (younger), copy it to the to-space.
- forward_address = to_space_->Alloc(self_, object_size, &dummy);
+ forward_address = to_space_->Alloc(self_, object_size, &bytes_allocated);
}
// Copy over the object and add it to the mark stack since we still need to update it's
// references.