1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
/* $Header$ */
/*
* Copyright (c) 1999, 2002 Michael J. Roberts. All Rights Reserved.
*
* Please see the accompanying license file, LICENSE.TXT, for information
* on using and copying this software.
*/
/*
Name
vmimgrb.h - image rebuilder
Function
Re-builds an image file from the loaded program's state. Useful
for writing an image file after pre-initialization has bee completed.
Notes
Modified
07/21/99 MJRoberts - Creation
*/
#ifndef VMIMGRB_H
#define VMIMGRB_H
#include "vmtype.h"
/* ------------------------------------------------------------------------ */
/*
* Rewrite the image file. Copies an original image file to the given
* file.
*/
void vm_rewrite_image(VMG_ CVmFile *origfp, CVmFile *newfp,
ulong static_cs_start_ofs);
/* ------------------------------------------------------------------------ */
/*
* Object-to-Constant Mapper.
*
* When we're rebuilding an image file, we might want to convert all
* string and list objects (i.e., instances of metaclass String or List)
* into constant string and list values, respectively, adding these
* values to the image file's constant pool rather than storing them as
* object instances. Using constant pool data in an image file
* increases a program's efficiency by reducing the number of active
* instances required at run-time.
*
* During the conversion process, we need to store the constant data
* that will go in the additional constant pool pages. We also need to
* maintain a translation table that gives us the constant pool address
* of each converted string or list value given its object ID. This
* object maintains these tables.
*/
class CVmConstMapper
{
public:
CVmConstMapper(VMG0_);
~CVmConstMapper();
/*
* Get an object's constant pool address. Returns zero if the
* object does not have an address mapped yet.
*/
ulong get_pool_addr(vm_obj_id_t obj_id);
/*
* Reserve space for an object's data in the new constant pool.
* Returns the constant pool address of the reserved space, and adds
* a translation mapping for the object to our table, so that future
* calls to get_pool_addr(obj_id) will return this address.
*
* If the object is too large to fit on a constant pool page, we'll
* return zero to indicate that the object cannot be stored in the
* constant pool; in this case, the object must remain an object
* instance rather than a constant item.
*
* This doesn't actually copy any data, but merely reserves space.
*/
ulong alloc_pool_space(vm_obj_id_t obj_id, size_t len);
/*
* Prepare to begin storing data. This must be called once, after
* all pool space has been reserved and before the first object's
* data are actually stored.
*/
void prepare_to_store_data();
/*
* Store the object's data in its pre-reserved space in the rebuilt
* constant pool. The space must have previously been allocated
* with alloc_pool_space(), and the size used must be exactly the
* same as the space allocated originally.
*/
void store_data(vm_obj_id_t obj_id, const void *ptr, size_t len);
/*
* get the number of pages we've stored - this is valid only after
* prepare_to_store_data() has been called
*/
size_t get_page_count() const { return pages_cnt_; }
/*
* Write our pages to an image file. This routine can be called
* only after all of the objects have been stored in the constant
* pool.
*/
void write_to_image_file(class CVmImageWriter *writer, uchar xor_mask);
protected:
/*
* Determine how many extra pages we need to add to the original
* image file's constant pool for our mapped data.
*/
size_t calc_page_count() const
{
/*
* calculate the total number of pages by dividing the page size
* into the total number of bytes we've allocated, rounded up to
* the next page whole page
*/
return (size_t)((next_free_ + (page_size_ - 1) - base_addr_)
/ page_size_);
}
/*
* index of our first page - this will be the next page after the
* last page used in the original image file
*/
size_t first_page_idx_;
/* constant pool page size */
size_t page_size_;
/* first address that we allocated */
ulong base_addr_;
/* next free address for the allocation pass */
ulong next_free_;
/* amount of space remaining on current pool allocation page */
size_t rem_;
/*
* Translation page array - each element of this array points to a
* page that contains 1024 object ID translations.
*/
ulong **obj_addr_;
/* number of page slots in obj_addr_ array */
size_t obj_addr_cnt_;
/*
* constant pool page data - we allocate the pages in
* prepare_to_store_data(), which is called after we know how many
* pages we'll need
*/
struct vm_const_mapper_page **pages_;
size_t pages_cnt_;
};
/*
* mapper constant pool page
*/
struct vm_const_mapper_page
{
/*
* high-water mark for data stored in the page, as an offset from
* the start of the page's data
*/
size_t max_ofs_used;
/* the page's data */
char buf[1];
};
#endif /* VMIMGRB_H */
|