static void verify_arena(Arena *arena) { for (int i = 0; i < arena->num_pages; i ++) { EJS_ASSERT (arena->pages[i] == arena->page_infos[i]->page_start); } }
static PageInfo* alloc_page_info_from_arena(Arena *arena, void *page_data, size_t cell_size) { // FIXME allocate the PageInfo and bitmap from the arena as well PageInfo* info = (PageInfo*)calloc(1, sizeof(PageInfo)); EJS_LIST_INIT(info); info->cell_size = cell_size; info->num_cells = CELLS_OF_SIZE(cell_size); info->num_free_cells = info->num_cells; EJS_ASSERT(info->num_cells > 0); info->page_start = page_data; info->page_end = info->page_start + PAGE_SIZE; // allocate a bitmap large enough to store any sized object so we can reuse the bitmap info->page_bitmap = (BitmapCell*)malloc (PAGE_SIZE / (1<<OBJECT_SIZE_LOW_LIMIT_BITS)); info->bump_ptr = info->page_start; memset (info->page_bitmap, CELL_FREE, info->num_cells * sizeof(BitmapCell)); pthread_mutex_init (&info->page_mutex, NULL); return info; }
static jschar * IntToUCS2(jschar *cbuf, jsint i, jsint base) { jsuint u = (i < 0) ? -i : i; jschar *cp = cbuf + UINT32_CHAR_BUFFER_LENGTH; *cp = '\0'; /* Build the string from behind. */ switch (base) { case 10: { // cp = BackfillIndexInCharBuffer(u, cp); uint32_t index = u; jschar *end = cp; do { uint32_t next = index / 10, digit = index % 10; *--end = '0' + digit; index = next; } while (index > 0); return end; break; } case 16: do { jsuint newu = u / 16; *--cp = "0123456789abcdef"[u - newu * 16]; u = newu; } while (u != 0); break; default: EJS_ASSERT(base >= 2 && base <= 36); do { jsuint newu = u / base; *--cp = "0123456789abcdefghijklmnopqrstuvwxyz"[u - newu * base]; u = newu; } while (u != 0); break; } if (i < 0) *--cp = '-'; return cp; }
static PageInfo* find_page_and_cell(GCObjectPtr ptr, uint32_t *cell_idx) { Arena *arena = find_arena(ptr); if (EJS_LIKELY (arena != NULL)) { SANITY(verify_arena(arena)); int page_index = PTR_TO_ARENA_PAGE_INDEX(ptr); if (page_index < 0 || page_index > arena->num_pages) { return NULL; } PageInfo *page = arena->page_infos[page_index]; if (!IS_ALIGNED_TO(ptr, page->cell_size)) { return NULL; // can't possibly point to allocated cells. } if (cell_idx) { *cell_idx = PTR_TO_CELL(ptr, page); EJS_ASSERT(*cell_idx >= 0 && *cell_idx < CELLS_IN_PAGE(page)); } return page; } // check if it's in the LOS LOCK_GC(); for (LargeObjectInfo *lobj = los_list; lobj; lobj = lobj->next) { if (lobj->page_info.page_start == ptr) { if (cell_idx) { *cell_idx = 0; } UNLOCK_GC(); return &lobj->page_info; } } UNLOCK_GC(); return NULL; }
ejsval ToNumber(ejsval exp) { if (EJSVAL_IS_NUMBER(exp)) return exp; else if (EJSVAL_IS_BOOLEAN(exp)) return EJSVAL_TO_BOOLEAN(exp) ? _ejs_one : _ejs_zero; else if (EJSVAL_IS_STRING(exp)) { char* num_utf8 = ucs2_to_utf8(EJSVAL_TO_FLAT_STRING(exp)); char *endptr; double d = strtod(num_utf8, &endptr); if (*endptr != '\0') return _ejs_nan; ejsval rv = NUMBER_TO_EJSVAL(d); // XXX NaN free (num_utf8); return rv; } else if (EJSVAL_IS_UNDEFINED(exp)) return _ejs_nan; else if (EJSVAL_IS_OBJECT(exp)) { if (EJSVAL_IS_DATE(exp)) { return NUMBER_TO_EJSVAL(_ejs_date_get_time ((EJSDate*)EJSVAL_TO_OBJECT(exp))); } else if (EJSVAL_IS_ARRAY(exp)) { int len = EJS_ARRAY_LEN(exp); if (len == 0) return _ejs_zero; else if (len > 1) return _ejs_nan; else { // XXX we need to support sparse arrays here too EJS_ASSERT (EJSVAL_IS_DENSE_ARRAY(exp)); return ToNumber(EJS_DENSE_ARRAY_ELEMENTS(exp)[0]); } } else return _ejs_nan; } else EJS_NOT_IMPLEMENTED(); }