dvander@28: /* vim: set ts=4 sw=4 tw=99 et: dvander@28: * dvander@0: * Copyright (C) 2012 David Anderson dvander@0: * dvander@0: * This file is part of JITCraft. dvander@0: * dvander@0: * JITCraft is free software: you can redistribute it and/or modify it under dvander@0: * the terms of the GNU General Public License as published by the Free dvander@0: * Software Foundation, either version 3 of the License, or (at your option) dvander@0: * any later version. dvander@0: * dvander@0: * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY dvander@0: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS dvander@0: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. dvander@0: * dvander@0: * You should have received a copy of the GNU General Public License along with dvander@0: * JITCraft. If not, see http://www.gnu.org/licenses/. dvander@0: */ dvander@0: #ifndef _include_jitcraft_thread_h_ dvander@0: #define _include_jitcraft_thread_h_ dvander@0: dvander@69: #include dvander@0: #include "PoolAllocator.h" dvander@0: #include "Stack.h" dvander@11: #include "Heap.h" dvander@11: #include "Barriers.h" dvander@27: #include "Handles.h" dvander@69: #include "Messages.h" dvander@29: #include "RootScopes.h" dvander@45: #include "VirtualObjectVisitor.h" dvander@0: dvander@59: namespace ke { dvander@0: dvander@11: class TypeManager; dvander@54: class String; dvander@54: class StringPool; dvander@61: class GlobalRoots; dvander@65: class ArrayMap; dvander@69: class Exception; dvander@11: dvander@0: class Zone dvander@0: { dvander@0: PoolAllocator pool_; dvander@0: Stack stack_; dvander@11: Heap heap_; dvander@11: dvander@11: // Map cache. dvander@11: Unbarriered maps_[MapKinds_Total]; dvander@65: Unbarriered genericArrayMap_; dvander@65: Unbarriered charArrayMap_; dvander@11: dvander@11: TypeManager *types_; dvander@54: StringPool *symbols_; dvander@61: GlobalRoots *globalRoots_; dvander@0: dvander@27: // Root list. dvander@28: Local *lastLocalRoot_; dvander@29: RootScopeManager rootScopes_; dvander@27: dvander@69: // Exception stuff. dvander@69: bool hasPendingException_; dvander@69: Ke::IMessageReporter *reporter_; dvander@69: dvander@69: private: dvander@69: Zone *thisFromCtor() { dvander@69: return this; dvander@69: } dvander@69: dvander@0: public: dvander@11: Zone(); dvander@54: ~Zone(); dvander@0: bool initialize(); dvander@0: dvander@0: PoolAllocator &pool() { dvander@0: return pool_; dvander@0: } dvander@0: Stack &stack() { dvander@0: return stack_; dvander@0: } dvander@11: Heap &heap() { dvander@11: return heap_; dvander@11: } dvander@11: Object *allocate(MapKind kind, size_t bytes, Heap::Tenure tenure = Heap::Tenure_Default) { dvander@11: assert(maps_[kind]); dvander@53: Local map(this, maps_[kind]); dvander@28: return allocate(map, bytes, tenure); dvander@12: } dvander@27: Object *allocate(Handle map, size_t bytes, Heap::Tenure tenure = Heap::Tenure_Default) { dvander@27: return heap_.allocate(map, bytes, tenure); dvander@27: } dvander@53: Map *getMap(MapKind kind) { dvander@53: return maps_[kind]; dvander@53: } dvander@12: Map *allocateMap(MapKind kind, size_t bytes, MapKind parent = MapKind_Meta); dvander@65: dvander@65: ArrayMap *genericArrayMap() { dvander@65: return genericArrayMap_; dvander@65: } dvander@65: ArrayMap *charArrayMap() { dvander@65: return charArrayMap_; dvander@65: } dvander@65: dvander@11: TypeManager *types() const { dvander@11: return types_; dvander@11: } dvander@28: Local **lastLocalRoot() { dvander@28: return &lastLocalRoot_; dvander@28: } dvander@29: Object **makeScopedRoot(Object *ptr) { dvander@29: return rootScopes_.make(ptr); dvander@29: } dvander@29: RootScopeManager &rootScopes() { dvander@29: return rootScopes_; dvander@29: } dvander@54: StringPool *symbols() { dvander@54: return symbols_; dvander@54: } dvander@61: GlobalRoots *globalRoots() { dvander@61: return globalRoots_; dvander@61: } dvander@54: dvander@54: String *makeSymbol(const char *string, size_t length); dvander@54: String *makeSymbol(const char *string); dvander@45: dvander@69: void reportOutOfMemory(); dvander@69: void reportError(Message message, ...); dvander@69: void reportErrorVA(Message message, va_list ap); dvander@69: bool hasPendingException(); dvander@69: void installErrorReporter(Ke::IMessageReporter *reporter); dvander@69: void beginCompilationErrors(const char *file); dvander@69: void reportCompilationError(Message message, unsigned line, unsigned col, va_list ap); dvander@69: void endCompilationErrors(); dvander@69: dvander@45: void accept(VirtualObjectVisitor *visitor); dvander@0: }; dvander@0: dvander@0: // In a multi-threaded system, this would be a TLS variable. dvander@0: // In the interest of simplicity, we are single-threaded for now. dvander@60: extern Zone *SingleThreadedZone; dvander@0: dvander@0: static inline Zone *ZONE() dvander@0: { dvander@60: return SingleThreadedZone; dvander@0: } dvander@0: dvander@28: template dvander@28: Local::Local(Zone *zone, T *thing) dvander@28: : zone_(zone), dvander@28: thing_(thing), dvander@28: prev_(*zone->lastLocalRoot()) dvander@28: { dvander@28: *zone->lastLocalRoot() = toRaw(); dvander@0: } dvander@0: dvander@28: template dvander@28: Local::~Local() dvander@28: { dvander@28: assert(*zone_->lastLocalRoot() == toRaw()); dvander@28: *zone_->lastLocalRoot() = prev_; dvander@28: } dvander@28: dvander@29: template dvander@53: ScopedRoot::ScopedRoot() dvander@53: : thingp_(make(NULL)) dvander@53: { dvander@53: } dvander@53: dvander@53: template dvander@29: ScopedRoot::ScopedRoot(T *thing) dvander@34: : thingp_(make(thing)) dvander@29: { dvander@29: // Type check that T is an Object. dvander@29: (void)static_cast(thing); dvander@29: } dvander@29: dvander@29: template T ** dvander@29: ScopedRoot::make(T *other) dvander@29: { dvander@29: return reinterpret_cast(ZONE()->makeScopedRoot(other)); dvander@29: } dvander@29: dvander@29: RootScope::RootScope(Zone *zone) dvander@60: : Ke::HandleScope(zone, zone->rootScopes().position(), *zone->rootScopes().scope()) dvander@29: { dvander@29: } dvander@29: dvander@28: } dvander@28: dvander@28: #endif // _include_jitcraft_thread_h_