Index: runtime/vm/scavenger.h |
diff --git a/runtime/vm/scavenger.h b/runtime/vm/scavenger.h |
index 82e9adc4badf3b5f1eb2aa1aac4a89cf24f4eaf0..1fd7c9fe2bd88b93e8f26e2c6b7964e11a0408bc 100644 |
--- a/runtime/vm/scavenger.h |
+++ b/runtime/vm/scavenger.h |
@@ -121,24 +121,46 @@ class Scavenger { |
RawObject* FindObject(FindObjectVisitor* visitor) const; |
- uword TryAllocate(intptr_t size) { |
+ uword AllocateGC(intptr_t size) { |
ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
ASSERT(heap_ != Dart::vm_isolate()->heap()); |
+ ASSERT(scavenging_); |
+ uword result = top_; |
+ intptr_t remaining = end_ - top_; |
+ |
+ // This allocation happens only in GC and only when copying objects to |
+ // the new to_ space. It must succeed. |
+ ASSERT(size <= remaining); |
+ ASSERT(to_->Contains(result)); |
+ ASSERT((result & kObjectAlignmentMask) == object_alignment_); |
+ top_ += size; |
+ ASSERT(to_->Contains(top_) || (top_ == to_->end())); |
+ return result; |
+ } |
+ |
+ uword TryAllocateInTLAB(Thread* thread, intptr_t size) { |
+ ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
+ ASSERT(heap_ != Dart::vm_isolate()->heap()); |
+ ASSERT(thread->IsMutatorThread()); |
+ ASSERT(thread->isolate()->IsMutatorThreadScheduled()); |
#if defined(DEBUG) |
- if (FLAG_gc_at_alloc && !scavenging_) { |
+ if (FLAG_gc_at_alloc) { |
+ ASSERT(!scavenging_); |
Scavenge(); |
} |
#endif |
- uword result = top_; |
- intptr_t remaining = end_ - top_; |
+ uword top = thread->top(); |
+ uword end = thread->end(); |
+ uword result = top; |
+ intptr_t remaining = end - top; |
if (remaining < size) { |
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())); |
+ thread->set_top(top); |
return result; |
} |
@@ -149,11 +171,14 @@ class Scavenger { |
// Promote all live objects. |
void Evacuate(); |
- // 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_); } |
+ uword top() { return top_; } |
+ uword end() { return end_; } |
+ |
+ void set_top(uword value) { top_ = value; } |
+ void set_end(uword value) { |
+ ASSERT(to_->end() == value); |
+ end_ = value; |
+ } |
int64_t UsedInWords() const { |
return (top_ - FirstObjectStart()) >> kWordSizeLog2; |
@@ -190,6 +215,8 @@ class Scavenger { |
void AllocateExternal(intptr_t size); |
void FreeExternal(intptr_t size); |
+ void FlushTLS() const; |
+ |
private: |
// Ids for time and data records in Heap::GCStats. |
enum { |
@@ -252,12 +279,6 @@ class Scavenger { |
intptr_t NewSizeInWords(intptr_t old_size_in_words) const; |
- // Accessed from generated code. |
- // ** This block of fields must come first! ** |
- // For AOT cross-compilation, we rely on these members having the same offsets |
- // in SIMARM(IA32) and ARM, and the same offsets in SIMARM64(X64) and ARM64. |
- // We use only word-sized fields to avoid differences in struct packing on the |
- // different architectures. See also CheckOffsets in dart.cc. |
uword top_; |
uword end_; |