blob: d7d21aaa68fa19bf0cde649596e374f92e9ff85f [file] [log] [blame]
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001// Copyright 2008 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// 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
30#include "v8.h"
31
32namespace v8 { namespace internal {
33
34
35void* Malloced::New(size_t size) {
36 ASSERT(NativeAllocationChecker::allocation_allowed());
37 void* result = malloc(size);
38 if (result == NULL) V8::FatalProcessOutOfMemory("Malloced operator new");
39 return result;
40}
41
42
43void Malloced::Delete(void* p) {
44 free(p);
45}
46
47
48void Malloced::FatalProcessOutOfMemory() {
49 V8::FatalProcessOutOfMemory("Out of memory");
50}
51
52
53#ifdef DEBUG
54
55static void* invalid = static_cast<void*>(NULL);
56
57void* Embedded::operator new(size_t size) {
58 UNREACHABLE();
59 return invalid;
60}
61
62
63void Embedded::operator delete(void* p) {
64 UNREACHABLE();
65}
66
67
68void* AllStatic::operator new(size_t size) {
69 UNREACHABLE();
70 return invalid;
71}
72
73
74void AllStatic::operator delete(void* p) {
75 UNREACHABLE();
76}
77
78#endif
79
80
81char* StrDup(const char* str) {
82 int length = strlen(str);
83 char* result = NewArray<char>(length + 1);
84 memcpy(result, str, length * kCharSize);
85 result[length] = '\0';
86 return result;
87}
88
89
90int NativeAllocationChecker::allocation_disallowed_ = 0;
91
92
93PreallocatedStorage PreallocatedStorage::in_use_list_(0);
94PreallocatedStorage PreallocatedStorage::free_list_(0);
95bool PreallocatedStorage::preallocated_ = false;
96
97
98void PreallocatedStorage::Init(size_t size) {
99 ASSERT(free_list_.next_ == &free_list_);
100 ASSERT(free_list_.previous_ == &free_list_);
101 PreallocatedStorage* free_chunk =
102 reinterpret_cast<PreallocatedStorage*>(new char[size]);
103 free_list_.next_ = free_list_.previous_ = free_chunk;
104 free_chunk->next_ = free_chunk->previous_ = &free_list_;
105 free_chunk->size_ = size - sizeof(PreallocatedStorage);
106 preallocated_ = true;
107}
108
109
110void* PreallocatedStorage::New(size_t size) {
111 if (!preallocated_) {
112 return FreeStoreAllocationPolicy::New(size);
113 }
114 ASSERT(free_list_.next_ != &free_list_);
115 ASSERT(free_list_.previous_ != &free_list_);
116 size = (size + kPointerSize - 1) & ~(kPointerSize - 1);
117 // Search for exact fit.
118 for (PreallocatedStorage* storage = free_list_.next_;
119 storage != &free_list_;
120 storage = storage->next_) {
121 if (storage->size_ == size) {
122 storage->Unlink();
123 storage->LinkTo(&in_use_list_);
124 return reinterpret_cast<void*>(storage + 1);
125 }
126 }
127 // Search for first fit.
128 for (PreallocatedStorage* storage = free_list_.next_;
129 storage != &free_list_;
130 storage = storage->next_) {
131 if (storage->size_ >= size + sizeof(PreallocatedStorage)) {
132 storage->Unlink();
133 storage->LinkTo(&in_use_list_);
134 PreallocatedStorage* left_over =
135 reinterpret_cast<PreallocatedStorage*>(
136 reinterpret_cast<char*>(storage + 1) + size);
137 left_over->size_ = storage->size_ - size - sizeof(PreallocatedStorage);
138 ASSERT(size + left_over->size_ + sizeof(PreallocatedStorage) ==
139 storage->size_);
140 storage->size_ = size;
141 left_over->LinkTo(&free_list_);
142 return reinterpret_cast<void*>(storage + 1);
143 }
144 }
145 // Allocation failure.
146 ASSERT(false);
147 return NULL;
148}
149
150
151// We don't attempt to coalesce.
152void PreallocatedStorage::Delete(void* p) {
153 if (p == NULL) {
154 return;
155 }
156 if (!preallocated_) {
157 FreeStoreAllocationPolicy::Delete(p);
158 return;
159 }
160 PreallocatedStorage* storage = reinterpret_cast<PreallocatedStorage*>(p) - 1;
161 ASSERT(storage->next_->previous_ == storage);
162 ASSERT(storage->previous_->next_ == storage);
163 storage->Unlink();
164 storage->LinkTo(&free_list_);
165}
166
167
168void PreallocatedStorage::LinkTo(PreallocatedStorage* other) {
169 next_ = other->next_;
170 other->next_->previous_ = this;
171 previous_ = other;
172 other->next_ = this;
173}
174
175
176void PreallocatedStorage::Unlink() {
177 next_->previous_ = previous_;
178 previous_->next_ = next_;
179}
180
181
182PreallocatedStorage::PreallocatedStorage(size_t size)
183 : size_(size) {
184 previous_ = next_ = this;
185}
186
187} } // namespace v8::internal