Index: runtime/vm/scavenger.h |
diff --git a/runtime/vm/scavenger.h b/runtime/vm/scavenger.h |
index 8d8c0e49e3fa121840f8d51ba958548d3c5401b9..a50f072e9d6241440770e70271e366c3b9094009 100644 |
--- a/runtime/vm/scavenger.h |
+++ b/runtime/vm/scavenger.h |
@@ -126,21 +126,49 @@ class Scavenger { |
uword TryAllocate(intptr_t size) { |
ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
ASSERT(heap_ != Dart::vm_isolate()->heap()); |
+ |
#if defined(DEBUG) |
if (FLAG_gc_at_alloc && !scavenging_) { |
Scavenge(); |
} |
#endif |
- uword result = top_; |
- intptr_t remaining = end_ - top_; |
- if (remaining < size) { |
+ |
+ Thread* thread = Thread::Current(); |
rmacnak
2017/07/05 17:39:53
This will hurt DBC as TLS is expensive. Pass in th
danunez
2017/07/05 18:12:55
I will do this as part of a separate function, as
|
+ uword top = 0; |
+ uword end = 0; |
+ |
+ if (!thread->IsMutatorThread()) { |
+ thread = Isolate::Current()->mutator_thread(); |
rmacnak
2017/07/05 17:39:53
We cannot access state on another Thread outside o
danunez
2017/07/05 18:12:56
Can't the background thread trigger a full heap GC
|
+ } |
+ |
+ if (thread->heap() != NULL) { |
rmacnak
2017/07/05 17:39:53
This shouldn't be possible unless we haven't corre
danunez
2017/07/05 18:12:56
This happens if the mutator is unscheduled, but th
|
+ top = thread->top(); |
+ end = thread->end(); |
+ } else { |
+ top = top_; |
+ end = end_; |
+ } |
+ |
+ uword result = top; |
+ intptr_t remaining = end - top; |
+ if ((remaining < size) || (CapacityInWords() == 0)) { |
rmacnak
2017/07/05 17:39:53
Why is the second check needed? Only the VM isolat
danunez
2017/07/05 18:12:56
Correct. There is exactly one test that checks the
|
return 0; |
} |
ASSERT(to_->Contains(result)); |
ASSERT((result & kObjectAlignmentMask) == object_alignment_); |
- top_ += size; |
- ASSERT(to_->Contains(top_) || (top_ == to_->end())); |
+ top += size; |
+ ASSERT(to_->Contains(top) || (top == to_->end())); |
+ |
+ if (thread->heap() != NULL) { |
+ thread->set_top_offset(top); |
+ } else { |
+ top_ = top; |
+ } |
+ // We only want to change top_ if mutator is scheduled and therefore |
+ // has a heap attached. |
+ |
+ |
return result; |
} |
@@ -158,8 +186,6 @@ class Scavenger { |
// Accessors to generate code for inlined allocation. |
uword* TopAddress() { return &top_; } |
uword* EndAddress() { return &end_; } |
- static intptr_t top_offset() { return OFFSET_OF(Scavenger, top_); } |
- static intptr_t end_offset() { return OFFSET_OF(Scavenger, end_); } |
int64_t UsedInWords() const { |
return (top_ - FirstObjectStart()) >> kWordSizeLog2; |
@@ -235,20 +261,75 @@ class Scavenger { |
// not consume space in the to space they leave enough room for this stack. |
void PushToPromotedStack(uword addr) { |
rmacnak
2017/07/05 17:39:53
Promo stack:
During a scavenge, we should be usin
danunez
2017/07/05 18:12:56
I do not recall why I changed this to use TLS. I w
|
ASSERT(scavenging_); |
- end_ -= sizeof(addr); |
- ASSERT(end_ > top_); |
- *reinterpret_cast<uword*>(end_) = addr; |
+ |
+ uword top = 0; |
+ uword end = 0; |
+ Thread* thread = Thread::Current(); |
+ if (!thread->IsMutatorThread()) { |
+ thread = Isolate::Current()->mutator_thread(); |
+ } |
+ |
+ if (thread->heap() != NULL) { |
+ top = thread->top(); |
+ end = thread->end(); |
+ } else { |
+ top = top_; |
+ end = end_; |
+ } |
+ |
+ end -= sizeof(addr); |
+ |
+ if (thread->heap() != NULL) { |
+ thread->set_end_offset(end); |
+ } else { |
+ end_ = end; |
+ } |
+ |
+ ASSERT(end > top); |
+ *reinterpret_cast<uword*>(end) = addr; |
} |
uword PopFromPromotedStack() { |
ASSERT(scavenging_); |
- uword result = *reinterpret_cast<uword*>(end_); |
- end_ += sizeof(result); |
- ASSERT(end_ <= to_->end()); |
+ |
+ uword end = 0; |
+ Thread* thread = Thread::Current(); |
+ if (!thread->IsMutatorThread()) { |
+ thread = Isolate::Current()->mutator_thread(); |
+ } |
+ |
+ if (thread->heap() != NULL) { |
+ end = thread->end(); |
+ } else { |
+ end = end_; |
+ } |
+ |
+ uword result = *reinterpret_cast<uword*>(end); |
+ end += sizeof(result); |
+ |
+ if (thread->heap() != NULL) { |
+ thread->set_end_offset(end); |
+ } else { |
+ end_ = end; |
+ } |
+ |
+ ASSERT(end <= to_->end()); |
return result; |
} |
bool PromotedStackHasMore() const { |
ASSERT(scavenging_); |
- return end_ < to_->end(); |
+ uword end = 0; |
+ Thread* thread = Thread::Current(); |
+ if (!thread->IsMutatorThread()) { |
+ thread = Isolate::Current()->mutator_thread(); |
+ } |
+ |
+ if (thread->heap() != NULL) { |
+ end = thread->end(); |
+ } else { |
+ end = end_; |
+ } |
+ |
+ return end < to_->end(); |
} |
void UpdateMaxHeapCapacity(); |
@@ -297,6 +378,8 @@ class Scavenger { |
// The total size of external data associated with objects in this scavenger. |
intptr_t external_size_; |
+ Mutex* space_lock_; |
rmacnak
2017/07/05 17:39:53
Add a comment describing what this lock protects.
danunez
2017/07/05 18:12:56
I will remove the lock for now. It has no purpose
|
+ |
friend class ScavengerVisitor; |
friend class ScavengerWeakVisitor; |