Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(863)

Unified Diff: runtime/vm/zone.cc

Issue 2762323002: Reimplemented zone memory tracking to avoid race conditions that were causing crashes in the previo… (Closed)
Patch Set: Final change Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/zone.h ('k') | runtime/vm/zone_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/zone.cc
diff --git a/runtime/vm/zone.cc b/runtime/vm/zone.cc
index 8b3cdac905faf210905786168a660c3c15e65329..9bbc8eb6b3ebabc8d4fc8fb39cd2e77035c970f7 100644
--- a/runtime/vm/zone.cc
+++ b/runtime/vm/zone.cc
@@ -28,6 +28,8 @@ class Zone::Segment {
// Allocate or delete individual segments.
static Segment* New(intptr_t size, Segment* next);
static void DeleteSegmentList(Segment* segment);
+ static void IncrementMemoryCapacity(uintptr_t size);
+ static void DecrementMemoryCapacity(uintptr_t size);
private:
Segment* next_;
@@ -42,16 +44,28 @@ class Zone::Segment {
};
+Zone::Segment* Zone::Segment::New(intptr_t size, Zone::Segment* next) {
+ ASSERT(size >= 0);
+ Segment* result = reinterpret_cast<Segment*>(malloc(size));
+ if (result == NULL) {
+ OUT_OF_MEMORY();
+ }
+ ASSERT(Utils::IsAligned(result->start(), Zone::kAlignment));
+#ifdef DEBUG
+ // Zap the entire allocated segment (including the header).
+ memset(result, kZapUninitializedByte, size);
+#endif
+ result->next_ = next;
+ result->size_ = size;
+ IncrementMemoryCapacity(size);
+ return result;
+}
+
+
void Zone::Segment::DeleteSegmentList(Segment* head) {
Segment* current = head;
- Thread* current_thread = Thread::Current();
while (current != NULL) {
- if (current_thread != NULL) {
- current_thread->DecrementMemoryUsage(current->size());
- } else if (ApiNativeScope::Current() != NULL) {
- // If there is no current thread, we might be inside of a native scope.
- ApiNativeScope::DecrementNativeScopeMemoryUsage(current->size());
- }
+ DecrementMemoryCapacity(current->size());
Segment* next = current->next();
#ifdef DEBUG
// Zap the entire current segment (including the header).
@@ -63,29 +77,28 @@ void Zone::Segment::DeleteSegmentList(Segment* head) {
}
-Zone::Segment* Zone::Segment::New(intptr_t size, Zone::Segment* next) {
- ASSERT(size >= 0);
- Segment* result = reinterpret_cast<Segment*>(malloc(size));
- if (result == NULL) {
- OUT_OF_MEMORY();
+void Zone::Segment::IncrementMemoryCapacity(uintptr_t size) {
+ Thread* current_thread = Thread::Current();
+ if (current_thread != NULL) {
+ current_thread->IncrementMemoryCapacity(size);
+ } else if (ApiNativeScope::Current() != NULL) {
+ // If there is no current thread, we might be inside of a native scope.
+ ApiNativeScope::IncrementNativeScopeMemoryCapacity(size);
}
- ASSERT(Utils::IsAligned(result->start(), Zone::kAlignment));
-#ifdef DEBUG
- // Zap the entire allocated segment (including the header).
- memset(result, kZapUninitializedByte, size);
-#endif
- result->next_ = next;
- result->size_ = size;
- Thread* current = Thread::Current();
- if (current != NULL) {
- current->IncrementMemoryUsage(size);
+}
+
+
+void Zone::Segment::DecrementMemoryCapacity(uintptr_t size) {
+ Thread* current_thread = Thread::Current();
+ if (current_thread != NULL) {
+ current_thread->DecrementMemoryCapacity(size);
} else if (ApiNativeScope::Current() != NULL) {
// If there is no current thread, we might be inside of a native scope.
- ApiNativeScope::IncrementNativeScopeMemoryUsage(size);
+ ApiNativeScope::DecrementNativeScopeMemoryCapacity(size);
}
- return result;
}
+
// TODO(bkonyi): We need to account for the initial chunk size when a new zone
// is created within a new thread or ApiNativeScope when calculating high
// watermarks or memory consumption.
@@ -98,10 +111,7 @@ Zone::Zone()
handles_(),
previous_(NULL) {
ASSERT(Utils::IsAligned(position_, kAlignment));
- Thread* current = Thread::Current();
- if (current != NULL) {
- current->IncrementMemoryUsage(kInitialChunkSize);
- }
+ Segment::IncrementMemoryCapacity(kInitialChunkSize);
#ifdef DEBUG
// Zap the entire initial buffer.
memset(initial_buffer_.pointer(), kZapUninitializedByte,
@@ -114,11 +124,8 @@ Zone::~Zone() {
if (FLAG_trace_zones) {
DumpZoneSizes();
}
- Thread* current = Thread::Current();
- if (current != NULL) {
- current->DecrementMemoryUsage(kInitialChunkSize);
- }
DeleteAll();
+ Segment::DecrementMemoryCapacity(kInitialChunkSize);
}
@@ -144,8 +151,8 @@ void Zone::DeleteAll() {
}
-intptr_t Zone::SizeInBytes() const {
- intptr_t size = 0;
+uintptr_t Zone::SizeInBytes() const {
+ uintptr_t size = 0;
for (Segment* s = large_segments_; s != NULL; s = s->next()) {
size += s->size();
}
@@ -160,8 +167,8 @@ intptr_t Zone::SizeInBytes() const {
}
-intptr_t Zone::CapacityInBytes() const {
- intptr_t size = 0;
+uintptr_t Zone::CapacityInBytes() const {
+ uintptr_t size = 0;
for (Segment* s = large_segments_; s != NULL; s = s->next()) {
size += s->size();
}
@@ -300,19 +307,6 @@ char* Zone::VPrint(const char* format, va_list args) {
}
-#ifndef PRODUCT
-// TODO(bkonyi): Currently dead code. See issue #28885.
-void Zone::PrintJSON(JSONStream* stream) const {
- JSONObject jsobj(stream);
- intptr_t capacity = CapacityInBytes();
- intptr_t used_size = SizeInBytes();
- jsobj.AddProperty("type", "_Zone");
- jsobj.AddProperty("capacity", capacity);
- jsobj.AddProperty("used", used_size);
-}
-#endif
-
-
StackZone::StackZone(Thread* thread) : StackResource(thread), zone_() {
if (FLAG_trace_zones) {
OS::PrintErr("*** Starting a new Stack zone 0x%" Px "(0x%" Px ")\n",
« no previous file with comments | « runtime/vm/zone.h ('k') | runtime/vm/zone_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698