00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #include "defs.h"
00052 #include "errors.h"
00053 #include "mempool.h"
00054 #include "region.h"
00055 #include "region_map.h"
00056
00057 #define REGION_EXPANSION_FACTOR 2
00058
00059
00060 static REGION_MAP free_maps;
00061
00062
00063 #define REGION_MAP_next(map) ((map)->values.ptr[0])
00064
00065
00066 void REGION_MAP_Init(void)
00067 {
00068 free_maps = NULL;
00069 }
00070
00071
00072 void REGION_MAP_Delete(REGION_MAP map)
00073 {
00074 DevAssert(!map->deleted, ("REGION_MAP 0x%x already deleted", map));
00075
00076 REGION_MAP_next(map) = free_maps;
00077 map->deleted = TRUE;
00078 free_maps = map;
00079 }
00080
00081
00082 inline UINT16 sizeof_kind(_REGION_MAP_KIND kind)
00083 {
00084 switch (kind) {
00085 case _REGION_MAP_PTR:
00086 return sizeof(void *);
00087 case _REGION_MAP_I32:
00088 return sizeof(mINT32);
00089 case _REGION_MAP_I64:
00090 return sizeof(mINT64);
00091 default:
00092 FmtAssert(FALSE, ("sizeof_kind passed bad <kind>"));
00093 }
00094
00095
00096
00097
00098
00099 return 0;
00100 }
00101
00102
00103 REGION_MAP REGION_MAP_create_kind(INT32 REGION_MAP_idx_max, _REGION_MAP_KIND kind)
00104 {
00105 REGION_MAP result, prev;
00106 UINT32 length = (REGION_MAP_idx_max + 1) * REGION_EXPANSION_FACTOR;
00107
00108
00109 prev = NULL;
00110 for (result = free_maps; result; result = (REGION_MAP) REGION_MAP_next(result)) {
00111 if (sizeof_kind(kind) == sizeof_kind(result->kind)) {
00112 if (prev)
00113 REGION_MAP_next(prev) = REGION_MAP_next(result);
00114 else
00115 free_maps = (REGION_MAP) REGION_MAP_next(result);
00116 result->deleted = FALSE;
00117 result->kind = kind;
00118 result->gen += 1;
00119 if (result->gen == 0) {
00120
00121 DevWarn("(Performance) REGION_MAP gen overflow - zeroing.");
00122 bzero(result->value_gens, sizeof(mUINT32) * result->length);
00123 bzero(result->values.ptr, sizeof_kind(kind) * result->length);
00124 }
00125 return result;
00126 }
00127 prev = result;
00128 }
00129
00130
00131 result = TYPE_P_ALLOC(struct region_map);
00132 result->deleted = FALSE;
00133 result->kind = kind;
00134 result->length = length;
00135 result->gen = 0;
00136 result->value_gens = TYPE_P_ALLOC_N(mUINT32, length);
00137 switch (kind) {
00138 case _REGION_MAP_PTR:
00139 result->values.ptr = TYPE_P_ALLOC_N(void *, length);
00140 break;
00141 case _REGION_MAP_I32:
00142 result->values.i32 = TYPE_P_ALLOC_N(mINT32, length);
00143 break;
00144 case _REGION_MAP_I64:
00145 result->values.i64 = TYPE_P_ALLOC_N(mINT64, length);
00146 break;
00147 default:
00148 FmtAssert(FALSE, ("REGION_MAP_create_kind passed bad <kind>"));
00149 }
00150
00151 return result;
00152 }
00153
00154
00155 void REGION_MAP_grow(REGION_MAP map, REGION *region)
00156 {
00157 INT32 new_length = (sizeof(map) + 1) * REGION_EXPANSION_FACTOR;
00158
00159 if (REGION_map_idx(region) > new_length) {
00160 DevWarn("REGION_MAP_idx_max not up to date");
00161 new_length = REGION_map_idx(region) + 1;
00162 }
00163
00164
00165
00166
00167
00168 map->value_gens = TYPE_MEM_POOL_REALLOC_N(mUINT32, &MEM_phase_pool,
00169 map->value_gens, map->length,
00170 new_length);
00171
00172 switch (map->kind) {
00173 case _REGION_MAP_PTR:
00174 map->values.ptr =
00175 TYPE_MEM_POOL_REALLOC_N(void *, &MEM_phase_pool, map->values.ptr,
00176 map->length, new_length);
00177 break;
00178 case _REGION_MAP_I32:
00179 map->values.i32 =
00180 TYPE_MEM_POOL_REALLOC_N(INT32, &MEM_phase_pool, map->values.i32,
00181 map->length, new_length);
00182 break;
00183 case _REGION_MAP_I64:
00184 map->values.i64 =
00185 TYPE_MEM_POOL_REALLOC_N(INT64, &MEM_phase_pool, map->values.i64,
00186 map->length, new_length);
00187 break;
00188 default:
00189 FmtAssert(FALSE, ("REGION_MAP_grow passed map with bad <kind>"));
00190 }
00191
00192 map->length = new_length;
00193 }