static int heapStatsCallback(void* ptr, unsigned char kind, size_t sz, int live, void* _data) { HeapStatsCallbackData* data = (HeapStatsCallbackData*) _data; LoadedClass* loadedClasses = data->loadedClasses; HeapStat** statsHashPtr = data->statsHashPtr; Class* key = NULL; if (kind == GC_gcj_kind || kind == objectArrayGCKind) { Object* obj = (Object*) ptr; if (obj && obj->clazz) { LoadedClass* loadedClass; HASH_FIND_PTR(loadedClasses, &(obj->clazz), loadedClass); if (!loadedClass) { return 0; // Don't clear this object } key = obj->clazz; } } HeapStat* stat; HASH_FIND_PTR(*statsHashPtr, &key, stat); if (!stat) { stat = calloc(1, sizeof(HeapStat)); stat->key = key; HASH_ADD_PTR(*statsHashPtr, key, stat); } stat->numberOfInstances++; stat->numberOfBytes += sz; if (live) { stat->numberOfLiveInstances++; stat->numberOfLiveBytes += sz; } return 0; // live ? 0 : 1; }
/****************************************************************************** tv_material_compile_shader Compiles the given shader (first looking to see if the shader already has been loaded by checking the appropriate "loaded_XXX_shaders" table. *****************************************************************************/ GLuint tv_material_compile_shader(tvchar* file, tvuint type) { TvMaterialShader* lup; tvchar* buffer; TvMaterialShader* shader_table; GLuint shader_handle; /* look up the shader - has it been loaded already? */ HASH_FIND_PTR(loaded_vertex_shaders, file, lup); switch(type) { case GL_VERTEX_SHADER: shader_table = loaded_fragment_shaders; break; case GL_FRAGMENT_SHADER: shader_table = loaded_vertex_shaders; break; case GL_GEOMETRY_SHADER: shader_table = loaded_geometry_shaders; break; case GL_TESS_CONTROL_SHADER: shader_table = loaded_tesselation_control_shaders; break; case GL_TESS_EVALUATION_SHADER: shader_table = loaded_tesselation_evaluation_shaders; break; default: tv_warning("unrecognized shader type"); return; } /* look up the shader */ HASH_FIND_PTR(shader_table, file, lup); /* if the shader has already been loaded, return it's handle. */ if(lup) { return (GLuint)lup->id; } /* shader has NOT been loaded, let's load it */ UtilReadFile(file, &buffer); shader_handle = compile_gl_shader(buffer, type); lup = (TvMaterialShader*)tv_alloc(sizeof(TvMaterialShader)); lup->name = file; lup->id = shader_handle; HASH_ADD_PTR(shader_table, name, lup); free(buffer); return (GLuint)shader_handle; }
static Bool DestroyPixmap(PixmapPtr pPixmap) { ScreenPtr pScreen = pPixmap->drawable.pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; Rk30MaliPtr rk_3d = FBDEVPTR(pScrn)->Rk30Mali; Bool result; UMPBufferInfoPtr umpbuf; HASH_FIND_PTR(rk_3d->HashPixmapToUMP, &pPixmap, umpbuf); if (umpbuf) { DebugMsg("DestroyPixmap %p for migrated UMP pixmap (UMP buffer=%p)\n", pPixmap, umpbuf); pPixmap->devKind = umpbuf->BackupDevKind; pPixmap->devPrivate.ptr = umpbuf->BackupDevPrivatePtr; ump_mapped_pointer_release(umpbuf->handle); ump_reference_release(umpbuf->handle); HASH_DEL(rk_3d->HashPixmapToUMP, umpbuf); DebugMsg("umpbuf->refcount=%d\n", umpbuf->refcount); if (--umpbuf->refcount <= 0) { DebugMsg("free(umpbuf)\n"); free(umpbuf); } } pScreen->DestroyPixmap = rk_3d->DestroyPixmap; result = (*pScreen->DestroyPixmap) (pPixmap); rk_3d->DestroyPixmap = pScreen->DestroyPixmap; pScreen->DestroyPixmap = DestroyPixmap; return result; }
/* Migrate pixmap to UMP buffer */ static UMPBufferInfoPtr MigratePixmapToUMP(PixmapPtr pPixmap) { ScreenPtr pScreen = pPixmap->drawable.pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; Rk30MaliPtr rk_3d = FBDEVPTR(pScrn)->Rk30Mali; UMPBufferInfoPtr umpbuf; size_t pitch = ((pPixmap->devKind + 7) / 8) * 8; size_t size = pitch * pPixmap->drawable.height; HASH_FIND_PTR(rk_3d->HashPixmapToUMP, &pPixmap, umpbuf); if (umpbuf) { DebugMsg("MigratePixmapToUMP %p, already exists = %p\n", pPixmap, umpbuf); return umpbuf; } /* create the UMP buffer */ umpbuf = calloc(1, sizeof(UMPBufferInfoRec)); if (!umpbuf) { ErrorF("MigratePixmapToUMP: calloc failed\n"); return NULL; } umpbuf->refcount = 1; umpbuf->pPixmap = pPixmap; umpbuf->handle = ump_ref_drv_allocate(size, UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR); if (umpbuf->handle == UMP_INVALID_MEMORY_HANDLE) { ErrorF("MigratePixmapToUMP: ump_ref_drv_allocate failed\n"); free(umpbuf); return NULL; } umpbuf->size = size; umpbuf->addr = ump_mapped_pointer_get(umpbuf->handle); umpbuf->depth = pPixmap->drawable.depth; umpbuf->width = pPixmap->drawable.width; umpbuf->height = pPixmap->drawable.height; /* copy the pixel data to the new location */ if (pitch == pPixmap->devKind) { memcpy(umpbuf->addr, pPixmap->devPrivate.ptr, size); } else { int y; for (y = 0; y < umpbuf->height; y++) { memcpy(umpbuf->addr + y * pitch, pPixmap->devPrivate.ptr + y * pPixmap->devKind, pPixmap->devKind); } } umpbuf->BackupDevKind = pPixmap->devKind; umpbuf->BackupDevPrivatePtr = pPixmap->devPrivate.ptr; pPixmap->devKind = pitch; pPixmap->devPrivate.ptr = umpbuf->addr; HASH_ADD_PTR(rk_3d->HashPixmapToUMP, pPixmap, umpbuf); DebugMsg("MigratePixmapToUMP %p, new buf = %p\n", pPixmap, umpbuf); return umpbuf; }
inline js_proxy_t *js_get_or_create_proxy(JSContext *cx, T *native_obj) { js_proxy_t *proxy; HASH_FIND_PTR(_native_js_global_ht, &native_obj, proxy); if (!proxy) { js_type_class_t *typeProxy = js_get_type_from_native<T>(native_obj); // Return NULL if can't find its type rather than making an assert. // assert(typeProxy); if (!typeProxy) { CCLOGINFO("Could not find the type of native object."); return NULL; } JSObject* js_obj = JS_NewObject(cx, typeProxy->jsclass, typeProxy->proto, typeProxy->parentProto); proxy = jsb_new_proxy(native_obj, js_obj); #ifdef DEBUG JS_AddNamedObjectRoot(cx, &proxy->obj, typeid(*native_obj).name()); #else JS_AddObjectRoot(cx, &proxy->obj); #endif return proxy; } else { return proxy; } return NULL; }
// XXX: Passing "const O *" instead of "const O&" because HASH_FIND_IT requries the address of a pointer // and, it is not possible to get the address of a reference Action* ActionManager::getActionByTag(int tag, const Object *target) const { CCASSERT(tag != Action::INVALID_TAG, ""); tHashElement *element = NULL; HASH_FIND_PTR(m_pTargets, &target, element); if (element) { if (element->actions != NULL) { long limit = element->actions->num; for (long i = 0; i < limit; ++i) { Action *action = (Action*)element->actions->arr[i]; if (action->getTag() == (int)tag) { return action; } } } CCLOG("cocos2d : getActionByTag(tag = %d): Action not found", tag); } else { // CCLOG("cocos2d : getActionByTag: Target not found"); } return NULL; }
void ActionManager::removeAllActionsFromTarget(Object *target) { // explicit null handling if (target == NULL) { return; } tHashElement *element = NULL; HASH_FIND_PTR(m_pTargets, &target, element); if (element) { if (ccArrayContainsObject(element->actions, element->currentAction) && (! element->currentActionSalvaged)) { element->currentAction->retain(); element->currentActionSalvaged = true; } ccArrayRemoveAllObjects(element->actions); if (m_pCurrentTarget == element) { m_bCurrentTargetSalvaged = true; } else { deleteHashElement(element); } } else { // CCLOG("cocos2d: removeAllActionsFromTarget: Target not found"); } }
void rvmRegisterReference(Env* env, Object* reference, Object* referent) { if (referent) { // Add 'reference' to the references list for 'referent' in the referents hashtable rvmLockMutex(&referentsLock); ReferenceList* l = rvmAllocateMemory(env, sizeof(ReferenceList)); if (!l) goto done; // OOM thrown l->reference = reference; void* key = (void*) GC_HIDE_POINTER(referent); // Hide the pointer from the GC so that it doesn't prevent the referent from being GCed. ReferentEntry* referentEntry; HASH_FIND_PTR(referents, &key, referentEntry); if (!referentEntry) { // referent is not in the hashtable. Add it. referentEntry = rvmAllocateMemory(env, sizeof(ReferentEntry)); if (!referentEntry) goto done; // OOM thrown referentEntry->key = key; HASH_ADD_PTR(referents, key, referentEntry); } // Add the reference to the referent's list of references LL_PREPEND(referentEntry->references, l); // Register the referent for finalization GC_REGISTER_FINALIZER_NO_ORDER(referent, _finalizeObject, NULL, NULL, NULL); done: rvmUnlockMutex(&referentsLock); } }
void ActionManager::addAction(Action *action, Node *target, bool paused) { CCASSERT(action != NULL, ""); CCASSERT(target != NULL, ""); tHashElement *element = NULL; // we should convert it to Object*, because we save it as Object* Object *tmp = target; HASH_FIND_PTR(m_pTargets, &tmp, element); if (! element) { element = (tHashElement*)kdCalloc(sizeof(*element), 1); element->paused = paused; target->retain(); element->target = target; HASH_ADD_PTR(m_pTargets, target, element); } actionAllocWithHashElement(element); CCASSERT(! ccArrayContainsObject(element->actions, action), ""); ccArrayAppendObject(element->actions, action); action->startWithTarget(target); }
void ActionManager::removeAllActionsByTag(int tag, Node *target) { CCASSERT(tag != Action::INVALID_TAG, "Invalid tag value!"); CCASSERT(target != nullptr, "target can't be nullptr!"); if (target == nullptr) { return; } tHashElement *element = nullptr; HASH_FIND_PTR(_targets, &target, element); if (element) { auto limit = element->actions->num; for (int i = 0; i < limit;) { Action *action = (Action*)element->actions->arr[i]; if (action->getTag() == (int)tag && action->getOriginalTarget() == target) { removeActionAtIndex(i, element); --limit; } else { ++i; } } } }
// FIXME: Passing "const O *" instead of "const O&" because HASH_FIND_IT requries the address of a pointer // and, it is not possible to get the address of a reference Action* ActionManager::getActionByTag(int tag, const Node *target) const { CCASSERT(tag != Action::INVALID_TAG, ""); tHashElement *element = nullptr; HASH_FIND_PTR(_targets, &target, element); if (element) { if (element->actions != nullptr) { auto limit = element->actions->num; for (int i = 0; i < limit; ++i) { Action *action = (Action*)element->actions->arr[i]; if (action->getTag() == (int)tag) { return action; } } } //CCLOG("cocos2d : getActionByTag(tag = %d): Action not found", tag); } else { // CCLOG("cocos2d : getActionByTag: Target not found"); } return nullptr; }
void ActionManager::removeAllActionsFromTarget(Node *target) { // explicit null handling if (target == nullptr) { return; } tHashElement *element = nullptr; HASH_FIND_PTR(_targets, &target, element); if (element) { if (ccArrayContainsObject(element->actions, element->currentAction) && (! element->currentActionSalvaged)) { element->currentAction->retain(); element->currentActionSalvaged = true; } ccArrayRemoveAllObjects(element->actions); if (_currentTarget == element) { _currentTargetSalvaged = true; } else { deleteHashElement(element); } } }
// FIXME: Passing "const O *" instead of "const O&" because HASH_FIND_IT requires the address of a pointer // and, it is not possible to get the address of a reference Action* ActionManager::getActionByTag(int tag, const Node *target) const { CCASSERT(tag != Action::INVALID_TAG, "Invalid tag value!"); tHashElement *element = nullptr; HASH_FIND_PTR(_targets, &target, element); if (element) { if (element->actions != nullptr) { auto limit = element->actions->num; for (int i = 0; i < limit; ++i) { Action *action = (Action*)element->actions->arr[i]; if (action->getTag() == (int)tag) { return action; } } } } return nullptr; }
void ActionManager::addAction(Action *action, Node *target, bool paused) { CCASSERT(action != nullptr, "action can't be nullptr!"); CCASSERT(target != nullptr, "target can't be nullptr!"); if(action == nullptr || target == nullptr) return; tHashElement *element = nullptr; // we should convert it to Ref*, because we save it as Ref* Ref *tmp = target; HASH_FIND_PTR(_targets, &tmp, element); if (! element) { element = (tHashElement*)calloc(sizeof(*element), 1); element->paused = paused; target->retain(); element->target = target; HASH_ADD_PTR(_targets, target, element); } actionAllocWithHashElement(element); CCASSERT(! ccArrayContainsObject(element->actions, action), "action already be added!"); ccArrayAppendObject(element->actions, action); action->startWithTarget(target); }
void ActionManager::removeActionsByFlags(unsigned int flags, Node *target) { if (flags == 0) { return; } CCASSERT(target != nullptr, "target can't be nullptr!"); if (target == nullptr) { return; } tHashElement *element = nullptr; HASH_FIND_PTR(_targets, &target, element); if (element) { auto limit = element->actions->num; for (int i = 0; i < limit;) { Action *action = (Action*)element->actions->arr[i]; if ((action->getFlags() & flags) != 0 && action->getOriginalTarget() == target) { removeActionAtIndex(i, element); --limit; } else { ++i; } } } }
void * debug_alloc_find (void *a) { alloc_table_t *at = NULL; /* entry corresponding to "a" */ HASH_FIND_PTR (atp, &a, at); return at; }
static void finalizeObject(Env* env, Object* obj) { // TRACEF("finalizeObject: %p (%s)\n", obj, obj->clazz->name); rvmLockMutex(&referentsLock); void* key = (void*) GC_HIDE_POINTER(obj); ReferentEntry* referentEntry; HASH_FIND_PTR(referents, &key, referentEntry); assert(referentEntry != NULL); if (referentEntry->references == NULL) { // The object is not referenced by any type of reference and can never be resurrected. HASH_DEL(referents, referentEntry); rvmUnlockMutex(&referentsLock); return; } Object* softReferences = NULL; Object* weakReferences = NULL; Object* finalizerReferences = NULL; Object* phantomReferences = NULL; Object* clearedReferences = NULL; ReferenceList* refNode; while (referentEntry->references != NULL) { refNode = referentEntry->references; LL_DELETE(referentEntry->references, refNode); Object** list = NULL; Object* reference = refNode->reference; if (rvmIsSubClass(java_lang_ref_SoftReference, reference->clazz)) { list = &softReferences; } else if (rvmIsSubClass(java_lang_ref_WeakReference, reference->clazz)) { list = &weakReferences; } else if (rvmIsSubClass(java_lang_ref_FinalizerReference, reference->clazz)) { list = &finalizerReferences; } else if (rvmIsSubClass(java_lang_ref_PhantomReference, reference->clazz)) { list = &phantomReferences; } enqueuePendingReference(env, reference, list); } assert(referentEntry->references == NULL); clearAndEnqueueReferences(env, &softReferences, &clearedReferences); clearAndEnqueueReferences(env, &weakReferences, &clearedReferences); enqueueFinalizerReferences(env, &finalizerReferences, &clearedReferences); clearAndEnqueueReferences(env, &phantomReferences, &clearedReferences); // Reregister for finalization. If no new references have been added to the list of references for the referent the // next time it gets finalized we know it will never be resurrected. GC_REGISTER_FINALIZER_NO_ORDER(obj, _finalizeObject, NULL, NULL, NULL); rvmUnlockMutex(&referentsLock); if (clearedReferences != NULL) { rvmCallVoidClassMethod(env, java_lang_ref_ReferenceQueue, java_lang_ref_ReferenceQueue_add, clearedReferences); assert(rvmExceptionOccurred(env) == NULL); } }
// Hash of JSObject -> proxy void* jsb_get_proxy_for_jsobject(JSObject *obj) { tHashJSObject *element = NULL; HASH_FIND_PTR(hash, &obj, element); if( element ) return element->proxy; return NULL; }
void ActionManager::resumeTarget(Node *target) { tHashElement *element = nullptr; HASH_FIND_PTR(_targets, &target, element); if (element) { element->paused = false; } }
void ActionManager::resumeTarget(Object *target) { tHashElement *element = NULL; HASH_FIND_PTR(m_pTargets, &target, element); if (element) { element->paused = false; } }
void jsb_del_proxy_for_jsobject(JSObject *obj) { tHashJSObject *element = NULL; HASH_FIND_PTR(hash, &obj, element); if( element ) { HASH_DEL(hash, element); free(element); } }
void jsb_del_jsobject_for_proxy(void* proxy) { tHashJSObject *element = NULL; HASH_FIND_PTR(reverse_hash, &proxy, element); if( element ) { HASH_DEL(reverse_hash, element); free(element); } }
// Reverse hash: Proxy -> JSObject JSObject* jsb_get_jsobject_for_proxy(void *proxy) { tHashJSObject *element = NULL; HASH_FIND_PTR(reverse_hash, &proxy, element); if( element ) return element->jsObject; return NULL; }
// XXX: Passing "const O *" instead of "const O&" because HASH_FIND_IT requries the address of a pointer // and, it is not possible to get the address of a reference KDint32 ActionManager::getNumberOfRunningActionsInTarget ( const Object* pTarget ) const { tHashElement *element = NULL; HASH_FIND_PTR(m_pTargets, &pTarget, element); if (element) { return element->actions ? element->actions->num : 0; } return 0; }
// FIXME: Passing "const O *" instead of "const O&" because HASH_FIND_IT requires the address of a pointer // and, it is not possible to get the address of a reference ssize_t ActionManager::getNumberOfRunningActionsInTarget(const Node *target) const { tHashElement *element = nullptr; HASH_FIND_PTR(_targets, &target, element); if (element) { return element->actions ? element->actions->num : 0; } return 0; }
void xpl_free(void *ptr) { xpl_allocation_t *allocation_info = NULL; HASH_FIND_PTR(allocations, &ptr, allocation_info); if (allocation_info == NULL) { LOG_ERROR("Double-free detected %p (allocation table entry not found)", ptr); xpl_allocation_t *found, *tmp; LOG_DEBUG("Table:"); HASH_ITER(hh, allocations, found, tmp) { LOG_DEBUG("> %p %lu bytes", found->handle, (unsigned long)found->bytes); }
/** * Returns the ReferentEntry for the specified object or creates one and adds * it to the referents hash if none exists. referentsLock MUST be held. */ static ReferentEntry* getReferentEntryForObject(Env* env, Object* o) { void* key = (void*) GC_HIDE_POINTER(o); // Hide the pointer from the GC so that the key doesn't prevent the object from being GCed. ReferentEntry* referentEntry; HASH_FIND_PTR(referents, &key, referentEntry); if (!referentEntry) { // Object is not in the hashtable. Add it. referentEntry = allocateMemoryOfKind(env, sizeof(ReferentEntry), referentEntryGCKind); if (!referentEntry) return NULL; // OOM thrown referentEntry->key = key; HASH_ADD_PTR(referents, key, referentEntry); } return referentEntry; }
size_t retreive_size(void *someaddr){ size_t res; hash_t *elem = NULL; HASH_FIND_PTR(size_hash, &someaddr, elem); if(!elem){ fprintf(stderr,"cannot find ptr %p to free!\n",someaddr); return 0; } res = elem->size; if(get_verbose_level()>=DEBUG) printf("Retreiving (%p,%ld)\n",someaddr, res); HASH_DEL( size_hash, elem); return res; }
static void account_realloc(void *p, void *ptr, size_t size) { // Do not account itself no_hook = 1; // ptr == NULL is equivalent to malloc(size) if (ptr == NULL) { account_alloc(p, size); } // size == 0 is equivalent to free(ptr), // and p will be NULL else if (size == 0) { account_alloc(ptr, size); } // Now the real realloc else { log("Realloc: %p -> %d\n", ptr, size); // if ptr was moved previous area will be freed if (p != ptr) { log("Realloc: Replacing pointer %p to %p\n", ptr, p); account_alloc(ptr, 0); account_alloc(p, size); } else { struct malloc_item *found; int alloc_diff; HASH_FIND_PTR(HT, &ptr, found); if (found) { // alloc_diff may be negative when shrinking memory alloc_diff = size - found->size; mem_allocated += alloc_diff; found->size += alloc_diff; log("Realloc: diff %p -> %d\n", ptr, alloc_diff); } else { log("Reallocating unaccounted pointer %p\n", ptr); } } } log(" [[[::: %d (%u) :::]]] \n", mem_allocated, HASH_COUNT(HT)); no_hook = 0; }
inline js_proxy_t *js_get_or_create_proxy(JSContext *cx, T *native_obj) { js_proxy_t *proxy; HASH_FIND_PTR(_native_js_global_ht, &native_obj, proxy); if (!proxy) { js_type_class_t *typeProxy = js_get_type_from_native<T>(native_obj); assert(typeProxy); JSObject* js_obj = JS_NewObject(cx, typeProxy->jsclass, typeProxy->proto, typeProxy->parentProto); JS_NEW_PROXY(proxy, native_obj, js_obj); #ifdef DEBUG JS_AddNamedObjectRoot(cx, &proxy->obj, typeid(*native_obj).name()); #else JS_AddObjectRoot(cx, &proxy->obj); #endif return proxy; } else { return proxy; } return NULL; }