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