cfad47cfa3/tads3/vmimgrb.h

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