blob: bbdf80a1818b27162462abed56c3c3112c034e4f [file] [log] [blame]
Carl Shapiro69759ea2011-07-21 18:13:35 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2// Author: cshapiro@google.com (Carl Shapiro)
3
4#include "src/heap.h"
5#include "src/object.h"
6#include "src/space.h"
7
8namespace art {
9
10Space* Heap::space_ = NULL;
11
12size_t Heap::startup_size_ = 0;
13
14size_t Heap::maximum_size_ = 0;
15
16bool Heap::is_gc_running_ = false;
17
18HeapBitmap* Heap::mark_bitmap_ = NULL;
19
20HeapBitmap* Heap::live_bitmap_ = NULL;
21
22bool Heap::Init(size_t startup_size, size_t maximum_size) {
23 space_ = Space::Create(startup_size, maximum_size);
24 if (space_ == NULL) {
25 return false;
26 }
27
28 byte* base = space_->GetBase();
29 size_t num_bytes = space_->Size();
30
31 // Allocate the initial live bitmap.
32 scoped_ptr<HeapBitmap> live_bitmap(HeapBitmap::Create(base, num_bytes));
33 if (live_bitmap == NULL) {
34 return false;
35 }
36
37 // Allocate the initial mark bitmap.
38 scoped_ptr<HeapBitmap> mark_bitmap(HeapBitmap::Create(base, num_bytes));
39 if (mark_bitmap == NULL) {
40 return false;
41 }
42
43 startup_size_ = startup_size;
44 maximum_size_ = maximum_size;
45 live_bitmap_ = live_bitmap.release();
46 mark_bitmap_ = mark_bitmap.release();
47
48 // TODO: allocate the card table
49
50 return true;
51}
52
53void Heap::Destroy() {
54 delete space_;
55 delete mark_bitmap_;
56 delete live_bitmap_;
57}
58
59Object* Heap::Allocate(size_t size) {
60 // Fail impossible allocations. TODO: collect soft references.
61 if (size > maximum_size_) {
62 return NULL;
63 }
64
65 Object* ptr = space_->AllocWithoutGrowth(size);
66 if (ptr != NULL) {
67 return ptr;
68 }
69
70 // The allocation failed. If the GC is running, block until it
71 // completes and retry.
72 if (is_gc_running_) {
73 // The GC is concurrently tracing the heap. Release the heap
74 // lock, wait for the GC to complete, and retrying allocating.
75 WaitForConcurrentGcToComplete();
76 ptr = space_->AllocWithoutGrowth(size);
77 if (ptr != NULL) {
78 return ptr;
79 }
80 }
81
82 // Another failure. Our thread was starved or there may be too many
83 // live objects. Try a foreground GC. This will have no effect if
84 // the concurrent GC is already running.
85 CollectGarbage();
86 ptr = space_->AllocWithoutGrowth(size);
87 if (ptr != NULL) {
88 return ptr;
89 }
90
91 // Even that didn't work; this is an exceptional state.
92 // Try harder, growing the heap if necessary.
93 ptr = space_->AllocWithGrowth(size);
94 if (ptr != NULL) {
95 //size_t new_footprint = dvmHeapSourceGetIdealFootprint();
96 size_t new_footprint = space_->MaxAllowedFootprint();
97 //TODO: may want to grow a little bit more so that the amount of free
98 // space is equal to the old free space + the utilization slop for
99 // the new allocation.
100 // LOGI_HEAP("Grow heap (frag case) to "
101 // "%zu.%03zuMB for %zu-byte allocation",
102 // FRACTIONAL_MB(newHeapSize), size);
103 LOG(INFO) << "Grow heap (frag case) to " << new_footprint
104 << "for " << size << "-byte allocation";
105 return ptr;
106 }
107
108 // Most allocations should have succeeded by now, so the heap is
109 // really full, really fragmented, or the requested size is really
110 // big. Do another GC, collecting SoftReferences this time. The VM
111 // spec requires that all SoftReferences have been collected and
112 // cleared before throwing an OOME.
113
114 //TODO: wait for the finalizers from the previous GC to finish
115 //collect_soft_refs:
116 LOG(INFO) << "Forcing collection of SoftReferences for "
117 << size << "-byte allocation";
118 //gcForMalloc(true);
119 CollectGarbage();
120 ptr = space_->AllocWithGrowth(size);
121 if (ptr != NULL) {
122 return ptr;
123 }
124 //TODO: maybe wait for finalizers and try one last time
125
126 //LOGE_HEAP("Out of memory on a %zd-byte allocation.", size);
127 LOG(ERROR) << "Out of memory on a " << size << " byte allocation";
128
129 //TODO: tell the HeapSource to dump its state
130 //dvmDumpThread(dvmThreadSelf(), false);
131
132 // TODO: stack trace
133 return NULL;
134}
135
136String* Heap::AllocStringFromModifiedUtf8(Class* java_lang_String,
137 Class* char_array,
138 const char* data) {
139 String* string = AllocString(java_lang_String);
140 uint32_t count = strlen(data); // TODO
141 CharArray* array = AllocCharArray(char_array, count);
142 string->array_ = array;
143 string->count_ = count;
144 return string;
145}
146
147void Heap::CollectGarbage() {
148}
149
150void Heap::CollectGarbageInternal() {
151}
152
153void Heap::WaitForConcurrentGcToComplete() {
154}
155
156// Given the current contents of the active heap, increase the allowed
157// heap footprint to match the target utilization ratio. This should
158// only be called immediately after a full garbage collection.
159void Heap::GrowForUtilization() {
160 LOG(FATAL) << "Unimplemented";
161}
162
163} // namespace art