Add weak hashtable to manage qual types.
1 /* vim: set ts=4 sw=4 tw=99 et:
3 * Copyright (C) 2012 David Anderson
5 * This file is part of JITCraft.
7 * JITCraft is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License as published by the Free
9 * Software Foundation, either version 3 of the License, or (at your option)
12 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with
17 * JITCraft. If not, see http://www.gnu.org/licenses/.
21 #include "StringPool.h"
22 #include "TypeManager.h"
23 #include "GlobalRoots.h"
24 #include "AllocatorPolicies.h"
26 #include "NativeTable.h"
27 #include "Spaces-inl.h"
32 Zone *ke::SingleThreadedZone;
34 void * const NullAddress::Sentinel = NULL;
37 : stack_(thisFromCtor()),
38 heap_(thisFromCtor()),
44 hasPendingException_(false),
60 if (!stack_.initialize())
62 if (!heap_.initialize())
65 symbols_ = new StringPool(this);
66 if (!symbols_ || !symbols_->initialize())
69 globalRoots_ = new GlobalRoots(this);
70 if (!globalRoots_ || !globalRoots_->initialize())
73 nativeTable_ = new NativeTable(this);
74 if (!nativeTable_ || !nativeTable_->initialize())
83 MapKind_ReferenceType,
91 MapKind_MetaEnvironment,
99 MapKind_EnvironmentSlotDescriptorArray
102 maps_[MapKind_Meta] = heap_.metaMap();
103 for (size_t i = 0; i < sizeof(maps) / sizeof(maps[0]); i++) {
104 if ((maps_[maps[i]] = allocateMap(maps[i], sizeof(Map))) == NULL)
108 types_ = new TypeManager(this);
109 if (!types_ || !types_->initialize())
112 // Create the cached array maps for generic arrays. This is for the API
113 // version of Invoke(), which needs to make arrays very quickly from C++.
115 // Generic "cell" array (contents do not matter, just non-gc things).
116 Local<Type> type(this, types_->getPrimitive(PrimitiveType_Int32));
120 type = types_->newExternalArray(type);
126 externalGenericArrayMap_ = ArrayMap::Attach(this, type);
127 if (!externalGenericArrayMap_)
131 type = types_->getPrimitive(PrimitiveType_Char);
135 type = types_->newExternalArray(type);
141 externalCharArrayMap_ = ArrayMap::Attach(this, type);
142 if (!externalCharArrayMap_)
151 Zone::allocateMap(MapKind kind, size_t bytes, MapKind parent)
153 assert(maps_[parent]);
154 Map *map = heap_.allocateMap(kind, bytes);
157 map->init(maps_[parent]);
162 Zone::accept(VirtualObjectVisitor *visitor)
164 for (unsigned i = 0; i < MapKinds_Total; i++)
165 visitor->visit(maps_[i].address());
166 visitor->visit(externalCharArrayMap_.address());
167 visitor->visit(externalGenericArrayMap_.address());
168 types()->accept(visitor);
170 Local<Object> *local = lastLocalRoot_;
172 visitor->visit(local->address());
173 local = local->prev();
176 globalRoots_->accept(visitor);
177 rootScopes_.accept(visitor);
178 nativeTable_->accept(visitor);
180 stack_.accept(visitor);
184 Zone::sweepWeakRoots()
191 Zone::makeSymbol(const char *str, size_t length)
193 return symbols_->add(str, length);
197 Zone::makeSymbol(const char *str)
199 return makeSymbol(str, strlen(str));
203 Zone::hasPendingException()
205 return hasPendingException_;
209 Zone::reportOutOfMemory()
215 Zone::reportError(Message message, ...)
218 va_start(ap, message);
219 reportErrorVA(message, ap);
223 #if defined(_MSC_VER)
224 # define VA_COPY(to, from) to = from
226 # define VA_COPY(to, from) va_copy(to, from)
230 BuildErrorMessage(const char *format, va_list ap)
235 // We over-allocate and zero terminate ahead of time, since LIBCRT's
236 // version of vsnprintf is screwy.
238 char *buffer = (char *)calloc(size + 1, 1);
243 int r = vsnprintf(buffer, size, format, use);
245 if (r > -1 && size_t(r) < size)
248 #if defined(_MSC_VER)
253 size = size_t(r) + 1;
259 if ((buffer = (char *)calloc(size + 1, 1)) == NULL)
267 Zone::reportErrorVA(Message message, va_list ap)
269 char *report = BuildErrorMessage(Messages[message].format, ap);
276 // Reporters can re-enter. When we start having actual exception
277 // objects that can be caught and inspected, this code will have to
278 // save and restore the exception state.
279 reporter_->onUncaughtException(report);
282 hasPendingException_ = true;
288 Zone::beginCompilationErrors(const char *file)
291 reporter_->beginCompilationErrors(file);
295 Zone::reportCompilationError(Message message, unsigned line, unsigned col, va_list ap)
297 char *report = BuildErrorMessage(Messages[message].format, ap);
304 // Reporters can re-enter. When we start having actual exception
305 // objects that can be caught and inspected, this code will have to
306 // save and restore the exception state.
307 reporter_->reportCompilationError(report, line, col);
314 Zone::endCompilationErrors()
317 reporter_->endCompilationErrors();
321 Zone::installErrorReporter(Ke::IMessageReporter *reporter)
323 reporter_ = reporter;
327 ZoneAllocatorPolicy::reportOutOfMemory()
329 ZONE()->reportOutOfMemory();
333 ZoneAllocatorPolicy::reportAllocationOverflow()
335 ZONE()->reportAllocationOverflow();
339 Zone::reportAllocationOverflow()
341 reportError(Message_AllocationOverflow);
345 Zone::clearPendingException()
347 hasPendingException_ = false;
351 Zone::setPublicFunctionListener(Ke::IPublicFunctionListener *listener)
353 publicFunctionListener_ = listener;
356 AutoRooted::AutoRooted(Zone *zone)
358 prev_(*zone->lastSpecialRoot())
360 *zone->lastSpecialRoot() = this;
363 AutoRooted::~AutoRooted()
365 *zone_->lastSpecialRoot() = prev_;