OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "mojo/public/cpp/bindings/lib/scratch_buffer.h" | 5 #include "mojo/public/cpp/bindings/lib/scratch_buffer.h" |
6 | 6 |
7 #include <assert.h> | 7 #include <assert.h> |
8 #include <stdlib.h> | 8 #include <stdlib.h> |
9 #include <string.h> | 9 #include <string.h> |
10 | 10 |
(...skipping 28 matching lines...) Expand all Loading... | |
39 Segment* doomed = overflow_; | 39 Segment* doomed = overflow_; |
40 overflow_ = overflow_->next; | 40 overflow_ = overflow_->next; |
41 DEBUG_SCRUB(doomed, doomed->end - reinterpret_cast<char*>(doomed)); | 41 DEBUG_SCRUB(doomed, doomed->end - reinterpret_cast<char*>(doomed)); |
42 free(doomed); | 42 free(doomed); |
43 } | 43 } |
44 DEBUG_SCRUB(fixed_data_, sizeof(fixed_data_)); | 44 DEBUG_SCRUB(fixed_data_, sizeof(fixed_data_)); |
45 } | 45 } |
46 | 46 |
47 void* ScratchBuffer::Allocate(size_t delta, Destructor func) { | 47 void* ScratchBuffer::Allocate(size_t delta, Destructor func) { |
48 delta = internal::Align(delta); | 48 delta = internal::Align(delta); |
49 void* result = AllocateInSegment(&fixed_, delta); | |
50 if (!result && overflow_) | |
51 result = AllocateInSegment(overflow_, delta); | |
49 | 52 |
50 void* result = AllocateInSegment(&fixed_, delta); | 53 if (!result && AddOverflowSegment(delta)) |
51 if (!result) { | 54 result = AllocateInSegment(overflow_, delta); |
52 if (overflow_) | |
53 result = AllocateInSegment(overflow_, delta); | |
54 | 55 |
55 if (!result) { | 56 if (func && result) { |
darin (slow to review)
2014/04/09 04:52:42
I'm pretty sure the bindings don't respond kindly
| |
56 AddOverflowSegment(delta); | |
57 result = AllocateInSegment(overflow_, delta); | |
58 } | |
59 } | |
60 | |
61 if (func) { | |
62 PendingDestructor dtor; | 57 PendingDestructor dtor; |
63 dtor.func = func; | 58 dtor.func = func; |
64 dtor.address = result; | 59 dtor.address = result; |
65 pending_dtors_.push_back(dtor); | 60 pending_dtors_.push_back(dtor); |
66 } | 61 } |
67 return result; | 62 return result; |
68 } | 63 } |
69 | 64 |
70 void* ScratchBuffer::AllocateInSegment(Segment* segment, size_t delta) { | 65 void* ScratchBuffer::AllocateInSegment(Segment* segment, size_t delta) { |
71 void* result; | |
72 if (static_cast<size_t>(segment->end - segment->cursor) >= delta) { | 66 if (static_cast<size_t>(segment->end - segment->cursor) >= delta) { |
73 result = segment->cursor; | 67 void* result = segment->cursor; |
74 memset(result, 0, delta); | 68 memset(result, 0, delta); // Required to avoid info leaks. |
75 segment->cursor += delta; | 69 segment->cursor += delta; |
76 } else { | 70 return result; |
77 result = NULL; | |
78 } | 71 } |
79 return result; | 72 return NULL; |
80 } | 73 } |
81 | 74 |
82 void ScratchBuffer::AddOverflowSegment(size_t delta) { | 75 bool ScratchBuffer::AddOverflowSegment(size_t delta) { |
83 if (delta < kMinSegmentSize) | 76 if (delta < kMinSegmentSize) |
84 delta = kMinSegmentSize; | 77 delta = kMinSegmentSize; |
85 | 78 |
79 if (delta > kMaxSegmentSize) | |
80 return false; | |
81 | |
86 // Ensure segment buffer is aligned. | 82 // Ensure segment buffer is aligned. |
87 size_t segment_size = internal::Align(sizeof(Segment)) + delta; | 83 size_t segment_size = internal::Align(sizeof(Segment)) + delta; |
84 Segment* segment = static_cast<Segment*>(malloc(segment_size)); | |
85 if (segment) { | |
darin (slow to review)
2014/04/09 04:52:42
I guess you are doing this because this code shoul
| |
86 segment->next = overflow_; | |
87 segment->cursor = reinterpret_cast<char*>(segment + 1); | |
88 segment->end = segment->cursor + delta; | |
89 overflow_ = segment; | |
90 return true; | |
91 } | |
88 | 92 |
89 Segment* segment = static_cast<Segment*>(malloc(segment_size)); | 93 return false; |
90 segment->next = overflow_; | |
91 segment->cursor = reinterpret_cast<char*>(segment + 1); | |
92 segment->end = segment->cursor + delta; | |
93 | |
94 overflow_ = segment; | |
95 } | 94 } |
96 | 95 |
97 } // namespace internal | 96 } // namespace internal |
98 } // namespace mojo | 97 } // namespace mojo |
OLD | NEW |