summaryrefslogtreecommitdiffstats
path: root/courgette/memory_allocator.cc
diff options
context:
space:
mode:
authortommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-06 17:42:45 +0000
committertommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-06 17:42:45 +0000
commit43a9e24a52fa867db98fc2195b8db85b4729e7a1 (patch)
treecad7a14c415542083ac3d1ecc2df1fd86f789557 /courgette/memory_allocator.cc
parent6768ac0b06ae36ec7b2d27adfb9b64fc17f57cee (diff)
downloadchromium_src-43a9e24a52fa867db98fc2195b8db85b4729e7a1.zip
chromium_src-43a9e24a52fa867db98fc2195b8db85b4729e7a1.tar.gz
chromium_src-43a9e24a52fa867db98fc2195b8db85b4729e7a1.tar.bz2
Switch out use of std::string and std::vector for large allocations for a buffer class that doesn't throw exceptions.
The new buffer class is pretty simple and relies on the MemoryAllocator class that I previously to back large allocations with mapped files when memory is scarce. That reduced the number of crashes quite a bit but we still crash on machines that are simply out of diskspace as well. So, the right thing to do is to expect and handle failures which is what this cl is all about. What we should see once this has landed is that crash dumps due to courgette running out of disk space should disappear from crash/ and instead we should see the number of users that run into this particular problem in dashboards. TEST=Courgette out-of-memory/out-of-diskspace errors should disappear from crash/ BUG=74777 Review URL: http://codereview.chromium.org/6677141 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@80648 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'courgette/memory_allocator.cc')
-rw-r--r--courgette/memory_allocator.cc75
1 files changed, 33 insertions, 42 deletions
diff --git a/courgette/memory_allocator.cc b/courgette/memory_allocator.cc
index d45d053..f2aed22 100644
--- a/courgette/memory_allocator.cc
+++ b/courgette/memory_allocator.cc
@@ -11,46 +11,30 @@
#ifdef OS_WIN
-// A helper function to help diagnose failures we've seen in the field.
-// The function constructs a string containing the error and throws a runtime
-// exception. The calling convention is set to stdcall to force argument
-// passing via the stack.
-__declspec(noinline)
-void __stdcall RuntimeError(DWORD err) {
- char buffer[20] = {0};
- wsprintfA(buffer, "err: %u", err);
- throw buffer;
-}
-
namespace courgette {
// TempFile
-TempFile::TempFile() : file_(base::kInvalidPlatformFileValue), size_(0) {
+TempFile::TempFile() : file_(base::kInvalidPlatformFileValue) {
}
TempFile::~TempFile() {
Close();
}
-FilePath TempFile::PrepareTempFile() {
- FilePath path;
- if (!file_util::CreateTemporaryFile(&path))
- RuntimeError(::GetLastError());
- return path;
-}
-
void TempFile::Close() {
if (valid()) {
base::ClosePlatformFile(file_);
file_ = base::kInvalidPlatformFileValue;
- size_ = 0;
}
}
-void TempFile::Create() {
+bool TempFile::Create() {
DCHECK(file_ == base::kInvalidPlatformFileValue);
- FilePath path(PrepareTempFile());
+ FilePath path;
+ if (!file_util::CreateTemporaryFile(&path))
+ return false;
+
bool created = false;
base::PlatformFileError error_code = base::PLATFORM_FILE_OK;
int flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_READ |
@@ -59,7 +43,9 @@ void TempFile::Create() {
base::PLATFORM_FILE_TEMPORARY;
file_ = base::CreatePlatformFile(path, flags, &created, &error_code);
if (file_ == base::kInvalidPlatformFileValue)
- RuntimeError(error_code);
+ return false;
+
+ return true;
}
bool TempFile::valid() const {
@@ -70,15 +56,8 @@ base::PlatformFile TempFile::handle() const {
return file_;
}
-size_t TempFile::size() const {
- return size_;
-}
-
-void TempFile::SetSize(size_t size) {
- bool set = base::TruncatePlatformFile(file_, size);
- if (!set)
- RuntimeError(::GetLastError());
- size_ = size;
+bool TempFile::SetSize(size_t size) {
+ return base::TruncatePlatformFile(file_, size);
}
// FileMapping
@@ -90,22 +69,25 @@ FileMapping::~FileMapping() {
Close();
}
-void FileMapping::InitializeView(size_t size) {
+bool FileMapping::InitializeView(size_t size) {
DCHECK(view_ == NULL);
DCHECK(mapping_ != NULL);
view_ = ::MapViewOfFile(mapping_, FILE_MAP_WRITE, 0, 0, size);
- if (!view_)
- RuntimeError(::GetLastError());
+ if (!view_) {
+ Close();
+ return false;
+ }
+ return true;
}
-void FileMapping::Create(HANDLE file, size_t size) {
+bool FileMapping::Create(HANDLE file, size_t size) {
DCHECK(file != INVALID_HANDLE_VALUE);
DCHECK(!valid());
mapping_ = ::CreateFileMapping(file, NULL, PAGE_READWRITE, 0, 0, NULL);
if (!mapping_)
- RuntimeError(::GetLastError());
+ return false;
- InitializeView(size);
+ return InitializeView(size);
}
void FileMapping::Close() {
@@ -133,17 +115,22 @@ TempMapping::TempMapping() {
TempMapping::~TempMapping() {
}
-void TempMapping::Initialize(size_t size) {
+bool TempMapping::Initialize(size_t size) {
// TODO(tommi): The assumption here is that the alignment of pointers (this)
// is as strict or stricter than the alignment of the element type. This is
// not always true, e.g. __m128 has 16-byte alignment.
size += sizeof(this);
- file_.Create();
- file_.SetSize(size);
- mapping_.Create(file_.handle(), size);
+ if (!file_.Create() ||
+ !file_.SetSize(size) ||
+ !mapping_.Create(file_.handle(), size)) {
+ file_.Close();
+ return false;
+ }
TempMapping** write = reinterpret_cast<TempMapping**>(mapping_.view());
write[0] = this;
+
+ return true;
}
void* TempMapping::memory() const {
@@ -154,6 +141,10 @@ void* TempMapping::memory() const {
return mem;
}
+bool TempMapping::valid() const {
+ return mapping_.valid();
+}
+
// static
TempMapping* TempMapping::GetMappingFromPtr(void* mem) {
TempMapping* ret = NULL;