OBJECT_PTR get_an_object_from_black() { #ifdef GC_USES_HASHTABLE OBJECT_PTR obj = (OBJECT_PTR)(((hashtable_entry_t *)(hashtable_get_any_element(black)))->ptr); assert(is_valid_object(obj)); #else //we can pick any object, //picking the root for convenience OBJECT_PTR obj = (OBJECT_PTR)*(OBJECT_PTR *)black->root->left->key; #endif return obj; }
void free_all_objects() { gc(true, false); unsigned int count = memory_deallocated(); //assert(!is_set_empty(BLACK)); while(!is_set_empty(BLACK)) { OBJECT_PTR obj = get_an_object_from_black(); assert(is_valid_object(obj)); dealloc(obj); remove_node(BLACK, obj); } //printf("%d words freed during cleanup\n", memory_deallocated() - count); }
void free_white_set_objects() { while(!is_set_empty(WHITE)) { #ifdef GC_USES_HASHTABLE hashtable_entry_t *e = hashtable_get_any_element(white); assert(e); OBJECT_PTR obj = (OBJECT_PTR)(e->ptr); assert(is_valid_object(obj)); #else rb_red_blk_node *white_obj = white->root->left; OBJECT_PTR obj = *((OBJECT_PTR *)(white_obj->key)); #endif if(!value_exists(BLACK, obj)) dealloc(obj); remove_node(WHITE, obj); } }
/** * General function to set value of local variable. * @param var_type type of the local variable * @param p_value pointer to the new variable value */ static jvmtiError set_local(jvmtiEnv* env, jthread thread, jint depth, jint slot, VM_Data_Type var_type, void* p_value) { SuspendEnabledChecker sec; /* * Check given env & current phase. */ jvmtiPhase phases[] = {JVMTI_PHASE_LIVE}; CHECK_EVERYTHING(); CHECK_CAPABILITY(can_access_local_variables); // check error condition: JVMTI_ERROR_INVALID_THREAD // check error condition: JVMTI_ERROR_THREAD_NOT_ALIVE // check error condition: JVMTI_ERROR_ILLEGAL_ARGUMENT jvmtiError err = GetLocal_checkArgs(env, &thread, depth, slot, p_value); if (err != JVMTI_ERROR_NONE) return err; // check error condition: JVMTI_ERROR_INVALID_OBJECT if (VM_DATA_TYPE_CLASS == var_type && ! is_valid_object(env, *(jobject*) p_value)) return JVMTI_ERROR_INVALID_OBJECT; bool thread_suspended = false; // Suspend thread before getting stacks vm_thread_t vm_thread; if (NULL != thread) { // Check that this thread is not current vm_thread = jthread_get_vm_thread_ptr_safe(thread); if (vm_thread != p_TLS_vmthread) { IDATA UNREF status = hythread_suspend_other((hythread_t)vm_thread); assert(TM_ERROR_NONE == status); thread_suspended = true; } } else vm_thread = p_TLS_vmthread; if (interpreter_enabled()) { // TODO: check error condition: JVMTI_ERROR_INVALID_SLOT // TODO: check error condition: JVMTI_ERROR_TYPE_MISMATCH // TODO: check error condition: JVMTI_ERROR_OPAQUE_FRAME // TODO: check error condition: JVMTI_ERROR_NO_MORE_FRAMES switch (var_type) { case VM_DATA_TYPE_CLASS: err = interpreter.interpreter_ti_setObject(env, vm_thread, depth, slot, *(jobject*) p_value); break; case VM_DATA_TYPE_INT32: case VM_DATA_TYPE_F4: err = interpreter.interpreter_ti_setLocal32(env, vm_thread, depth, slot, *(int*) p_value); break; case VM_DATA_TYPE_INT64: case VM_DATA_TYPE_F8: err = interpreter.interpreter_ti_setLocal64(env, vm_thread, depth, slot, *(int64*) p_value); break; default: DIE(("Error: unrecognized local variable type")); } } else { GET_JIT_FRAME_CONTEXT; tmn_suspend_disable(); OpenExeJpdaError result; switch (var_type) { case VM_DATA_TYPE_CLASS: if (NULL != *(jobject*) p_value) result = jit->set_local_var(method, jfc, slot, VM_DATA_TYPE_CLASS, &(*(ObjectHandle*) p_value)->object); else { ManagedObject *n = (ManagedObject *)VM_Global_State::loader_env->managed_null; result = jit->set_local_var(method, jfc, slot, VM_DATA_TYPE_CLASS, &n); } break; case VM_DATA_TYPE_INT32: case VM_DATA_TYPE_F4: case VM_DATA_TYPE_INT64: case VM_DATA_TYPE_F8: result = jit->set_local_var(method, jfc, slot, var_type, p_value); break; default: DIE(("Error: unrecognized local variable type")); } si_free(si); tmn_suspend_enable(); err = jvmti_translate_jit_error(result); } if (thread_suspended) hythread_resume((hythread_t)vm_thread); return err; }
OBJECT_PTR eval_backquote(OBJECT_PTR form) { OBJECT_PTR car_obj; assert(is_valid_object(form)); if(is_atom(form)) return form; car_obj = car(form); assert(is_valid_object(car_obj)); if(IS_SYMBOL_OBJECT(car_obj)) { char buf[SYMBOL_STRING_SIZE]; print_symbol(car_obj, buf); if(car_obj == COMMA) { OBJECT_PTR temp = compile(CADR(form), NIL); #ifdef WIN32 if(temp == ERROR1) #else if(temp == ERROR) #endif { throw_generic_exception("Backquote evaluation(1): compile failed"); return NIL; } reg_next_expression = cons(cons(FRAME, cons(cons(CONS_HALT_NIL, CADR(form)), cons(temp, CADR(form)))), CADR(form)); reg_current_value_rib = NIL; while(car(reg_next_expression) != NIL) { //print_object(car(reg_next_expression));printf("\n");getchar(); eval(false); if(in_error) { throw_generic_exception("Evaluation of backquote failed(1)"); return NIL; } } reg_next_expression = cons(CONS_RETURN_NIL, cdr(reg_next_expression)); reg_current_value_rib = NIL; return reg_accumulator; } } if(form_contains_comma_at(form)) { //1. loop through elements in form //2. if element is not comma-at, call eval_backquote on // it and append it to the result list without splicing //3. if it is comma-at, get its symbol value and // splice the value to the result list //4. return the result list OBJECT_PTR result = NIL; OBJECT_PTR rest = form; while(rest != NIL) { OBJECT_PTR ret; OBJECT_PTR obj; if(IS_CONS_OBJECT(car(rest)) && IS_SYMBOL_OBJECT(CAAR(rest))) { char buf[SYMBOL_STRING_SIZE]; print_symbol(CAAR(rest), buf); if(CAAR(rest) == COMMA_AT) { OBJECT_PTR temp = compile(CADAR(rest), NIL); #ifdef WIN32 if(temp == ERROR1) #else if(temp == ERROR) #endif { throw_generic_exception("Backquote evaluation(2): compile failed"); return NIL; } reg_next_expression = cons(cons(FRAME, cons(cons(CONS_HALT_NIL, CADAR(rest)), cons(temp, CADAR(rest)))), CADAR(rest)); reg_current_value_rib = NIL; while(car(reg_next_expression) != NIL) { eval(false); if(in_error) { throw_generic_exception("Evaluation of backquote failed(2)"); return NIL; } } reg_next_expression = cons(CONS_RETURN_NIL, cdr(reg_next_expression)); reg_current_value_rib = NIL; obj = reg_accumulator; if(result == NIL) result = obj; else set_heap(last_cell(result) & POINTER_MASK, 1, obj); } else { obj = eval_backquote(car(rest)); if(result == NIL) result = cons(obj, NIL); else set_heap(last_cell(result) & POINTER_MASK, 1, cons(obj, NIL)); } } else { obj = eval_backquote(car(rest)); if(result == NIL) result = cons(obj, NIL); else set_heap(last_cell(result) & POINTER_MASK, 1, cons(obj, NIL)); } rest = cdr(rest); } return result; } return cons(eval_backquote(car(form)), eval_backquote(cdr(form))); }
void dealloc(OBJECT_PTR ptr) { unsigned int prev_words_deallocated = words_deallocated; if(!is_valid_object(ptr)) { printf("%d\n", ptr); assert(false); } unsigned int tag = ptr & BIT_MASK; OBJECT_PTR array_size; switch(tag) { case CONS_TAG: words_deallocated += 2; break; case ARRAY_TAG: array_size = *((OBJECT_PTR *)extract_ptr(ptr)); words_deallocated += (array_size + 1); break; case CLOSURE_TAG: words_deallocated += 4; break; case MACRO_TAG: words_deallocated += 4; break; case CONTINUATION_TAG: words_deallocated += 1; break; case INTEGER_TAG: words_deallocated += 1; break; case FLOAT_TAG: words_deallocated += 1; break; /* case FUNCTION2_TAG: */ /* words_allocated += 2; */ /* break; */ /* case MACRO2_TAG: */ /* words_allocated += 2; */ /* break; */ case NATIVE_FN_TAG: words_deallocated += 1; break; default: assert(false); } uintptr_t p = extract_ptr(ptr); int i; for(i=0; i < words_deallocated - prev_words_deallocated; i++) *((OBJECT_PTR *)p+i) = 0xFEEEFEEE; #ifdef WIN32 __mingw_aligned_free((void *)extract_ptr(ptr)); #else free((void *)extract_ptr(ptr)); #endif }