blob: d74c37cd799499b32fe053fa5ceb2b1476547983 [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// Copyright 2008 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include <stdlib.h>
29
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080030#include "../include/v8stdint.h"
31#include "globals.h"
32#include "checks.h"
33#include "allocation.h"
34#include "utils.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000035
36namespace v8 {
37namespace internal {
38
Steve Blocka7e24c12009-10-30 11:49:00 +000039void* Malloced::New(size_t size) {
40 ASSERT(NativeAllocationChecker::allocation_allowed());
41 void* result = malloc(size);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080042 if (result == NULL) {
43 v8::internal::FatalProcessOutOfMemory("Malloced operator new");
44 }
Steve Blocka7e24c12009-10-30 11:49:00 +000045 return result;
46}
47
48
49void Malloced::Delete(void* p) {
50 free(p);
51}
52
53
54void Malloced::FatalProcessOutOfMemory() {
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080055 v8::internal::FatalProcessOutOfMemory("Out of memory");
Steve Blocka7e24c12009-10-30 11:49:00 +000056}
57
58
59#ifdef DEBUG
60
61static void* invalid = static_cast<void*>(NULL);
62
63void* Embedded::operator new(size_t size) {
64 UNREACHABLE();
65 return invalid;
66}
67
68
69void Embedded::operator delete(void* p) {
70 UNREACHABLE();
71}
72
73
74void* AllStatic::operator new(size_t size) {
75 UNREACHABLE();
76 return invalid;
77}
78
79
80void AllStatic::operator delete(void* p) {
81 UNREACHABLE();
82}
83
84#endif
85
86
87char* StrDup(const char* str) {
Steve Blockd0582a62009-12-15 09:54:21 +000088 int length = StrLength(str);
Steve Blocka7e24c12009-10-30 11:49:00 +000089 char* result = NewArray<char>(length + 1);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080090 memcpy(result, str, length);
Steve Blocka7e24c12009-10-30 11:49:00 +000091 result[length] = '\0';
92 return result;
93}
94
95
Steve Blockd0582a62009-12-15 09:54:21 +000096char* StrNDup(const char* str, int n) {
97 int length = StrLength(str);
Steve Blocka7e24c12009-10-30 11:49:00 +000098 if (n < length) length = n;
99 char* result = NewArray<char>(length + 1);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800100 memcpy(result, str, length);
Steve Blocka7e24c12009-10-30 11:49:00 +0000101 result[length] = '\0';
102 return result;
103}
104
105
106int NativeAllocationChecker::allocation_disallowed_ = 0;
107
108
109PreallocatedStorage PreallocatedStorage::in_use_list_(0);
110PreallocatedStorage PreallocatedStorage::free_list_(0);
111bool PreallocatedStorage::preallocated_ = false;
112
113
114void PreallocatedStorage::Init(size_t size) {
115 ASSERT(free_list_.next_ == &free_list_);
116 ASSERT(free_list_.previous_ == &free_list_);
117 PreallocatedStorage* free_chunk =
118 reinterpret_cast<PreallocatedStorage*>(new char[size]);
119 free_list_.next_ = free_list_.previous_ = free_chunk;
120 free_chunk->next_ = free_chunk->previous_ = &free_list_;
121 free_chunk->size_ = size - sizeof(PreallocatedStorage);
122 preallocated_ = true;
123}
124
125
126void* PreallocatedStorage::New(size_t size) {
127 if (!preallocated_) {
128 return FreeStoreAllocationPolicy::New(size);
129 }
130 ASSERT(free_list_.next_ != &free_list_);
131 ASSERT(free_list_.previous_ != &free_list_);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800132
Steve Blocka7e24c12009-10-30 11:49:00 +0000133 size = (size + kPointerSize - 1) & ~(kPointerSize - 1);
134 // Search for exact fit.
135 for (PreallocatedStorage* storage = free_list_.next_;
136 storage != &free_list_;
137 storage = storage->next_) {
138 if (storage->size_ == size) {
139 storage->Unlink();
140 storage->LinkTo(&in_use_list_);
141 return reinterpret_cast<void*>(storage + 1);
142 }
143 }
144 // Search for first fit.
145 for (PreallocatedStorage* storage = free_list_.next_;
146 storage != &free_list_;
147 storage = storage->next_) {
148 if (storage->size_ >= size + sizeof(PreallocatedStorage)) {
149 storage->Unlink();
150 storage->LinkTo(&in_use_list_);
151 PreallocatedStorage* left_over =
152 reinterpret_cast<PreallocatedStorage*>(
153 reinterpret_cast<char*>(storage + 1) + size);
154 left_over->size_ = storage->size_ - size - sizeof(PreallocatedStorage);
155 ASSERT(size + left_over->size_ + sizeof(PreallocatedStorage) ==
156 storage->size_);
157 storage->size_ = size;
158 left_over->LinkTo(&free_list_);
159 return reinterpret_cast<void*>(storage + 1);
160 }
161 }
162 // Allocation failure.
163 ASSERT(false);
164 return NULL;
165}
166
167
168// We don't attempt to coalesce.
169void PreallocatedStorage::Delete(void* p) {
170 if (p == NULL) {
171 return;
172 }
173 if (!preallocated_) {
174 FreeStoreAllocationPolicy::Delete(p);
175 return;
176 }
177 PreallocatedStorage* storage = reinterpret_cast<PreallocatedStorage*>(p) - 1;
178 ASSERT(storage->next_->previous_ == storage);
179 ASSERT(storage->previous_->next_ == storage);
180 storage->Unlink();
181 storage->LinkTo(&free_list_);
182}
183
184
185void PreallocatedStorage::LinkTo(PreallocatedStorage* other) {
186 next_ = other->next_;
187 other->next_->previous_ = this;
188 previous_ = other;
189 other->next_ = this;
190}
191
192
193void PreallocatedStorage::Unlink() {
194 next_->previous_ = previous_;
195 previous_->next_ = next_;
196}
197
198
199PreallocatedStorage::PreallocatedStorage(size_t size)
200 : size_(size) {
201 previous_ = next_ = this;
202}
203
204} } // namespace v8::internal