jitcraft/Spaces.cpp
author David Anderson <dvander@alliedmods.net>
Fri Jul 06 18:57:27 2012 -0400 (2012-07-06)
changeset 50 5e3c49013064
parent 49 a92afa7484fd
child 51 fb324242a675
permissions -rw-r--r--
Added a large object space.
     1 /* vim: set ts=4 sw=4 tw=99 et:
     2  *
     3  * Copyright (C) 2012 David Anderson
     4  *
     5  * This file is part of JITCraft.
     6  *
     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)
    10  * any later version.
    11  * 
    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.
    15  *
    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/.
    18  */
    19 #include "Spaces.h"
    20 #include "Platform.h"
    21 #include "Spaces-inl.h"
    22 
    23 using namespace jc;
    24 
    25 HeapStack::HeapStack()
    26   : buffer_(NULL),
    27     pos_(NULL),
    28     end_(NULL)
    29 {
    30 }
    31 
    32 HeapStack::~HeapStack()
    33 {
    34     if (buffer_)
    35         OS::UnmapAlignedMemory(map_.base(), map_.size());
    36 }
    37 
    38 bool
    39 HeapStack::initialize()
    40 {
    41     map_ = OS::MapAlignedMemory(kStackSize, kStackSize, OS::Map_Commit);
    42     if (!map_.base())
    43         return false;
    44 
    45     buffer_ = map_.aligned();
    46     pos_ = buffer_;
    47     end_ = buffer_ + kStackSize;
    48     mask_ = kStackSize - 1;
    49     return true;
    50 }
    51 
    52 HeapChunk *
    53 HeapChunk::New(HeapChunk *prev, size_t size)
    54 {
    55     OS::AlignableMapping map = 
    56         OS::MapAlignedMemory(size, HeapChunk::kAlignment, OS::Map_Commit);
    57 
    58     if (!map.base())
    59         return NULL;
    60 
    61     HeapChunk *chunk = reinterpret_cast<HeapChunk *>(map.aligned());
    62     chunk->base_ = map.base();
    63     chunk->end_ = map.base() + map.size();
    64     chunk->cursor_ = chunk->first();
    65     if (prev)
    66         prev->next_ = chunk;
    67 
    68     return chunk;
    69 }
    70 
    71 void
    72 HeapChunk::Destroy(HeapChunk *chunk)
    73 {
    74     OS::UnmapAlignedMemory(chunk->base(), chunk->size());
    75 }
    76 
    77 OldSpace::OldSpace()
    78   : first_(NULL),
    79     last_(NULL)
    80 {
    81 }
    82 
    83 bool
    84 OldSpace::initialize()
    85 {
    86     first_ = HeapChunk::New(first_, HeapChunk::kDefaultSize);
    87     last_ = first_;
    88 
    89     return !!first_;
    90 }
    91 
    92 Address
    93 OldSpace::allocateSlow(size_t nbytes)
    94 {
    95     HeapChunk *chunk = HeapChunk::New(last_, HeapChunk::kDefaultSize);
    96     if (!chunk)
    97         return NULL;
    98 
    99     return chunk->allocate(nbytes);
   100 }
   101 
   102 OldSpace::~OldSpace()
   103 {
   104     while (first_) {
   105         HeapChunk *temp = first_->next();
   106         HeapChunk::Destroy(first_);
   107         first_ = temp;
   108     }
   109 }
   110 
   111 LargeObjectSpace::LargeObjectSpace()
   112   : first_(NULL),
   113     last_(NULL)
   114 {
   115 }
   116 
   117 LargeObjectSpace::~LargeObjectSpace()
   118 {
   119     while (first_) {
   120         HeapChunk *temp = first_->next();
   121         HeapChunk::Destroy(first_);
   122         first_ = temp;
   123     }
   124 }
   125 
   126 bool
   127 LargeObjectSpace::initialize()
   128 {
   129     return true;
   130 }
   131 
   132 Address
   133 LargeObjectSpace::allocate(size_t nbytes)
   134 {
   135     assert(IsAligned(nbytes, kObjectAlignment));
   136 
   137     // Always allocate a new chunk for large objects.
   138     HeapChunk *chunk = HeapChunk::New(last_, nbytes);
   139     if (!chunk)
   140         return NULL;
   141 
   142     if (!first_)
   143         first_ = chunk;
   144     last_ = chunk;
   145 
   146     Address address = chunk->allocate(nbytes);
   147     assert(address);
   148 
   149     return address;
   150 }
   151