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 #ifndef _HDR_HEAP_H_
00034 #define _HDR_HEAP_H_
00035
00036 #include "Ptr.h"
00037 #include "ink_defs.h"
00038 #include "ink_assert.h"
00039 #include "Arena.h"
00040 #include "HdrToken.h"
00041
00042
00043
00044
00045 #define HDR_PTR_SIZE (sizeof(uint64_t))
00046 #define HDR_PTR_ALIGNMENT_MASK ((HDR_PTR_SIZE) - 1L)
00047
00048 #define ROUND(x,l) (((x) + ((l) - 1L)) & ~((l) - 1L))
00049
00050
00051
00052
00053
00054 #define HDR_BUF_RONLY_HEAPS 3
00055
00056 #define HDR_HEAP_DEFAULT_SIZE 2048
00057 #define HDR_STR_HEAP_DEFAULT_SIZE 2048
00058
00059 #define HDR_MAX_ALLOC_SIZE (HDR_HEAP_DEFAULT_SIZE - sizeof(HdrHeap))
00060 #define HDR_HEAP_HDR_SIZE ROUND(sizeof(HdrHeap), HDR_PTR_SIZE)
00061 #define STR_HEAP_HDR_SIZE sizeof(HdrStrHeap)
00062
00063 enum
00064 {
00065 HDR_HEAP_OBJ_EMPTY = 0,
00066 HDR_HEAP_OBJ_RAW = 1,
00067 HDR_HEAP_OBJ_URL = 2,
00068 HDR_HEAP_OBJ_HTTP_HEADER = 3,
00069 HDR_HEAP_OBJ_MIME_HEADER = 4,
00070 HDR_HEAP_OBJ_FIELD_BLOCK = 5,
00071 HDR_HEAP_OBJ_FIELD_STANDALONE = 6,
00072 HDR_HEAP_OBJ_FIELD_SDK_HANDLE = 7,
00073
00074 HDR_HEAP_OBJ_MAGIC = 0x0FEEB1E0
00075 };
00076
00077 struct HdrHeapObjImpl
00078 {
00079 uint32_t m_type:8;
00080 uint32_t m_length:20;
00081 uint32_t m_obj_flags:4;
00082 };
00083
00084
00085
00086
00087 extern void obj_describe(HdrHeapObjImpl * obj, bool recurse);
00088
00089 inline int
00090 obj_is_aligned(HdrHeapObjImpl * obj)
00091 {
00092 return (((((uintptr_t) obj) & HDR_PTR_ALIGNMENT_MASK) == 0) && ((obj->m_length & HDR_PTR_ALIGNMENT_MASK) == 0));
00093 }
00094
00095 inline void
00096 obj_clear_data(HdrHeapObjImpl * obj)
00097 {
00098 char *ptr = (char *) obj;
00099 int hdr_length = sizeof(HdrHeapObjImpl);
00100 memset(ptr + hdr_length, '\0', obj->m_length - hdr_length);
00101 }
00102
00103 inline void
00104 obj_copy_data(HdrHeapObjImpl * s_obj, HdrHeapObjImpl * d_obj)
00105 {
00106 char *src, *dst;
00107
00108 ink_assert((s_obj->m_length == d_obj->m_length) && (s_obj->m_type == d_obj->m_type));
00109
00110 int hdr_length = sizeof(HdrHeapObjImpl);
00111 src = (char *) s_obj + hdr_length;
00112 dst = (char *) d_obj + hdr_length;
00113 memcpy(dst, src, d_obj->m_length - hdr_length);
00114 }
00115
00116 inline void
00117 obj_copy(HdrHeapObjImpl * s_obj, char *d_addr)
00118 {
00119 memcpy(d_addr, (char *) s_obj, s_obj->m_length);
00120 }
00121
00122 inline void
00123 obj_init_header(HdrHeapObjImpl * obj, uint32_t type, uint32_t nbytes, uint32_t obj_flags)
00124 {
00125 obj->m_type = type;
00126 obj->m_length = nbytes;
00127 obj->m_obj_flags = obj_flags;
00128 }
00129
00130
00131
00132
00133 enum
00134 {
00135 HDR_BUF_MAGIC_ALIVE = 0xabcdfeed,
00136 HDR_BUF_MAGIC_MARSHALED = 0xdcbafeed,
00137 HDR_BUF_MAGIC_DEAD = 0xabcddead,
00138 HDR_BUF_MAGIC_CORRUPT = 0xbadbadcc
00139 };
00140
00141 struct StrHeapDesc
00142 {
00143 StrHeapDesc();
00144 Ptr<RefCountObj> m_ref_count_ptr;
00145 char *m_heap_start;
00146 int32_t m_heap_len;
00147 bool m_locked;
00148
00149 bool contains(const char *str) const
00150 {
00151 return (str >= m_heap_start && str < (m_heap_start + m_heap_len));
00152 }
00153 };
00154
00155
00156 class IOBufferBlock;
00157
00158 class HdrStrHeap:public RefCountObj
00159 {
00160 public:
00161
00162 virtual void free();
00163
00164 char *allocate(int nbytes);
00165 char *expand(char *ptr, int old_size, int new_size);
00166 int space_avail();
00167
00168 uint32_t m_heap_size;
00169 char *m_free_start;
00170 uint32_t m_free_size;
00171
00172 bool contains(const char *str) const
00173 {
00174 return (str >= ((const char*)this + STR_HEAP_HDR_SIZE) && str < ((const char*)this + m_heap_size));
00175 }
00176 };
00177
00178 class CoreUtils;
00179
00180 class HdrHeap
00181 {
00182 friend class CoreUtils;
00183 public:
00184 void init();
00185 inkcoreapi void destroy();
00186
00187
00188 HdrHeapObjImpl *allocate_obj(int nbytes, int type);
00189 void deallocate_obj(HdrHeapObjImpl * obj);
00190
00191
00192 char *allocate_str(int nbytes);
00193 char *expand_str(const char *old_str, int old_len, int new_len);
00194 char *duplicate_str(const char *str, int nbytes);
00195 void free_string(const char *s, int len);
00196
00197
00198 inkcoreapi int marshal_length();
00199 inkcoreapi int marshal(char *buf, int length);
00200 int unmarshal(int buf_length, int obj_type, HdrHeapObjImpl ** found_obj, RefCountObj * block_ref);
00201
00202
00203 int unmarshal_size() const;
00204
00205
00206 void inherit_string_heaps(const HdrHeap * inherit_from);
00207 int attach_block(IOBufferBlock * b, const char *use_start);
00208 void set_ronly_str_heap_end(int slot, const char *end);
00209
00210
00211
00212
00213 void lock_ronly_str_heap(int i)
00214 {
00215 m_ronly_heap[i].m_locked = true;
00216 };
00217 void unlock_ronly_str_heap(int i)
00218 {
00219 m_ronly_heap[i].m_locked = false;
00220
00221
00222
00223
00224 for (int j = 0; j < i; j++) {
00225 if (m_ronly_heap[j].m_heap_start == NULL) {
00226
00227 m_ronly_heap[j].m_ref_count_ptr = m_ronly_heap[i].m_ref_count_ptr;
00228 m_ronly_heap[j].m_heap_start = m_ronly_heap[i].m_heap_start;
00229 m_ronly_heap[j].m_heap_len = m_ronly_heap[i].m_heap_len;
00230 m_ronly_heap[j].m_locked = m_ronly_heap[i].m_locked;
00231 m_ronly_heap[i].m_ref_count_ptr = NULL;
00232 m_ronly_heap[i].m_heap_start = NULL;
00233 m_ronly_heap[i].m_heap_len = 0;
00234 m_ronly_heap[i].m_locked = false;
00235 }
00236 }
00237 };
00238
00239
00240 void sanity_check_strs();
00241 bool check_marshalled(uint32_t buf_length);
00242
00243
00244 void dump_heap(int len = -1);
00245
00246 uint32_t m_magic;
00247 char *m_free_start;
00248 char *m_data_start;
00249 uint32_t m_size;
00250
00251 bool m_writeable;
00252
00253
00254
00255
00256
00257
00258
00259
00260 HdrHeap *m_next;
00261
00262
00263 uint32_t m_free_size;
00264
00265 int demote_rw_str_heap();
00266 void coalesce_str_heaps(int incoming_size = 0);
00267 void evacuate_from_str_heaps(HdrStrHeap * new_heap);
00268 size_t required_space_for_evacuation();
00269 int attach_str_heap(char *h_start, int h_len, RefCountObj * h_ref_obj, int *index);
00270
00271
00272
00273
00274
00275
00276
00277 struct HeapGuard {
00278
00279 HeapGuard(HdrHeap* heap, const char *str)
00280 {
00281 if (heap->m_read_write_heap && heap->m_read_write_heap->contains(str)) {
00282 m_ptr = heap->m_read_write_heap;
00283 } else {
00284 for (int i=0; i < HDR_BUF_RONLY_HEAPS; ++i) {
00285 if (heap->m_ronly_heap[i].contains(str)) {
00286 m_ptr = heap->m_ronly_heap[i].m_ref_count_ptr;
00287 break;
00288 }
00289 }
00290 }
00291 }
00292
00293
00294
00295
00296
00297 Ptr<RefCountObj> m_ptr;
00298 };
00299
00300
00301 Ptr<HdrStrHeap> m_read_write_heap;
00302 StrHeapDesc m_ronly_heap[HDR_BUF_RONLY_HEAPS];
00303 int m_lost_string_space;
00304 };
00305
00306 inline void
00307 HdrHeap::free_string(const char *s, int len)
00308 {
00309 if (s && len > 0) {
00310 m_lost_string_space += len;
00311 }
00312 }
00313
00314 inline int
00315 HdrHeap::unmarshal_size() const {
00316 return m_size + m_ronly_heap[0].m_heap_len;
00317 }
00318
00319
00320
00321 struct MarshalXlate
00322 {
00323 char *start;
00324 char *end;
00325 char *offset;
00326 };
00327
00328 struct HeapCheck
00329 {
00330 char *start;
00331 char *end;
00332 };
00333
00334
00335
00336 #define HDR_MARSHAL_STR(ptr, table, nentries) \
00337 if (ptr) { \
00338 int found = 0; \
00339 for (int i = 0; i < nentries; i++) { \
00340 if (ptr >= table[i].start && \
00341 ptr <= table[i].end) { \
00342 ptr = (((char*)ptr) - (uintptr_t) table[i].offset); \
00343 found = 1; \
00344 break; \
00345 } \
00346 } \
00347 ink_assert(found); \
00348 if (found == 0) { \
00349 return -1; \
00350 } \
00351 }
00352
00353
00354 #define HDR_MARSHAL_STR_1(ptr, table) \
00355 if (ptr) { \
00356 int found = 0; \
00357 if (ptr >= table[0].start && \
00358 ptr <= table[0].end) { \
00359 ptr = (((char*)ptr) - (uintptr_t) table[0].offset); \
00360 found = 1; \
00361 } \
00362 ink_assert(found); \
00363 if (found == 0) { \
00364 return -1; \
00365 } \
00366 }
00367
00368
00369
00370 #define HDR_MARSHAL_PTR(ptr, type, table, nentries) \
00371 if (ptr) { \
00372 int found = 0; \
00373 for (int i = 0; i < nentries; i++) { \
00374 if ((char*) ptr >= table[i].start && \
00375 (char*) ptr <= table[i].end) { \
00376 ptr = (type *) (((char*)ptr) - (uintptr_t) table[i].offset); \
00377 found = 1; \
00378 break; \
00379 } \
00380 } \
00381 ink_assert(found); \
00382 if (found == 0) { \
00383 return -1; \
00384 } \
00385 }
00386
00387 #define HDR_MARSHAL_PTR_1(ptr, type, table) \
00388 if (ptr) { \
00389 int found = 0; \
00390 if ((char*) ptr >= table[0].start && \
00391 (char*) ptr <= table[0].end) { \
00392 ptr = (type *) (((char*)ptr) - (uintptr_t) table[0].offset); \
00393 found = 1; \
00394 } \
00395 ink_assert(found); \
00396 if (found == 0) { \
00397 return -1; \
00398 } \
00399 }
00400
00401
00402
00403
00404 #define HDR_UNMARSHAL_STR(ptr, offset) \
00405 if (ptr) { \
00406 ptr = ((char*)ptr) + offset; \
00407 }
00408
00409 #define HDR_UNMARSHAL_PTR(ptr, type, offset) \
00410 if (ptr) { \
00411 ptr = (type *) (((char*)ptr) + offset); \
00412 }
00413
00414
00415
00416 #define HDR_MOVE_STR(str, len) \
00417 { \
00418 if (str) { \
00419 char* new_str = new_heap->allocate(len); \
00420 if(new_str) \
00421 memcpy(new_str, str, len); \
00422 str = new_str; \
00423 } \
00424 }
00425
00426
00427
00428 #define CHECK_STR(str, len, _heaps, _num_heaps) \
00429 { \
00430 if (str) { \
00431 int found = 0; \
00432 for (int i = 0; i < _num_heaps; i++) { \
00433 if (str >= _heaps[i].start && \
00434 str + len <= heaps[i].end) { \
00435 found = 1; \
00436 } \
00437 } \
00438 ink_release_assert(found); \
00439 } \
00440 }
00441
00442
00443
00444
00445
00446
00447
00448
00449 struct HdrHeapSDKHandle
00450 {
00451 public:
00452 HdrHeapSDKHandle()
00453 : m_heap(NULL)
00454 { }
00455
00456 ~HdrHeapSDKHandle() { clear(); }
00457
00458
00459
00460 void clear();
00461
00462
00463
00464 void destroy();
00465
00466 void set(const HdrHeapSDKHandle * from);
00467 const char *make_sdk_string(const char *raw_str, int raw_str_len);
00468
00469 HdrHeap *m_heap;
00470
00471 private:
00472
00473
00474 HdrHeapSDKHandle(const HdrHeapSDKHandle & r);
00475 HdrHeapSDKHandle & operator =(const HdrHeapSDKHandle & r);
00476 };
00477
00478 inline void
00479 HdrHeapSDKHandle::destroy()
00480 {
00481 if (m_heap) {
00482 m_heap->destroy();
00483 }
00484 clear();
00485 }
00486
00487 inline void
00488 HdrHeapSDKHandle::clear()
00489 {
00490 m_heap = NULL;
00491 }
00492
00493 inline void
00494 HdrHeapSDKHandle::set(const HdrHeapSDKHandle * from)
00495 {
00496 clear();
00497 m_heap = from->m_heap;
00498 }
00499
00500 inkcoreapi HdrHeap *new_HdrHeap(int size = HDR_HEAP_DEFAULT_SIZE);
00501
00502 void hdr_heap_test();
00503 #endif