void Method::add_vtable_patch(void *patch) { Global_Env * vm_env = VM_Global_State::loader_env; vm_env->p_vtable_patch_lock->_lock(); // vvv if (_vtable_patch == NULL) { VTable_Patches *vp = (VTable_Patches *)STD_MALLOC(sizeof(VTable_Patches)); memset(vp, 0, sizeof(VTable_Patches)); _vtable_patch = vp; } VTable_Patches *curr_vp = _vtable_patch; for (int i = 0; i < MAX_VTABLE_PATCH_ENTRIES; i++) { if (curr_vp->patch_table[i] == NULL) { curr_vp->patch_table[i] = patch; vm_env->p_vtable_patch_lock->_unlock(); // ^^ return; } } VTable_Patches *new_vp = (VTable_Patches *)STD_MALLOC(sizeof(VTable_Patches)); memset(new_vp, 0, sizeof(VTable_Patches)); new_vp->next = curr_vp; _vtable_patch = new_vp; new_vp->patch_table[0] = patch; vm_env->p_vtable_patch_lock->_unlock(); // ^^^ } //Method::add_vtable_patch
void verifier_metadata_initialize(Heap_Verifier* heap_verifier) { Heap_Verifier_Metadata* heap_verifier_metadata = (Heap_Verifier_Metadata* )STD_MALLOC(sizeof(Heap_Verifier_Metadata)); assert(heap_verifier_metadata); memset(heap_verifier_metadata, 0, sizeof(Heap_Verifier_Metadata)); unsigned int seg_size = GC_VERIFIER_METADATA_SIZE_BYTES + GC_VERIFIER_METADATA_BLOCK_SIZE_BYTES; void* metadata = STD_MALLOC(seg_size); assert(metadata); memset(metadata, 0, seg_size); heap_verifier_metadata->segments[0] = metadata; metadata = (void*)round_up_to_size((POINTER_SIZE_INT)metadata, GC_VERIFIER_METADATA_BLOCK_SIZE_BYTES); heap_verifier_metadata->num_alloc_segs = 1; unsigned int i = 0; unsigned int num_blocks = GC_VERIFIER_METADATA_SIZE_BYTES/GC_VERIFIER_METADATA_BLOCK_SIZE_BYTES; for(i=0; i<num_blocks; i++){ Vector_Block* block = (Vector_Block*)((POINTER_SIZE_INT)metadata + i*GC_VERIFIER_METADATA_BLOCK_SIZE_BYTES); vector_block_init(block, GC_VERIFIER_METADATA_BLOCK_SIZE_BYTES); } unsigned num_tasks = num_blocks>>1; heap_verifier_metadata->free_task_pool = sync_pool_create(); for(i=0; i<num_tasks; i++){ Vector_Block *block = (Vector_Block*)((POINTER_SIZE_INT)metadata + i*GC_VERIFIER_METADATA_BLOCK_SIZE_BYTES); vector_stack_init((Vector_Block*)block); pool_put_entry(heap_verifier_metadata->free_task_pool, (void*)block); } heap_verifier_metadata->free_set_pool = sync_pool_create(); for(; i<num_blocks; i++){ POINTER_SIZE_INT block = (POINTER_SIZE_INT)metadata + i*GC_VERIFIER_METADATA_BLOCK_SIZE_BYTES; pool_put_entry(heap_verifier_metadata->free_set_pool, (void*)block); } heap_verifier_metadata->mark_task_pool = sync_pool_create(); heap_verifier_metadata->root_set_pool = sync_pool_create(); heap_verifier_metadata->objects_pool_before_gc = sync_pool_create(); heap_verifier_metadata->objects_pool_after_gc = sync_pool_create(); heap_verifier_metadata->resurrect_objects_pool_before_gc = sync_pool_create(); heap_verifier_metadata->resurrect_objects_pool_after_gc = sync_pool_create(); heap_verifier_metadata->new_objects_pool = sync_pool_create(); heap_verifier_metadata->hashcode_pool_before_gc = sync_pool_create(); heap_verifier_metadata->hashcode_pool_after_gc = sync_pool_create(); heap_verifier_metadata->obj_with_fin_pool= sync_pool_create(); heap_verifier_metadata->finalizable_obj_pool= sync_pool_create(); verifier_metadata = heap_verifier_metadata; heap_verifier->heap_verifier_metadata = heap_verifier_metadata; return; }
/*Malloc and initialize fake blocks for LOS_Shrink*/ void gc_space_tuner_init_fake_blocks_for_los_shrink(GC* gc) { Blocked_Space* mspace = (Blocked_Space*)gc_get_mos((GC_Gen*)gc); Space_Tuner* tuner = gc->tuner; Block_Header* mos_first_block = (Block_Header*)&mspace->blocks[0]; unsigned int trans_blocks = (unsigned int)(tuner->tuning_size >> GC_BLOCK_SHIFT_COUNT); tuner->interim_blocks = (Block_Header*)STD_MALLOC(trans_blocks * sizeof(Block_Header)); Block_Header* los_trans_fake_blocks = tuner->interim_blocks; memset(los_trans_fake_blocks, 0, trans_blocks * sizeof(Block_Header)); void* trans_base = (void*)((POINTER_SIZE_INT)mos_first_block - tuner->tuning_size); unsigned int start_idx = GC_BLOCK_INDEX_FROM(gc->heap_start, trans_base); Block_Header* last_block = los_trans_fake_blocks; for(unsigned int i = 0; i < trans_blocks; i ++){ Block_Header* curr_block = &los_trans_fake_blocks[i]; curr_block->block_idx = start_idx + i; curr_block->base = (void*)((POINTER_SIZE_INT)trans_base + i * GC_BLOCK_SIZE_BYTES + GC_BLOCK_HEADER_SIZE_BYTES); curr_block->free = curr_block->base ; curr_block->new_free = curr_block->free; curr_block->ceiling = (void*)((POINTER_SIZE_INT)curr_block->base + GC_BLOCK_BODY_SIZE_BYTES); curr_block->status = BLOCK_COMPACTED; #ifdef USE_32BITS_HASHCODE curr_block->hashcode_buf = hashcode_buf_create(); #endif last_block->next = curr_block; last_block = curr_block; } last_block->next = mos_first_block; }
M2nFrame* m2n_push_suspended_frame(VM_thread* thread, Registers* regs) { M2nFrame* m2nf = (M2nFrame*)STD_MALLOC(sizeof(M2nFrame)); assert(m2nf); m2n_push_suspended_frame(thread, m2nf, regs); return m2nf; }
void insert_object_location(GC_Thread *gc_thread, void *dest, Partial_Reveal_Object *p_obj) { assert ((p_obj->get_obj_info() & FORWARDING_BIT_MASK) == FORWARDING_BIT_MASK); // Make sure we have the forwarding bit. Obj_Info_Type orig_obj_info = p_obj->get_obj_info() & ~FORWARDING_BIT_MASK; // The original obj_info without the forwarding bit set. if (orig_obj_info) { // obj_info is not zero so remember it. object_lock_save_info *obj_info = (object_lock_save_info *) STD_MALLOC(sizeof(object_lock_save_info)); if (!obj_info) { DIE("Internal but out of c malloc space."); } // Save what needs to be restored. obj_info->obj_header = orig_obj_info; // I need to keep track of the new after-slided address obj_info->p_obj = (Partial_Reveal_Object *) dest; gc_thread->insert_object_header_info_during_sliding_compaction(obj_info); gc_trace (p_obj, "Object being compacted or colocated needs obj_info perserved."); } assert ((p_obj->get_obj_info() & FORWARDING_BIT_MASK) == FORWARDING_BIT_MASK); // Make sure we have the forwarding bit. // clobber the header with the new address. assert (dest); assert (((POINTER_SIZE_INT)dest | FORWARDING_BIT_MASK) != (POINTER_SIZE_INT)dest); // This might break on Linux if the heap is in the upper 2 gig of memory. (high bit set) // If it does we need to change to the low bit. p_obj->set_forwarding_pointer(dest); gc_trace (p_obj, "Insert new object location for this object"); gc_trace (dest, "Eventual object location installed."); }
GC* gc_gen_create() { GC* gc = (GC*)STD_MALLOC(sizeof(GC_Gen)); assert(gc); memset(gc, 0, sizeof(GC_Gen)); return gc; }
// Notify the given JIT whenever this method is recompiled or initially compiled. // The callback_data pointer will be passed back to the JIT during the callback. // The JIT's callback function is JIT_recompiled_method_callback. void Method::register_jit_recompiled_method_callback(JIT *jit_to_be_notified, Method* caller, void *callback_data) { // Don't insert the same entry repeatedly on the _notify_recompiled_records list. Method_Change_Notification_Record *nr = _notify_recompiled_records; while (nr != NULL) { if (nr->equals(jit_to_be_notified, callback_data)) { return; } nr = nr->next; } // Insert a new notification record. Method_Change_Notification_Record *new_nr = (Method_Change_Notification_Record *)STD_MALLOC(sizeof(Method_Change_Notification_Record)); new_nr->caller = caller; new_nr->jit = jit_to_be_notified; new_nr->callback_data = callback_data; new_nr->next = _notify_recompiled_records; _notify_recompiled_records = new_nr; // Record a callback in the caller method to let it unregister itself if unloaded. ClassLoader* this_loader = get_class()->get_class_loader(); ClassLoader* caller_loader = caller->get_class()->get_class_loader(); if (this_loader == caller_loader || caller_loader->IsBootstrap()) return; MethodSet *vec = caller->_recompilation_callbacks; if (vec == NULL) { vec = caller->_recompilation_callbacks = new MethodSet(); } vec->push_back(this); } //Method::register_jit_recompiled_method_callback
StackIterator * si_create_from_native(VM_thread * thread) { ASSERT_NO_INTERPRETER // Allocate iterator StackIterator * si = (StackIterator *)STD_MALLOC(sizeof(StackIterator)); si_fill_from_native(si, thread); return si; }
void gc_gen_stats_initialize(GC_Gen* gc) { GC_Gen_Stats* stats = (GC_Gen_Stats*)STD_MALLOC(sizeof(GC_Gen_Stats)); memset(stats, 0, sizeof(GC_Gen_Stats)); stats->is_los_collected = FALSE; gc->stats = stats; }
void gc_space_tuner_initialize(GC* gc) { Space_Tuner* tuner = (Space_Tuner*)STD_MALLOC(sizeof(Space_Tuner)); assert(tuner); memset(tuner, 0, sizeof(Space_Tuner)); tuner->kind = TRANS_NOTHING; tuner->tuning_size = 0; gc->tuner = tuner; }
void sd_init_crash_handler() { // Get current directory char buf[PATH_MAX + 1]; char* cwd = getcwd(buf, sizeof(buf)); if (cwd) { cwd = (char*)STD_MALLOC(strlen(cwd) + 1); g_curdir = cwd; if (cwd) strcpy(cwd, buf); } // Get command line sprintf(buf, "/proc/%d/cmdline", getpid()); int file = open(buf, O_RDONLY); if (file > 0) { size_t size = 0; char rdbuf[256]; ssize_t rd; do { rd = read(file, rdbuf, sizeof(rdbuf)); size += (rd > 0) ? rd : 0; } while (rd == sizeof(rdbuf)); if (size) { char* cmd = (char*)STD_MALLOC(size + 1); g_cmdline = cmd; if (cmd) { cmd[size] = '\0'; lseek(file, 0, SEEK_SET); read(file, cmd, size); } } close(file); } }
void initialize_vm_cmd_state(Global_Env *p_env, JavaVMInitArgs* arguments) { p_env->vm_arguments.version = arguments->version; p_env->vm_arguments.nOptions = arguments->nOptions; p_env->vm_arguments.ignoreUnrecognized = arguments->ignoreUnrecognized; JavaVMOption *options = p_env->vm_arguments.options = (JavaVMOption*)STD_MALLOC(sizeof(JavaVMOption) * (arguments->nOptions)); assert(options); memcpy(options, arguments->options, sizeof(JavaVMOption) * (arguments->nOptions)); } //initialize_vm_cmd_state
StackIterator * si_create_from_registers(Registers * regs, bool is_ip_past, M2nFrame * lm2nf) { ASSERT_NO_INTERPRETER // Allocate iterator StackIterator * si = (StackIterator *)STD_MALLOC(sizeof(StackIterator)); assert(si); si_fill_from_registers(si, regs, is_ip_past, lm2nf); return si; }
APR_DECLARE(apr_status_t) port_executable_name(char** self_name) { char* buf; /* Dhruwat - haiku porting - start */ /*#if defined(FREEBSD)*/ #if defined(FREEBSD) || defined(HAIKU) /* Dhruwat - haiku porting - end */ Dl_info info; if (dladdr( (const void*)&main, &info) == 0) { return APR_ENOENT; } buf = (char*)STD_MALLOC(strlen(info.dli_fname) + 1); if (!buf) return APR_ENOMEM; strcpy(buf, info.dli_fname); #else char tmpbuf[PATH_MAX + 1]; int n = readlink("/proc/self/exe", tmpbuf, PATH_MAX); if (n == -1) { return apr_get_os_error(); } tmpbuf[n] = '\0'; buf = (char*)STD_MALLOC(n + 1); if (!buf) return APR_ENOMEM; strcpy(buf, tmpbuf); #endif *self_name = buf; return APR_SUCCESS; }
/** * Sets resisters to JVMTI thread */ void vm_set_jvmti_saved_exception_registers(vm_thread_t vm_thread, Registers* regs) { assert(vm_thread); jvmti_thread_t jvmti_thread = &vm_thread->jvmti_thread; if (!jvmti_thread->jvmti_saved_exception_registers) { jvmti_thread->jvmti_saved_exception_registers = (Registers*)STD_MALLOC(sizeof(Registers)); assert(jvmti_thread->jvmti_saved_exception_registers); } *(jvmti_thread->jvmti_saved_exception_registers) = *regs; } // vm_set_jvmti_saved_exception_registers
Vector_Block* gc_verifier_metadata_extend(Pool* pool, Boolean is_set_pool) { /*add a slot to pool point back to verifier_metadata, then we do not need the global var verifer_metadata*/ lock(verifier_metadata->alloc_lock); Vector_Block* block = pool_get_entry(pool); if( block ){ unlock(verifier_metadata->alloc_lock); return block; } unsigned int num_alloced = verifier_metadata->num_alloc_segs; if(num_alloced == METADATA_SEGMENT_NUM){ printf("Run out GC metadata, please give it more segments!\n"); exit(0); } unsigned int seg_size = GC_VERIFIER_METADATA_EXTEND_SIZE_BYTES + GC_VERIFIER_METADATA_BLOCK_SIZE_BYTES; void *new_segment = STD_MALLOC(seg_size); assert(new_segment); memset(new_segment, 0, seg_size); verifier_metadata->segments[num_alloced] = new_segment; new_segment = (void*)round_up_to_size((POINTER_SIZE_INT)new_segment, GC_VERIFIER_METADATA_BLOCK_SIZE_BYTES); verifier_metadata->num_alloc_segs = num_alloced + 1; unsigned int num_blocks = GC_VERIFIER_METADATA_EXTEND_SIZE_BYTES/GC_VERIFIER_METADATA_BLOCK_SIZE_BYTES; unsigned int i=0; for(i=0; i<num_blocks; i++){ Vector_Block* block = (Vector_Block*)((POINTER_SIZE_INT)new_segment + i*GC_VERIFIER_METADATA_BLOCK_SIZE_BYTES); vector_block_init(block, GC_VERIFIER_METADATA_BLOCK_SIZE_BYTES); assert(vector_block_is_empty(block)); } if(is_set_pool){ for(i=0; i<num_blocks; i++){ POINTER_SIZE_INT block = (POINTER_SIZE_INT)new_segment + i*GC_VERIFIER_METADATA_BLOCK_SIZE_BYTES; pool_put_entry(pool, (void*)block); } }else{ for(i=0; i<num_blocks; i++){ Vector_Block *block = (Vector_Block *)((POINTER_SIZE_INT)new_segment + i*GC_VERIFIER_METADATA_BLOCK_SIZE_BYTES); vector_stack_init(block); pool_put_entry(pool, (void*)block); } } block = pool_get_entry(pool); unlock(verifier_metadata->alloc_lock); return block; }
void gc_gen_mode_adapt_init(GC_Gen *gc) { gc->gen_mode_adaptor = (Gen_Mode_Adaptor*)STD_MALLOC( sizeof(Gen_Mode_Adaptor)); Gen_Mode_Adaptor* gen_mode_adaptor = gc->gen_mode_adaptor; gen_mode_adaptor->gen_minor_throughput = 0.0f; /*reset the nongen_minor_throughput: the first default nongen minor (maybe testgc)may caused the result calculated to be zero. so we initial the value to 1.0f here. */ gen_mode_adaptor->nongen_minor_throughput = 1.0f; gen_mode_adaptor->gen_mode_trial_count = 0; gen_mode_adaptor->major_survive_ratio_threshold = 1.0f; gen_mode_adaptor->major_repeat_count = 1; gen_mode_adaptor->adapt_nos_size = min_nos_size_bytes; }
void Class::setup_as_array(Global_Env* env, unsigned char num_dimensions, bool isArrayOfPrimitives, Class* baseClass, Class* elementClass) { m_is_array = 1; m_num_dimensions = (unsigned char)num_dimensions; if(m_num_dimensions == 1) { m_is_array_of_primitives = isArrayOfPrimitives; } else { m_is_array_of_primitives = false; } m_array_element_class = elementClass; m_array_base_class = baseClass; m_state = ST_Initialized; assert(elementClass); // insert Java field, required by spec - 'length I' m_num_fields = 1; m_fields = new Field[1]; m_fields[0].set(this, env->Length_String, env->string_pool.lookup("I"), ACC_PUBLIC|ACC_FINAL); m_fields[0].set_field_type_desc( type_desc_create_from_java_descriptor("I", NULL)); m_fields[0].set_injected(); m_super_class.name = env->JavaLangObject_String; m_super_class.cp_index = 0; m_access_flags = (ACC_FINAL | ACC_ABSTRACT); if(isArrayOfPrimitives) { m_access_flags |= ACC_PUBLIC; } else { // set array access flags the same as in its base class m_access_flags = (uint16)(m_access_flags | (baseClass->get_access_flags() & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED))); } m_package = elementClass->m_package; // array classes implement two interfaces: Cloneable and Serializable m_superinterfaces = (Class_Super*) STD_MALLOC(2 * sizeof(Class_Super)); m_superinterfaces[0].name = env->Clonable_String; m_superinterfaces[0].cp_index = 0; m_superinterfaces[1].name = env->Serializable_String; m_superinterfaces[1].cp_index = 0; m_num_superinterfaces = 2; }
// Adding dynamic generated code info to global list void compile_add_dynamic_generated_code_chunk(const char* name, bool free_name, const void* address, size_t length) { DynamicCode *dc = (DynamicCode *)STD_MALLOC(sizeof(DynamicCode)); assert(dc); dc->name = name; dc->free_name = free_name; dc->address = address; dc->length = length; // Synchronizing access to dynamic code list LMAutoUnlock dcll(VM_Global_State::loader_env->p_dclist_lock); DynamicCode** pdcList = &VM_Global_State::loader_env->dcList; dc->next = *pdcList; *pdcList = dc; }
// Create an exception from a given type and a message. // Set cause to the current thread exception. static void compile_raise_exception(const char* name, const char* message, Method* method) { assert(hythread_is_suspend_enabled()); jthrowable old_exc = exn_get(); exn_clear(); const char* c = method->get_class()->get_name()->bytes; const char* m = method->get_name()->bytes; const char* d = method->get_descriptor()->bytes; size_t sz = 3 + // a space, a dot, and a terminator strlen(message) + method->get_class()->get_name()->len + method->get_name()->len + method->get_descriptor()->len; char* msg_raw = (char*)STD_MALLOC(sz); assert(msg_raw); sprintf(msg_raw, "%s%s.%s%s", message, c, m, d); assert(strlen(msg_raw) < sz); jthrowable new_exc = exn_create(name, msg_raw, old_exc); exn_raise_object(new_exc); STD_FREE(msg_raw); }
int port_thread_attach() { int res; port_tls_data_t* tlsdata; if (!port_shared_data && (res = init_port_shared_data()) != 0) return res; if (get_private_tls_data()) return 0; tlsdata = (port_tls_data_t*)STD_MALLOC(sizeof(port_tls_data_t)); if (!tlsdata) return ENOMEM; res = port_thread_attach_local(tlsdata, FALSE, TRUE, 0); if (res != 0) STD_FREE(tlsdata); return res; }
Class* resolve_class_array_of_class(Global_Env* env, Class* cc) { // If the element type is primitive, return one of the preloaded // classes of arrays of primitive types. if (cc->is_primitive()) { if (cc == env->Boolean_Class) { return env->ArrayOfBoolean_Class; } else if (cc == env->Byte_Class) { return env->ArrayOfByte_Class; } else if (cc == env->Char_Class) { return env->ArrayOfChar_Class; } else if (cc == env->Short_Class) { return env->ArrayOfShort_Class; } else if (cc == env->Int_Class) { return env->ArrayOfInt_Class; } else if (cc == env->Long_Class) { return env->ArrayOfLong_Class; } else if (cc == env->Float_Class) { return env->ArrayOfFloat_Class; } else if (cc == env->Double_Class) { return env->ArrayOfDouble_Class; } } char *array_name = (char *)STD_MALLOC(cc->get_name()->len + 5); if(cc->get_name()->bytes[0] == '[') { sprintf(array_name, "[%s", cc->get_name()->bytes); } else { sprintf(array_name, "[L%s;", cc->get_name()->bytes); } String *arr_str = env->string_pool.lookup(array_name); STD_FREE(array_name); Class* arr_clss = cc->get_class_loader()->LoadVerifyAndPrepareClass(env, arr_str); return arr_clss; } // resolve_class_array_of_class
void mutator_initialize(GC* gc, void *unused_gc_information) { /* FIXME:: make sure gc_info is cleared */ Mutator *mutator = (Mutator *)STD_MALLOC(sizeof(Mutator)); memset(mutator, 0, sizeof(Mutator)); mutator->alloc_space = gc_get_nos((GC_Gen*)gc); mutator->gc = gc; if(gc_is_gen_mode()){ mutator->rem_set = free_set_pool_get_entry(gc->metadata); assert(vector_block_is_empty(mutator->rem_set)); } mutator->dirty_set = free_set_pool_get_entry(gc->metadata); if(!IGNORE_FINREF ) mutator->obj_with_fin = finref_get_free_block(gc); else mutator->obj_with_fin = NULL; #ifdef USE_UNIQUE_MARK_SWEEP_GC allocator_init_local_chunks((Allocator*)mutator); #endif lock(gc->mutator_list_lock); // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv mutator->next = (Mutator *)gc->mutator_list; gc->mutator_list = mutator; gc->num_mutators++; /*Begin to measure the mutator thread execution time. */ mutator->time_measurement_start = time_now(); unlock(gc->mutator_list_lock); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ gc_set_tls(mutator); return; }
void parse_vm_arguments2(Global_Env *p_env) { bool version_printed = false; #ifdef _DEBUG TRACE("p_env->vm_arguments.nOptions = " << p_env->vm_arguments.nOptions); for (int _i = 0; _i < p_env->vm_arguments.nOptions; _i++) TRACE("p_env->vm_arguments.options[ " << _i << "] = " << p_env->vm_arguments.options[_i].optionString); #endif //_DEBUG apr_pool_t *pool; apr_pool_create(&pool, 0); for (int i = 0; i < p_env->vm_arguments.nOptions; i++) { const char* option = p_env->vm_arguments.options[i].optionString; if (begins_with(option, XBOOTCLASSPATH)) { /* * Override for bootclasspath - * set in the environment- the boot classloader will be responsible for * processing and setting up "vm.boot.class.path" and "sun.boot.class.path" * Note that in the case of multiple arguments, the last one will be used */ p_env->VmProperties()->set(XBOOTCLASSPATH, option + strlen(XBOOTCLASSPATH)); } else if (begins_with(option, XBOOTCLASSPATH_A)) { /* * addition to append to boot classpath * set in environment - responsibility of boot classloader to process * Note that we accumulate if multiple, appending each time */ char *bcp_old = p_env->VmProperties()->get(XBOOTCLASSPATH_A); const char *value = option + strlen(XBOOTCLASSPATH_A); char *bcp_new = NULL; if (bcp_old) { char *tmp = (char *) STD_MALLOC(strlen(bcp_old) + strlen(PORT_PATH_SEPARATOR_STR) + strlen(value) + 1); strcpy(tmp, bcp_old); strcat(tmp, PORT_PATH_SEPARATOR_STR); strcat(tmp, value); bcp_new = tmp; } p_env->VmProperties()->set(XBOOTCLASSPATH_A, bcp_old ? bcp_new : value); p_env->VmProperties()->destroy(bcp_old); STD_FREE((void*)bcp_new); } else if (begins_with(option, XBOOTCLASSPATH_P)) { /* * addition to prepend to boot classpath * set in environment - responsibility of boot classloader to process * Note that we accumulate if multiple, prepending each time */ char *bcp_old = p_env->VmProperties()->get(XBOOTCLASSPATH_P); const char *value = option + strlen(XBOOTCLASSPATH_P); char *bcp_new = NULL; if (bcp_old) { char *tmp = (char *) STD_MALLOC(strlen(bcp_old) + strlen(PORT_PATH_SEPARATOR_STR) + strlen(value) + 1); strcpy(tmp, value); strcat(tmp, PORT_PATH_SEPARATOR_STR); strcat(tmp, bcp_old); bcp_new = tmp; } p_env->VmProperties()->set(XBOOTCLASSPATH_P, bcp_old ? bcp_new : value); p_env->VmProperties()->destroy(bcp_old); STD_FREE((void*)bcp_new); } else if (begins_with(option, "-Xjit:")) { // Do nothing here, just skip this option for later parsing } else if (strcmp(option, "-Xint") == 0) { p_env->VmProperties()->set("vm.use_interpreter", "true"); #ifdef VM_STATS } else if (begins_with(option, "-Xstats:")) { vm_print_total_stats = true; const char* arg = option + strlen("-Xstats:"); vm_print_total_stats_level = atoi(arg); #endif } else if (strcmp(option, "-version") == 0) { // Print the version number and exit LECHO_VERSION; log_exit(0); } else if (strcmp(option, "-showversion") == 0) { if (!version_printed) { // Print the version number and continue LECHO_VERSION; version_printed = true; } } else if (strcmp(option, "-fullversion") == 0) { // Print the version number and exit LECHO_VM_VERSION; log_exit(0); } else if (begins_with(option, "-Xgc:")) { // make prop_key to be "gc.<something>" char* prop_key = strdup(option + strlen("-X")); prop_key[2] = '.'; TRACE(prop_key << " = 1"); p_env->VmProperties()->set(prop_key, "1"); free(prop_key); } else if (begins_with(option, "-Xem:")) { const char* arg = option + strlen("-Xem:"); p_env->VmProperties()->set("em.properties", arg); } else if (strcmp(option, "-client") == 0 || strcmp(option, "-server") == 0) { p_env->VmProperties()->set("em.properties", option + 1); } else if (begins_with(option, "-Xms") || begins_with(option, "-ms")) { // cut -Xms || -ms const char* arg = option + (begins_with(option, "-ms") ? 3 : 4); TRACE("gc.ms = " << arg); if (atoi(arg) <= 0) { LECHO(34, "Negative or invalid heap size. Default value will be used!"); } p_env->VmProperties()->set("gc.ms", arg); } else if (begins_with(option, "-Xmx") || begins_with(option, "-mx")) { // cut -Xmx const char* arg = option + (begins_with(option, "-mx") ? 3 : 4); TRACE("gc.mx = " << arg); if (atoi(arg) <= 0) { LECHO(34, "Negative or invalid heap size. Default value will be used!"); } p_env->VmProperties()->set("gc.mx", arg); } else if (begins_with(option, "-Xss")) { const char* arg = option + 4; TRACE("thread.stacksize = " << arg); if (atoi(arg) <= 0) { LECHO(34, "Negative or invalid stack size. Default value will be used!"); } p_env->VmProperties()->set("thread.stacksize", arg); } else if (begins_with(option, STRING_POOL_SIZE_OPTION)) { // the pool is already created } else if (begins_with(option, "-agentlib:")) { p_env->TI->addAgent(option); } else if (begins_with(option, "-agentpath:")) { p_env->TI->addAgent(option); } else if (begins_with(option, "-javaagent:")) { char* dest = (char*) STD_MALLOC(strlen("-agentlib:hyinstrument=") + strlen(option + 11) + 1); strcpy(dest, "-agentlib:hyinstrument="); strcat(dest, option + 11); p_env->TI->addAgent(dest); STD_FREE((void*) dest); } else if (begins_with(option, "-Xrun")) { // Compatibility with JNDI p_env->TI->addAgent(option); } else if (strcmp(option, "-Xnoagent") == 0) { // Do nothing, this option is only for compatibility with old JREs } else if (strcmp(option, "-Xdebug") == 0) { // Do nothing, this option is only for compatibility with old JREs } else if (strcmp(option, "-Xfuture") == 0) { // Do nothing, this option is only for compatibility with old JREs } else if (strcmp(option, "-Xinvisible") == 0) { p_env->retain_invisible_annotations = true; } else if (strcmp(option, "-Xverify") == 0) { p_env->verify_all = true; } else if (strcmp(option, "-Xverify:none") == 0 || strcmp(option, "-noverify") == 0) { p_env->VmProperties()->set("vm.use_verifier", "false"); } else if (strcmp(option, "-Xverify:all") == 0) { p_env->verify_all = true; p_env->verify_strict = true; } else if (strcmp(option, "-Xverify:strict") == 0) { p_env->verify_all = true; p_env->verify_strict = true; } else if (strcmp(option, "-verify") == 0) { p_env->verify_all = true; } else if (begins_with(option, "-verbose")) { // Moved to set_log_levels_from_cmd } else if (begins_with(option, "-Xfileline")) { // Moved to set_log_levels_from_cmd } else if (begins_with(option, "-Xthread")) { // Moved to set_log_levels_from_cmd } else if (begins_with(option, "-Xcategory")) { // Moved to set_log_levels_from_cmd } else if (begins_with(option, "-Xtimestamp")) { // Moved to set_log_levels_from_cmd } else if (begins_with(option, "-Xverbose")) { // Moved to set_log_levels_from_cmd } else if (begins_with(option, "-Xwarn")) { // Moved to set_log_levels_from_cmd } else if (begins_with(option, "-Xfunction")) { // Moved to set_log_levels_from_cmd #ifdef _DEBUG } else if (begins_with(option, "-Xlog")) { // Moved to set_log_levels_from_cmd } else if (begins_with(option, "-Xtrace")) { // Moved to set_log_levels_from_cmd #endif //_DEBUG } else if (strncmp(option, "-D", 2) == 0) { } else if (strncmp(option, "-XD", 3) == 0 || strncmp(option, "-XX:", 4) == 0) { } else if (strcmp(option, "-Xdumpstubs") == 0) { dump_stubs = true; } else if (strcmp(option, "-Xparallel_jit") == 0) { parallel_jit = true; } else if (strcmp(option, "-Xno_parallel_jit") == 0) { parallel_jit = false; } else if (begins_with(option, "-Xdumpfile:")) { const char* arg = option + strlen("-Xdumpfile:"); dump_file_name = arg; } else if (strcmp(option, "_org.apache.harmony.vmi.portlib") == 0) { // Store a pointer to the portlib p_env->portLib = p_env->vm_arguments.options[i].extraInfo; } else if (strcmp(option, "-help") == 0 || strcmp(option, "-h") == 0 || strcmp(option, "-?") == 0) { print_generic_help(); log_exit(0); } else if (strcmp(option,"-X") == 0) { print_help_on_nonstandard_options(); log_exit(0); } else if (begins_with(option, "-enableassertions")) { add_assert_rec(p_env, option, "-enableassertions", true); } else if (begins_with(option, "-ea")) { add_assert_rec(p_env, option, "-ea", true); } else if (begins_with(option, "-disableassertions")) { add_assert_rec(p_env, option, "-disableassertions", false); } else if (begins_with(option, "-da")) { add_assert_rec(p_env, option, "-da", false); } else if (strcmp(option, "-esa") == 0 || strcmp(option, "-enablesystemassertions") == 0) { get_assert_reg(p_env)->enable_system = true; } else if (strcmp(option, "-dsa") == 0 || strcmp(option, "-disablesystemassertions") == 0) { if (p_env->assert_reg) { p_env->assert_reg->enable_system = false; } } else { LECHO(30, "Unknown option {0}" << option); USE_JAVA_HELP; log_exit(1); } } // for apr_pool_destroy(pool); } //parse_vm_arguments2
ncaiError JNICALL ncaiWriteMemory(ncaiEnv* env, void* addr, size_t size, void* buf) { TRACE2("ncai.memory", "WriteMemory called"); if (!env) return NCAI_ERROR_INVALID_ENVIRONMENT; VMBreakPoints* vm_breaks = VM_Global_State::loader_env->TI->vm_brpt; LMAutoUnlock lock(vm_breaks->get_lock()); jbyte* end_addr = (jbyte*)addr + size; VMBreakPoint* cur; size_t rewrite_count = 0; // Count addresses in given range for (cur = vm_breaks->get_first_breakpoint(); cur; cur = vm_breaks->get_next_breakpoint(cur)) { if (cur->addr >= addr && cur->addr < end_addr) ++rewrite_count; } // Simple case: there are no breakpoints in specified address range if (rewrite_count == 0) { if (port_write_memory(addr, size, buf) == 0) return NCAI_ERROR_NONE; else return NCAI_ERROR_ACCESS_DENIED; } // Allocate array for address sorting RewriteArray rwa; rwa.array = (BreakListItem*)STD_MALLOC(rewrite_count*sizeof(BreakListItem)); if (!rwa.array) return NCAI_ERROR_OUT_OF_MEMORY; memset(rwa.array, 0, rewrite_count*sizeof(BreakListItem)); rwa.list = NULL; rwa.size = rewrite_count; rwa.count = 0; // Add matching addresses to sorted list for (cur = vm_breaks->get_first_breakpoint(); cur; cur = vm_breaks->get_next_breakpoint(cur)) { if (cur->addr >= addr && cur->addr < end_addr) add_rewrite_address(&rwa, cur); } // Write memory size_t remain = size; BreakListItem* cur_bla = rwa.list; assert(cur_bla); jbyte* cbuf = (jbyte*)buf; jbyte* cur_addr = (jbyte*)addr; int err = 0; while (remain) { if (!cur_bla || cur_bla->bp->addr > cur_addr) { // Write buffer to memory size_t offset = (size_t)cur_addr - (size_t)addr; size_t chunk_size = cur_bla ? ((jbyte*)cur_bla->bp->addr - cur_addr) : (end_addr - cur_addr); err = port_write_memory(cur_addr, chunk_size, cbuf + offset); if (err != 0) break; cur_addr += chunk_size; remain -= chunk_size; } if (cur_bla) { // Write byte from buffer to 'saved_byte' field in breakpoint assert(cur_addr == cur_bla->bp->addr); size_t offset = (size_t)cur_addr - (size_t)addr; cur_bla->bp->saved_byte = cbuf[offset]; cur_bla = cur_bla->next; ++cur_addr; --remain; } } STD_FREE(rwa.array); return (err == 0) ? NCAI_ERROR_NONE : NCAI_ERROR_ACCESS_DENIED; }
LONG NTAPI vectored_exception_handler_internal(LPEXCEPTION_POINTERS nt_exception) { DWORD code = nt_exception->ExceptionRecord->ExceptionCode; void* fault_addr = nt_exception->ExceptionRecord->ExceptionAddress; Registers regs; // Convert NT context to Registers port_thread_context_to_regs(®s, nt_exception->ContextRecord); // Check if TLS structure is set - probably we should produce minidump port_tls_data_t* tlsdata = get_private_tls_data(); if (!tlsdata) // Tread is not attached - attach thread temporarily { int res; tlsdata = (port_tls_data_t*)STD_MALLOC(sizeof(port_tls_data_t)); if (tlsdata) // Try to attach the thread res = port_thread_attach_local(tlsdata, TRUE, TRUE, 0); if (!tlsdata || res != 0) { // Can't process correctly; perform default actions if (FLAG_CORE) create_minidump(nt_exception); if (FLAG_DBG) { show_debugger_dialog(); // Workaround; EXCEPTION_CONTINUE_SEARCH does not work _exit(-1); return EXCEPTION_CONTINUE_SEARCH; // Assert dialog } _exit(-1); } // SO for alien thread can't be processed out of VEH if (code == STATUS_STACK_OVERFLOW && sd_is_handler_registered(PORT_SIGNAL_STACK_OVERFLOW)) { int result; size_t alt_stack_size = ALT_PAGES_COUNT*tlsdata->guard_page_size; void* alt_stack = map_alt_stack(alt_stack_size); void* stack_bottom = (void*)((POINTER_SIZE_INT)alt_stack + alt_stack_size); if (alt_stack) result = (int)(POINTER_SIZE_INT)port_call_alt_stack( port_process_signal, stack_bottom, 4, PORT_SIGNAL_STACK_OVERFLOW, ®s, fault_addr, FALSE); else result = port_process_signal(PORT_SIGNAL_STACK_OVERFLOW, ®s, fault_addr, FALSE); if (result == 0) { if (port_thread_detach_temporary() == 0) STD_FREE(tlsdata); if (alt_stack) unmap_alt_stack(alt_stack, alt_stack_size); return EXCEPTION_CONTINUE_EXECUTION; } if (FLAG_CORE) { if (alt_stack) port_call_alt_stack(create_minidump, stack_bottom, 1, nt_exception); else create_minidump(nt_exception); } if (alt_stack) unmap_alt_stack(alt_stack, alt_stack_size); if (result > 0) { show_debugger_dialog(); // Workaround; EXCEPTION_CONTINUE_SEARCH does not work _exit(-1); shutdown_signals(); return EXCEPTION_CONTINUE_SEARCH; // Assert dialog } _exit(-1); } } if (tlsdata->produce_core) { create_minidump(nt_exception); if (!tlsdata->debugger) _exit(-1); } if (tlsdata->debugger) { show_debugger_dialog(); // Workaround _exit(-1); // Go to handler to restore CRT/VEH settings and crash once again // port_set_longjump_regs(&prepare_assert_dialog, ®s, 1, ®s); // port_thread_regs_to_context(nt_exception->ContextRecord, ®s); // return EXCEPTION_CONTINUE_EXECUTION; } switch (code) { case STATUS_STACK_OVERFLOW: if (!sd_is_handler_registered(PORT_SIGNAL_STACK_OVERFLOW)) return EXCEPTION_CONTINUE_SEARCH; break; case STATUS_ACCESS_VIOLATION: if (!sd_is_handler_registered(PORT_SIGNAL_GPF)) return EXCEPTION_CONTINUE_SEARCH; break; case JVMTI_EXCEPTION_STATUS: if (!sd_is_handler_registered(PORT_SIGNAL_BREAKPOINT)) return EXCEPTION_CONTINUE_SEARCH; break; case STATUS_INTEGER_DIVIDE_BY_ZERO: case EXCEPTION_FLT_DIVIDE_BY_ZERO: case EXCEPTION_FLT_OVERFLOW: case EXCEPTION_FLT_UNDERFLOW: case EXCEPTION_INT_OVERFLOW: if (!sd_is_handler_registered(PORT_SIGNAL_ARITHMETIC)) return EXCEPTION_CONTINUE_SEARCH; break; default: return EXCEPTION_CONTINUE_SEARCH; } if (code == STATUS_STACK_OVERFLOW) { tlsdata->guard_page_set = FALSE; // GUARD_PAGE was cleared by OS if (!tlsdata->restore_guard_page) tlsdata->restore_guard_page = TRUE; } // Prepare to transfering control out of VEH handler port_set_longjump_regs(&c_handler, ®s, 4, ®s, nt_exception->ExceptionRecord->ExceptionAddress, (void*)(size_t)nt_exception->ExceptionRecord->ExceptionCode, (void*)(size_t)nt_exception->ExceptionRecord->ExceptionFlags); // Convert prepared Registers back to NT context port_thread_regs_to_context(nt_exception->ContextRecord, ®s); // Return from VEH - presumably continue execution return EXCEPTION_CONTINUE_EXECUTION; }
// // Input/Output next_obj_start_arg - a pointer to a pointer to where the // fused objects will eventually reside. Updated to the end of the fused // objects. // bool fuse_objects (GC_Thread *gc_thread, Partial_Reveal_Object *p_obj, void **next_obj_start_arg, unsigned int *problem_locks) { bool UNUSED debug_printf_trigger = false; unsigned int moved_count = 0; unsigned int unmoved_count = 0; // If we can fuse an object we do and return it. assert (p_obj->vt()->get_gcvt()->gc_fuse_info); gc_trace (p_obj, "This object is a candidate for fusing with next object."); Partial_Reveal_Object *scan_stack[MAX_FUSABLE_OBJECT_SCAN_STACK]; unsigned top = 0; Partial_Reveal_Object *fuse_queue[MAX_FUSED_OBJECT_COUNT]; unsigned last = 0; scan_stack[top++] = p_obj; unsigned int fused_size = get_object_size_bytes(p_obj); unsigned int base_obj_size = fused_size; void *to_obj = *next_obj_start_arg; void * UNUSED debug_orig_to_obj = to_obj; // Claim the Forwading bit if you can. If you loose the race you can't fuse since someone else is. Obj_Info_Type old_base_value = p_obj->get_obj_info(); Obj_Info_Type new_base_value = old_base_value; if ((old_base_value & FORWARDING_BIT_MASK) == FORWARDING_BIT_MASK) { return false; // Some other thread is going to move this object. } new_base_value = old_base_value | FORWARDING_BIT_MASK; if (p_obj->compare_exchange(new_base_value, old_base_value) != old_base_value) { // We did not get the forwarding pointer successfully, some other thread got it. // Since this is the base object we can just return false. return false; } // Build a queue of objects to colocate but do not grab the FORWARDING_BIT until the queue is built. while (top > 0) { Partial_Reveal_Object *p_cur_obj = scan_stack[--top]; int *offset_scanner = init_fused_object_scanner(p_cur_obj); Slot pp_next_object(NULL); Partial_Reveal_Object *p_last_object = p_obj; while (pp_next_object.set(p_get_ref(offset_scanner, p_cur_obj)) != NULL) { // Move the scanner to the next reference. offset_scanner = p_next_ref (offset_scanner); // This object is to be fused with the object located at the gc_fuse_info so calculate the required size. Partial_Reveal_Object *p_next_from_obj = pp_next_object.dereference(); gc_trace (p_next_from_obj, "This object is a candidate to be fused with previous object."); if (p_next_from_obj) { // Check NULL. block_info *fuse_block_info = GC_BLOCK_INFO(p_next_from_obj); void * next_natural_obj = (void *) (POINTER_SIZE_INT(p_last_object) + get_object_size_bytes(p_last_object)); Obj_Info_Type new_value = p_next_from_obj->get_obj_info(); bool is_colocation_natural = (next_natural_obj == (void *)p_next_from_obj); bool overflow = (((POINTER_SIZE_INT)to_obj + fused_size + get_object_size_bytes(p_next_from_obj)) > (POINTER_SIZE_INT)(GC_BLOCK_CEILING(to_obj))); bool already_forwarded = ((new_value & FORWARDING_BIT_MASK) == FORWARDING_BIT_MASK); bool in_compaction_block = gc_thread->_p_gc->is_compaction_block(fuse_block_info); bool can_fuse = ((!already_forwarded) && (!is_colocation_natural) && (!overflow) && in_compaction_block ); if (can_fuse){ if (p_next_from_obj->vt()->get_gcvt()->gc_fuse_info) { scan_stack[top++] = p_next_from_obj; } fuse_queue[last] = p_next_from_obj; fused_size += get_object_size_bytes(p_next_from_obj); last++; } else { p_obj->set_obj_info(old_base_value); // Release the forwarding bit and don't colocate this object. return false; } } } } unsigned i; // Grab the forwarding bits for the other object in the queue.. If you can't get a bit // remove the object from the queue. for (i = 0; i < last; i++) { Partial_Reveal_Object *p_fuse_obj = fuse_queue[i]; Obj_Info_Type new_value = p_fuse_obj->get_obj_info(); Obj_Info_Type old_value = new_value; bool already_forwarded = ((new_value & FORWARDING_BIT_MASK) == FORWARDING_BIT_MASK); new_value = old_value | FORWARDING_BIT_MASK; // Create the value with a the forwarding bit set. if (!already_forwarded) { // install the forwarding bit if it has not already been forwarded. already_forwarded = (p_fuse_obj->compare_exchange(new_value, old_value) != old_value); } if (already_forwarded) { debug_printf_trigger = true; TRACE("REMOVING FROM FUSE QUEUE."); // Remove this object from the queue since we can colocate it. unsigned int j; for (j = i; j < last - 1; j++) { fuse_queue[j] = fuse_queue[j+1]; } // We have one less object on the queue. fuse_queue[last] = NULL; last--; i--; // Redo since fuse_queue[i] now holds a new object. unmoved_count++; } gc_trace (p_fuse_obj, "No space so this object is not fused with parent."); } // We don't fuse more than a single block worth of objects. assert (fused_size <= GC_BLOCK_ALLOC_SIZE); // We own all the forwarding bits in all the objects in the fuse_queue. // If we only have the base object and no other object to colocate with it just return. if (last == 0) { p_obj->set_obj_info(old_base_value); // Release the forwarding bit and don't colocate this object. // No objects to relocate. TRACE("3"); return false; } // At this point all objects in the queue will be fused, we have the forwarding bits // so we now figure out where they will be colocated. gc_trace (p_obj, "Fusing this object with offspring."); assert ((POINTER_SIZE_INT)(GC_BLOCK_INFO (to_obj + get_object_size_bytes(p_obj) - 1)) <= (POINTER_SIZE_INT)(GC_BLOCK_CEILING(to_obj))); assert ((p_obj->get_obj_info() & FORWARDING_BIT_MASK) == FORWARDING_BIT_MASK); if (object_info_is_not_zero(p_obj)) { if ((p_obj->get_obj_info() & ~FORWARDING_BIT_MASK) != 0) { object_lock_save_info *obj_info = (object_lock_save_info *) STD_MALLOC(sizeof(object_lock_save_info)); assert(obj_info); // Save what needs to be restored. obj_info->obj_header = p_obj->get_obj_info(); obj_info->obj_header = obj_info->obj_header & ~FORWARDING_BIT_MASK; // Clear forwarding bit. // I need to keep track of the new after-slided address obj_info->p_obj = (Partial_Reveal_Object *) to_obj; gc_thread->insert_object_header_info_during_sliding_compaction(obj_info); *problem_locks = *problem_locks + 1;; // placement code does not deal with this so this is likely to be wrong. gc_trace (p_obj, "Object being fused needs obj_info preserved."); debug_printf_trigger = true; INFO("preserving base fused object header"); } } // Finally deal with this placement, moving the base object first. insert_object_location (gc_thread, to_obj, p_obj); gc_trace (to_obj, " In allocate_forwarding_pointers_for_compaction_live_objects forwarding *to* this location. (vtable not yet legal)"); gc_trace(p_obj, " was forwarded..."); if (verify_live_heap) { add_repointed_info_for_thread(p_obj, (Partial_Reveal_Object *) to_obj, gc_thread->get_id()); } assert (base_obj_size == get_object_size_bytes(p_obj)); to_obj = (void *) ((POINTER_SIZE_INT) to_obj + base_obj_size); // Now figure out where the referent objects belong and set up their forwarding pointers. for (i = 0; i < last; i++) { Partial_Reveal_Object *p_fuse_obj = fuse_queue[i]; unsigned int fused_obj_size = get_object_size_bytes(p_fuse_obj); gc_trace (p_fuse_obj, "Fusing this object with parent."); // Finally deal with this colocations. assert (p_fuse_obj != p_obj); // Nulls should have been filtered out up above. if (object_info_is_not_zero(p_fuse_obj)) { if ((p_fuse_obj->get_obj_info() & ~FORWARDING_BIT_MASK) != 0) { object_lock_save_info *obj_info = (object_lock_save_info *) STD_MALLOC(sizeof(object_lock_save_info)); assert(obj_info); // Save what needs to be restored. obj_info->obj_header = p_fuse_obj->get_obj_info(); obj_info->obj_header = obj_info->obj_header & ~FORWARDING_BIT_MASK; // Clear forwarding bit. // I need to keep track of the new after-slided address obj_info->p_obj = (Partial_Reveal_Object *) to_obj; gc_thread->insert_object_header_info_during_sliding_compaction(obj_info); *problem_locks = *problem_locks + 1;; // placement code does not deal with this so this is likely to be wrong. gc_trace (p_fuse_obj, "Object being fused needs obj_info preserved."); debug_printf_trigger = true; INFO("preserving fused object header"); } } // Counts are not thread safe but it is just an approximation.... moved_count++; // The object in the queue its forwarding bit set. { POINTER_SIZE_INT UNUSED next_available = (POINTER_SIZE_INT)to_obj + get_object_size_bytes(p_fuse_obj) -1; assert ((fuse_queue[i]->get_obj_info() & FORWARDING_BIT_MASK) == FORWARDING_BIT_MASK); assert (next_available <= ((POINTER_SIZE_INT)(GC_BLOCK_CEILING(to_obj)))); } insert_object_location(gc_thread, to_obj, p_fuse_obj); gc_trace (to_obj, " In allocate_forwarding_pointers_for_compaction_live_objects forwarding *to* this location. (vtable not yet legal)"); gc_trace(p_obj, " was forwarded..."); if (verify_live_heap) { add_repointed_info_for_thread(p_fuse_obj, (Partial_Reveal_Object *) to_obj, gc_thread->get_id()); } to_obj = (void *) ((POINTER_SIZE_INT) to_obj + fused_obj_size); } *next_obj_start_arg = to_obj; // Update and return. TRACE("next_obj_start_arg addr: " << next_obj_start_arg << ", old_val " << debug_orig_to_obj << ", new_val " << to_obj); return true; }
int port_thread_create(/* out */osthread_t* phandle, size_t stacksize, int priority, port_threadfunc_t func, void *data) { pthread_t thread; pthread_attr_t attr; pthread_attr_t attr_nosched; struct sched_param param; thread_start_struct_t* startstr; int res; if (!port_shared_data) { res = init_port_shared_data(); /* assert(res); */ /* It's OK to have an error here when Port shared library is not available yet; only signals/crash handling will not be available for the thread */ /* return res; */ } if (!func) return EINVAL; startstr = (thread_start_struct_t*)STD_MALLOC(sizeof(thread_start_struct_t)); if (!startstr) return ENOMEM; pthread_attr_init(&attr); pthread_attr_init(&attr_nosched); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_attr_setdetachstate(&attr_nosched, PTHREAD_CREATE_DETACHED); if (stacksize != 0) { if (stacksize < MINSIGSTKSZ) stacksize = MINSIGSTKSZ; if (port_shared_data) { size_t min_stacksize = /* Let's get alt stack size for normal stack and add guard page size */ ((2*port_shared_data->guard_stack_size + port_shared_data->guard_page_size) /* Roung up to alt stack size */ + port_shared_data->guard_stack_size - 1) & ~(port_shared_data->guard_stack_size - 1); if (stacksize < min_stacksize) stacksize = min_stacksize; } res = pthread_attr_setstacksize(&attr, stacksize); if (res == 0) res = pthread_attr_setstacksize(&attr_nosched, stacksize); if (res) { pthread_attr_destroy(&attr); pthread_attr_destroy(&attr_nosched); STD_FREE(startstr); return res; } } if (priority) { res = pthread_attr_setschedpolicy(&attr, SCHED_FIFO); if (res == 0) { param.sched_priority = priority; res = pthread_attr_setschedparam(&attr, ¶m); } /* This does not work anyway on some Linuses if (res != 0) { pthread_attr_destroy(&attr); pthread_attr_destroy(&attr_nosched); STD_FREE(startstr); return res; }*/ } startstr->fun = func; startstr->arg = data; startstr->stack_size = stacksize; res = pthread_create(&thread, &attr, (pthread_func_t)thread_start_func, startstr); if (res == EPERM) // EPERM relates to scheduling only res = pthread_create(&thread, &attr_nosched, (pthread_func_t)thread_start_func, startstr); pthread_attr_destroy(&attr); pthread_attr_destroy(&attr_nosched); if (res == 0) { *phandle = thread; return 0; } STD_FREE(startstr); return res; }
void gc_gen_collector_stats_initialize(Collector* collector) { GC_Gen_Collector_Stats* stats = (GC_Gen_Collector_Stats*)STD_MALLOC(sizeof(GC_Gen_Collector_Stats)); memset(stats, 0, sizeof(GC_Gen_Collector_Stats)); collector->stats = (void*)stats; }
/* * Class: java_lang_VMClassRegistry * Method: getSystemPackages * Signature: (I)[[Ljava/lang/String; */ JNIEXPORT jobjectArray JNICALL Java_java_lang_VMClassRegistry_getSystemPackages (JNIEnv *jenv, jclass, jint len) { Global_Env* genv = VM_Global_State::loader_env; ClassLoader* cl = static_cast<ClassLoader*> (genv->bootstrap_class_loader); Package_Table* ptab = cl->getPackageTable(); cl->Lock(); unsigned p_num = (unsigned)ptab->size(); if (p_num == (unsigned)len) { cl->Unlock(); return NULL; } const char ** pkgs = (const char **)STD_MALLOC(p_num * 2 * sizeof(char*)); size_t buf_len = 0; unsigned index = 0; for (Package_Table::const_iterator it = ptab->begin(), end = ptab->end(); it != end; ++it) { const char* name = pkgs[index++] = (*it).first->bytes; pkgs[index++] = (*it).second->get_jar(); size_t name_len = (*it).first->len; if (name_len > buf_len) { buf_len = name_len; } } cl->Unlock(); jclass string_class = struct_Class_to_java_lang_Class_Handle(genv->JavaLangString_Class); static Class* aos = genv->LoadCoreClass("[Ljava/lang/String;"); jclass string_array_class = struct_Class_to_java_lang_Class_Handle(aos); assert(string_class); assert(string_array_class); jobjectArray result = NewObjectArray(jenv, p_num, string_array_class, NULL); if (result) { char* buf = (char*)STD_MALLOC(buf_len + 1); p_num *= 2; for (index = 0; index < p_num; ) { jobjectArray pair = NewObjectArray(jenv, 2, string_class, NULL); if (!pair) { break; } SetObjectArrayElement(jenv, result, index/2, pair); char* name = strcpy(buf, pkgs[index++]); for (char* c = name; *c != '\0'; ++c) { if (*c == '/') { *c = '.'; } } jstring jname = NewStringUTF(jenv, name); if (!jname) { break; } SetObjectArrayElement(jenv, pair, 0, jname); const char * jar = pkgs[index++]; if (jar) { jstring js = NewStringUTF(jenv, jar); if (!js) break; SetObjectArrayElement(jenv, pair, 1, js); } } STD_FREE(buf); } STD_FREE(pkgs); assert(result || exn_raised()); return result; }