static void write_barrier_rem_source_obj(Managed_Object_Handle p_obj_holding_ref) { if(obj_need_remember((Partial_Reveal_Object*)p_obj_holding_ref)){ Mutator *mutator = (Mutator *)gc_get_tls(); //FIXME: Release lock. obj_dirty_in_table((Partial_Reveal_Object *) p_obj_holding_ref); mutator_dirtyset_add_entry(mutator, (Partial_Reveal_Object*)p_obj_holding_ref); } }
void mutator_destruct(GC* gc, void *unused_gc_information) { Mutator *mutator = (Mutator *)gc_get_tls(); alloc_context_reset((Allocator*)mutator); lock(gc->mutator_list_lock); // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv #ifdef USE_UNIQUE_MARK_SWEEP_GC allocactor_destruct_local_chunks((Allocator*)mutator); #endif mutator_register_new_obj_size(mutator); volatile Mutator *temp = gc->mutator_list; if (temp == mutator) { /* it is at the head of the list */ gc->mutator_list = temp->next; } else { while (temp->next != mutator) { temp = temp->next; assert(temp); } temp->next = mutator->next; } gc->num_mutators--; unlock(gc->mutator_list_lock); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ if(gc_is_gen_mode()){ /* put back the remset when a mutator exits */ pool_put_entry(gc->metadata->mutator_remset_pool, mutator->rem_set); mutator->rem_set = NULL; } if(mutator->obj_with_fin){ pool_put_entry(gc->finref_metadata->obj_with_fin_pool, mutator->obj_with_fin); mutator->obj_with_fin = NULL; } lock(mutator->dirty_set_lock); if( mutator->dirty_set != NULL){ if(vector_block_is_empty(mutator->dirty_set)) pool_put_entry(gc->metadata->free_set_pool, mutator->dirty_set); else{ /* FIXME:: this condition may be released. */ pool_put_entry(gc->metadata->gc_dirty_set_pool, mutator->dirty_set); mutator->dirty_set = NULL; } } unlock(mutator->dirty_set_lock); STD_FREE(mutator); gc_set_tls(NULL); return; }
/* The implementations are only temporary */ static void gen_write_barrier_rem_slot(Managed_Object_Handle *p_slot, Managed_Object_Handle p_target) { if(p_target >= nos_boundary && p_slot < nos_boundary){ Mutator *mutator = (Mutator *)gc_get_tls(); assert( addr_belongs_to_nos(p_target) && !addr_belongs_to_nos(p_slot)); mutator_remset_add_entry(mutator, (REF*)p_slot); } return; }
void tgprpl_info_show (PurpleConnection *gc, const char *who) { tgl_peer_t *P = tgp_blist_lookup_peer_get (gc_get_data (gc)->TLS, who); if (P) { switch (tgl_get_peer_type (P->id)) { case TGL_PEER_ENCR_CHAT: { tgl_peer_t *parent = tgp_encr_chat_get_partner (gc_get_tls (gc), &P->encr_chat); if (parent) { tgl_do_get_user_info (gc_get_tls (gc), parent->id, 0, tgp_info_load_user_done, P); } break; } case TGL_PEER_CHANNEL: tgl_do_get_channel_info (gc_get_tls (gc), P->id, FALSE, tgp_info_load_channel_done, P); break; case TGL_PEER_USER: tgl_do_get_user_info (gc_get_tls (gc), P->id, 0, tgp_info_load_user_done, P); break; } } }
void tgprpl_chat_join (PurpleConnection *gc, GHashTable *data) { debug ("tgprpl_chat_join()"); g_return_if_fail(data); // auto joins will cause chat joins at a time when the dialogue list is not ready, remember // those chats and join them once the dialogue list is fetched if (! gc_get_data (gc)->dialogues_ready) { g_return_if_fail (data); const char *id = g_hash_table_lookup (data, "id"); if (id) { debug ("attempting to join chat %s while not ready, queue up for later", id); gc_get_data (gc)->pending_joins = g_list_append (gc_get_data (gc)->pending_joins, g_strdup (id)); } return; } // join existing chat by id when the user clicks on a chat in the buddy list void *value = g_hash_table_lookup (data, "id"); if (value && atoi (value)) { tgl_peer_id_t cid = TGL_MK_CHAT(atoi (value)); tgl_peer_t *P = tgl_peer_get (gc_get_tls (gc), cid); if (P) { debug ("joining chat by id %d ...", tgl_get_peer_id (cid)); tgl_do_get_chat_info (gc_get_tls (gc), cid, FALSE, tgp_chat_on_loaded_chat_full_joining, NULL); } else { warning ("Cannot join chat %d, peer not found...", tgl_get_peer_id (cid)); purple_serv_got_join_chat_failed (gc, data); } return; } // join chat by invite link provided in the chat join window const char *link = g_hash_table_lookup (data, "link"); if (str_not_empty (link)) { tgl_do_import_chat_link (gc_get_tls (gc), link, (int)strlen (link), tgp_notify_on_error_gw, NULL); return; } // if a chat with this name doesn't exist yet, prompt to create one const char *subject = g_hash_table_lookup (data, "subject"); if (str_not_empty (subject)) { tgl_peer_t *P = tgl_peer_get_by_name (gc_get_tls (gc), subject); // handle joining chats by print_names as used by the Adium plugin if (P && tgl_get_peer_type (P->id) == TGL_PEER_CHAT) { debug ("joining chat by subject %s ...", subject); tgl_do_get_chat_info (gc_get_tls (gc), P->id, FALSE, tgp_chat_on_loaded_chat_full_joining, NULL); return; } // user creates a new chat by providing its subject the chat join window request_create_chat (gc_get_tls (gc), subject); } }
/*This function is for concurrent mark.*/ static void write_barrier_rem_obj_snapshot(Managed_Object_Handle p_obj_holding_ref) { Mutator *mutator = (Mutator *)gc_get_tls(); REF* p_obj_slot; if(obj_need_take_snapshot((Partial_Reveal_Object*)p_obj_holding_ref)){ if (object_is_array((Partial_Reveal_Object*)p_obj_holding_ref)) { Partial_Reveal_Object* array = (Partial_Reveal_Object*)p_obj_holding_ref; assert(!obj_is_primitive_array(array)); Partial_Reveal_Object* obj_to_snapshot; I_32 array_length = vector_get_length((Vector_Handle) array); for (int i = 0; i < array_length; i++) { p_obj_slot = (REF*)vector_get_element_address_ref((Vector_Handle) array, i); obj_to_snapshot = (Partial_Reveal_Object*)read_slot(p_obj_slot); if (obj_to_snapshot != NULL) mutator_dirtyset_add_entry(mutator, obj_to_snapshot); } }else{ /* scan non-array object */ Partial_Reveal_Object* p_obj = (Partial_Reveal_Object*)p_obj_holding_ref; unsigned int num_refs = object_ref_field_num(p_obj); int *ref_iterator = object_ref_iterator_init(p_obj); Partial_Reveal_Object* obj_to_snapshot; for(unsigned int i=0; i<num_refs; i++){ p_obj_slot = object_ref_iterator_get(ref_iterator+i, p_obj); obj_to_snapshot = (Partial_Reveal_Object*)read_slot(p_obj_slot); if (obj_to_snapshot != NULL) mutator_dirtyset_add_entry(mutator, obj_to_snapshot); } if(is_reference_obj(p_obj)){ REF* p_referent_field = obj_get_referent_field(p_obj); obj_to_snapshot = (Partial_Reveal_Object*)read_slot(p_referent_field); if (obj_to_snapshot != NULL) mutator_dirtyset_add_entry(mutator, obj_to_snapshot); } } obj_mark_gray_in_table((Partial_Reveal_Object *) p_obj_holding_ref); // now, the black-only obj (no gray bit been set) will also be scaned by marker, here mark it to gray to prevent this, just a workaround obj_mark_black_in_table((Partial_Reveal_Object *) p_obj_holding_ref, mutator); obj_dirty_in_table((Partial_Reveal_Object *) p_obj_holding_ref); } }
static void mutator_rem_obj(Managed_Object_Handle p_obj_written) { if( obj_is_remembered((Partial_Reveal_Object*)p_obj_written)) return; Partial_Reveal_Object* p_obj = (Partial_Reveal_Object*)p_obj_written; Obj_Info_Type info = get_obj_info_raw(p_obj); Obj_Info_Type new_info = info | OBJ_REM_BIT; while ( info != new_info) { Obj_Info_Type temp = atomic_casptrsz((volatile POINTER_SIZE_INT*)get_obj_info_addr(p_obj), new_info, info); if (temp == info) break; info = get_obj_info_raw(p_obj); new_info = info | OBJ_REM_BIT; } if(info == new_info) return; /* remembered by other */ Mutator *mutator = (Mutator *)gc_get_tls(); mutator_remset_add_entry(mutator, (REF*)p_obj); return; }
static void gc_object_write_barrier(Managed_Object_Handle p_object) { if( addr_belongs_to_nos(p_object)) return; Mutator *mutator = (Mutator *)gc_get_tls(); REF* p_slot; /* scan array object */ if (object_is_array((Partial_Reveal_Object*)p_object)) { Partial_Reveal_Object* array = (Partial_Reveal_Object*)p_object; assert(!obj_is_primitive_array(array)); I_32 array_length = vector_get_length((Vector_Handle) array); for (int i = 0; i < array_length; i++) { p_slot = (REF*)vector_get_element_address_ref((Vector_Handle) array, i); if( read_slot(p_slot) != NULL && addr_belongs_to_nos(read_slot(p_slot))){ mutator_remset_add_entry(mutator, p_slot); } } return; } /* scan non-array object */ Partial_Reveal_Object* p_obj = (Partial_Reveal_Object*)p_object; unsigned int num_refs = object_ref_field_num(p_obj); int *ref_iterator = object_ref_iterator_init(p_obj); for(unsigned int i=0; i<num_refs; i++){ p_slot = object_ref_iterator_get(ref_iterator+i, p_obj); if( addr_belongs_to_nos(read_slot(p_slot))){ mutator_remset_add_entry(mutator, p_slot); } } return; }