OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "mojo/public/bindings/lib/buffer.h" | |
6 | |
7 #include <stdlib.h> | |
8 #include <string.h> | |
9 | |
10 #include <algorithm> | |
11 | |
12 namespace mojo { | |
13 | |
14 namespace { | |
viettrungluu
2013/10/09 03:44:06
(Note that the anonymous namespace is redundant, s
| |
15 const uint32_t kAlignment = 8U; | |
16 } // namespace | |
17 | |
18 //----------------------------------------------------------------------------- | |
19 | |
20 StackBuffer::StackBuffer() | |
21 : overflow_(NULL) { | |
22 fixed_.next = NULL; | |
23 fixed_.cursor = fixed_data_; | |
24 fixed_.end = fixed_data_ + kMinSegmentSize; | |
25 } | |
26 | |
27 StackBuffer::~StackBuffer() { | |
28 while (overflow_) { | |
29 Segment* doomed = overflow_; | |
30 overflow_ = overflow_->next; | |
31 free(doomed); | |
32 } | |
33 } | |
34 | |
35 void* StackBuffer::Allocate(uint32_t delta) { | |
36 if (delta % kAlignment) | |
37 delta += (kAlignment - (delta % kAlignment)); | |
38 | |
39 void* result = | |
40 AllocateInSegment((overflow_ != NULL) ? overflow_ : &fixed_, delta); | |
41 if (result) | |
42 return result; | |
43 | |
44 AddOverflowSegment(delta); | |
45 return Allocate(delta); | |
46 } | |
47 | |
48 void* StackBuffer::AllocateInSegment(Segment* segment, uint32_t delta) { | |
49 void* result; | |
50 if ((segment->end - segment->cursor) >= delta) { | |
51 result = segment->cursor; | |
52 memset(result, 0, delta); | |
53 segment->cursor += delta; | |
54 } else { | |
55 result = NULL; | |
56 } | |
57 return result; | |
58 } | |
59 | |
60 void StackBuffer::AddOverflowSegment(uint32_t delta) { | |
61 if (delta < kMinSegmentSize) | |
62 delta = kMinSegmentSize; | |
63 Segment* segment = static_cast<Segment*>(malloc(sizeof(Segment) + delta)); | |
64 segment->next = overflow_; | |
65 segment->cursor = reinterpret_cast<char*>(segment + 1); | |
66 segment->end = segment->cursor + delta; | |
67 overflow_ = segment; | |
68 } | |
69 | |
70 //----------------------------------------------------------------------------- | |
71 | |
72 ContiguousBuffer::ContiguousBuffer() | |
73 : ptr_(NULL), | |
74 size_(0), | |
75 capacity_(0) { | |
76 } | |
77 | |
78 ContiguousBuffer::~ContiguousBuffer() { | |
79 free(ptr_); | |
80 } | |
81 | |
82 void* ContiguousBuffer::Allocate(uint32_t delta) { | |
83 uint32_t old_size = size_; | |
84 uint32_t new_size = old_size + delta; | |
85 | |
86 if (new_size % kAlignment) | |
87 new_size += (kAlignment - (new_size % kAlignment)); | |
88 | |
89 const uint32_t kInitialCapacity = 512U; | |
90 uint32_t new_capacity = std::max(capacity_, kInitialCapacity); | |
91 while (new_capacity < new_size) | |
92 new_capacity <<= 1; | |
93 | |
94 if (new_capacity != capacity_) { | |
95 ptr_ = static_cast<char*>(realloc(ptr_, new_capacity)); | |
96 // TODO: only memset what gets used | |
97 memset(ptr_ + capacity_, 0, new_capacity - capacity_); | |
98 capacity_ = new_capacity; | |
99 } | |
100 | |
101 size_ = new_size; | |
102 return ptr_ + old_size; | |
103 } | |
104 | |
105 void* ContiguousBuffer::Leak() { | |
106 char* ptr = ptr_; | |
107 ptr_ = NULL; | |
108 size_ = 0; | |
109 return ptr; | |
110 } | |
111 | |
112 } // namespace mojo | |
OLD | NEW |