virtualspace.cpp

Go to the documentation of this file.
00001 /* Copyright 1994, 1995 LongView Technologies L.L.C. $Revision: 1.7 */
00002 /* Copyright (c) 2006, Sun Microsystems, Inc.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
00006 following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
00010           disclaimer in the documentation and/or other materials provided with the distribution.
00011     * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 
00012           from this software without specific prior written permission.
00013 
00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00020 
00021 
00022 */
00023 
00024 #include "incls/_precompiled.incl"
00025 #include "incls/_virtualspace.cpp.incl"
00026 
00027 ReservedSpace::ReservedSpace(int size) {
00028   assert((size % os::vm_page_size()) == 0, "size not page aligned");
00029   _base = os::reserve_memory(size);
00030   _size = size;
00031 }
00032 
00033 ReservedSpace ReservedSpace::first_part(int partition_size) {
00034   if (partition_size > size())
00035     fatal("partition failed");
00036   ReservedSpace result(base(), partition_size);
00037   return result;
00038 }
00039 
00040 ReservedSpace ReservedSpace::last_part(int  partition_size) {
00041   if (partition_size > size())
00042     fatal("partition failed");
00043   ReservedSpace result(base() + partition_size, size() - partition_size);
00044   return result;
00045 }
00046 
00047 int ReservedSpace::page_align_size(int size) {
00048   int alignment = os::vm_page_size();
00049   int adjust    = alignment - (size%alignment) % alignment;
00050   return size + adjust;
00051 }
00052 
00053 VirtualSpace::VirtualSpace(int reserved_size, int committed_size, bool low_to_high) {
00054   ReservedSpace rs(reserved_size);
00055   initialize(rs, committed_size, low_to_high);
00056 }
00057 
00058 VirtualSpace::VirtualSpace(ReservedSpace reserved, int committed_size, bool low_to_high) {
00059   initialize(reserved, committed_size, low_to_high);
00060 }
00061 
00062 VirtualSpace::VirtualSpace() {
00063   _low_boundary  = NULL;
00064   _high_boundary = NULL;
00065   _low_to_high   = true;
00066   _low           = NULL;
00067   _high          = NULL;
00068 }
00069 
00070 void VirtualSpace::initialize(ReservedSpace reserved, int committed_size, bool low_to_high) {
00071   _low_boundary  = reserved.base();
00072   _high_boundary = low_boundary() + reserved.size();
00073 
00074   _low_to_high = low_to_high;
00075 
00076   if (low_boundary() == NULL) fatal("os::reserve_memory failed");
00077 
00078   // initialize committed area
00079   _low  = low_to_high ? low_boundary() : high_boundary();
00080   _high = low();
00081 
00082   // commit to initial size
00083   expand(committed_size);
00084 
00085   VirtualSpaces::add(this);
00086 }
00087 
00088 VirtualSpace::~VirtualSpace() { 
00089   release();
00090 }
00091 
00092 void VirtualSpace::release() {
00093   os::release_memory(low_boundary(), reserved_size());
00094   _low_boundary  = NULL;
00095   _high_boundary = NULL;
00096   _low           = NULL;
00097   _high          = NULL;
00098   VirtualSpaces::remove(this);
00099 }
00100 
00101 int VirtualSpace::committed_size() const { 
00102   return high() - low();
00103 }
00104 
00105 int VirtualSpace::reserved_size() const {
00106   return high_boundary() - low_boundary();
00107 }
00108 
00109 int VirtualSpace::uncommitted_size()  const {
00110   return reserved_size() - committed_size();
00111 }
00112 
00113 bool VirtualSpace::contains(void* p) const {
00114   return low() <= (char*) p && (char*) p < high();
00115 }
00116 
00117 bool VirtualSpace::low_to_high() const {
00118   return _low_to_high;
00119 }
00120 
00121 
00122 void VirtualSpace::expand(int size) {
00123   assert(uncommitted_size() >= size, "not space enough");
00124   assert((size % os::vm_page_size()) == 0, "size not page aligned");
00125   if (low() == low_boundary()) {
00126     if (!os::commit_memory(high(), size)) fatal("os::commit_memory failed");
00127     _high += size;
00128   } else {
00129     _low -= size;
00130     if (!os::commit_memory(low(), size)) fatal("os::commit_memory failed");
00131   }
00132 }
00133 
00134 void VirtualSpace::shrink(int size) {
00135   assert(committed_size() >= size, "not space enough");
00136   assert((size % os::vm_page_size()) == 0, "size not page aligned");
00137   if (low() == low_boundary()) {
00138     _high -= size;
00139     if (!os::uncommit_memory(high(), size)) fatal("os::uncommit_memory failed");
00140   } else {
00141     if (!os::uncommit_memory(low(), size)) fatal("os::uncommit_memory failed");
00142     _low += size;
00143   }
00144 }
00145 
00146 void VirtualSpace::print() {  
00147   std->print_cr("Virtual space:");
00148   std->print_cr(" - committed: %d", committed_size());
00149   std->print_cr(" - reserved: %d",  reserved_size());
00150   std->print_cr(" - [low, high]: [0x%lx, 0x%lx]",  low(), high());
00151   std->print_cr(" - [low_b, high_b]: [0x%lx, 0x%lx]",  low_boundary(), high_boundary());
00152 }
00153 
00154 
00155 VirtualSpace* VirtualSpaces::head = NULL;
00156 
00157 void VirtualSpaces::add(VirtualSpace* sp) {
00158   sp->next = head;
00159   head = sp;
00160 }
00161 
00162 void VirtualSpaces::remove(VirtualSpace* sp) {
00163   if (!head) return;
00164   if (head == sp)
00165     head = sp->next;
00166   else {
00167     for(VirtualSpace* p = head; p->next; p = p->next)
00168       if (p->next = sp)
00169         p->next = sp->next;
00170   }
00171 }
00172 
00173 int VirtualSpaces::committed_size() {
00174   int total = 0;
00175   for(VirtualSpace* p = head; p; p = p->next)
00176     total += p->committed_size();
00177   return total;
00178 }
00179 
00180 int VirtualSpaces::reserved_size() {
00181   int total = 0;
00182   for(VirtualSpace* p = head; p; p = p->next)
00183     total += p->reserved_size();
00184   return total;
00185 }
00186 
00187 int VirtualSpaces::uncommitted_size() {
00188   int total = 0;
00189   for(VirtualSpace* p = head; p; p = p->next)
00190     total += p->uncommitted_size();
00191   return total;
00192 }
00193 
00194 void VirtualSpaces::print() {
00195   std->print_cr("VirtualSpaces:");
00196   for(VirtualSpace* p = head; p; p = p->next)
00197     p->print();
00198 }
00199 
00200 void VirtualSpaces::test() {
00201   VirtualSpace space(128 *1024, 4 * 1024);
00202   space.print();
00203   space.expand(4 * 1024);
00204   space.print();
00205   space.expand(4 * 1024);
00206   space.print();
00207   space.shrink(4 * 1024);
00208   space.print();
00209   space.shrink(4 * 1024);
00210   space.print();
00211 }

Generated on Mon Oct 9 13:37:30 2006 for Strongtalk VM by  doxygen 1.4.7