jvmtiError JvmtiManageCapabilities::add_capabilities(const jvmtiCapabilities *current, const jvmtiCapabilities *prohibited, const jvmtiCapabilities *desired, jvmtiCapabilities *result) { // check that the capabilities being added are potential capabilities jvmtiCapabilities temp; get_potential_capabilities(current, prohibited, &temp); if (has_some(exclude(desired, &temp, &temp))) { return JVMTI_ERROR_NOT_AVAILABLE; } // add to the set of ever acquired capabilities either(&acquired_capabilities, desired, &acquired_capabilities); // onload capabilities that got added are now permanent - so, also remove from onload both(&onload_capabilities, desired, &temp); either(&always_capabilities, &temp, &always_capabilities); exclude(&onload_capabilities, &temp, &onload_capabilities); // same for solo capabilities (transferred capabilities in the remaining sets handled as part of standard grab - below) both(&onload_solo_capabilities, desired, &temp); either(&always_solo_capabilities, &temp, &always_solo_capabilities); exclude(&onload_solo_capabilities, &temp, &onload_solo_capabilities); // remove solo capabilities that are now taken exclude(&always_solo_remaining_capabilities, desired, &always_solo_remaining_capabilities); exclude(&onload_solo_remaining_capabilities, desired, &onload_solo_remaining_capabilities); // return the result either(current, desired, result); update(); return JVMTI_ERROR_NONE; }
jvmtiError CVMjvmtiAddCapabilities(const jvmtiCapabilities *current, const jvmtiCapabilities *prohibited, const jvmtiCapabilities *desired, jvmtiCapabilities *result) { CVMJvmtiGlobals *globals = &CVMglobals.jvmti; /* check that the capabilities being added are potential capabilities */ jvmtiCapabilities temp; CVMjvmtiGetPotentialCapabilities(current, prohibited, &temp); if (hasSome(exclude(desired, &temp, &temp))) { return JVMTI_ERROR_NOT_AVAILABLE; } /* add to the set of ever acquired capabilities */ either(&globals->capabilities.acquired, desired, &globals->capabilities.acquired); /* onload capabilities that got added are now permanent - so, also remove from onload */ both(&globals->capabilities.onload, desired, &temp); either(&globals->capabilities.always, &temp, &globals->capabilities.always); exclude(&globals->capabilities.onload, &temp, &globals->capabilities.onload); /* same for solo capabilities (transferred capabilities in the remaining sets handled as part of standard grab - below) */ both(&globals->capabilities.onload_solo, desired, &temp); either(&globals->capabilities.always_solo, &temp, &globals->capabilities.always_solo); exclude(&globals->capabilities.onload_solo, &temp, &globals->capabilities.onload_solo); /* remove solo capabilities that are now taken */ exclude(&globals->capabilities.always_solo_remaining, desired, &globals->capabilities.always_solo_remaining); exclude(&globals->capabilities.onload_solo_remaining, desired, &globals->capabilities.onload_solo_remaining); /* return the result */ either(current, desired, result); update(); return JVMTI_ERROR_NONE; }
void JvmtiManageCapabilities::get_potential_capabilities(const jvmtiCapabilities *current, const jvmtiCapabilities *prohibited, jvmtiCapabilities *result) { // exclude prohibited capabilities, must be before adding current exclude(&always_capabilities, prohibited, result); // must include current since it may possess solo capabilities and now prohibited either(result, current, result); // add other remaining either(result, &always_solo_remaining_capabilities, result); // if this is during OnLoad more capabilities are available if (JvmtiEnv::get_phase() == JVMTI_PHASE_ONLOAD) { either(result, &onload_capabilities, result); either(result, &onload_solo_remaining_capabilities, result); } }
void JvmtiManageCapabilities::relinquish_capabilities(const jvmtiCapabilities *current, const jvmtiCapabilities *unwanted, jvmtiCapabilities *result) { jvmtiCapabilities to_trash; jvmtiCapabilities temp; // can't give up what you don't have both(current, unwanted, &to_trash); // restore solo capabilities but only those that belong either(&always_solo_remaining_capabilities, both(&always_solo_capabilities, &to_trash, &temp), &always_solo_remaining_capabilities); either(&onload_solo_remaining_capabilities, both(&onload_solo_capabilities, &to_trash, &temp), &onload_solo_remaining_capabilities); update(); // return the result exclude(current, unwanted, result); }
void CVMjvmtiGetPotentialCapabilities(const jvmtiCapabilities *current, const jvmtiCapabilities *prohibited, jvmtiCapabilities *result) { CVMJvmtiGlobals *globals = &CVMglobals.jvmti; /* exclude prohibited capabilities, must be before adding current */ exclude(&globals->capabilities.always, prohibited, result); /* must include current since it may possess solo capabilities and now prohibited */ either(result, current, result); /* add other remaining */ either(result, &globals->capabilities.always_solo_remaining, result); /* if this is during OnLoad more capabilities are available */ /* if (JvmtiEnv::get_phase() == JVMTI_PHASE_ONLOAD) { */ either(result, &globals->capabilities.onload, result); either(result, &globals->capabilities.onload_solo_remaining, result); /* } */ }
void CVMjvmtiRelinquishCapabilities(const jvmtiCapabilities *current, const jvmtiCapabilities *unwanted, jvmtiCapabilities *result) { CVMJvmtiGlobals *globals = &CVMglobals.jvmti; jvmtiCapabilities to_trash; jvmtiCapabilities temp; /* can't give up what you don't have */ both(current, unwanted, &to_trash); /* restore solo capabilities but only those that belong */ either(&globals->capabilities.always_solo_remaining, both(&globals->capabilities.always_solo, &to_trash, &temp), &globals->capabilities.always_solo_remaining); either(&globals->capabilities.onload_solo_remaining, both(&globals->capabilities.onload_solo, &to_trash, &temp), &globals->capabilities.onload_solo_remaining); update(); /* return the result */ exclude(current, unwanted, result); }
/******************************* Discard units unless mismatched. *******************************/ STATIC_ROUTINE only_mismatch(struct descriptor_xd uni[2]) { either(uni); if (uni[0].pointer && uni[0].pointer != (struct descriptor *)&bad) MdsFree1Dx(&uni[0],NULL); return 1; }
void JvmtiManageCapabilities::update() { jvmtiCapabilities avail; // all capabilities either(&always_capabilities, &always_solo_capabilities, &avail); bool interp_events = avail.can_generate_field_access_events || avail.can_generate_field_modification_events || avail.can_generate_single_step_events || avail.can_generate_frame_pop_events || avail.can_generate_method_entry_events || avail.can_generate_method_exit_events; bool enter_all_methods = interp_events || avail.can_generate_breakpoint_events; UseFastEmptyMethods = !enter_all_methods; UseFastAccessorMethods = !enter_all_methods; if (avail.can_generate_breakpoint_events) { RewriteFrequentPairs = false; } // If can_redefine_classes is enabled in the onload phase then we know that the // dependency information recorded by the compiler is complete. if ((avail.can_redefine_classes || avail.can_retransform_classes) && JvmtiEnv::get_phase() == JVMTI_PHASE_ONLOAD) { JvmtiExport::set_all_dependencies_are_recorded(true); } JvmtiExport::set_can_get_source_debug_extension(avail.can_get_source_debug_extension); JvmtiExport::set_can_maintain_original_method_order(avail.can_maintain_original_method_order); JvmtiExport::set_can_post_interpreter_events(interp_events); JvmtiExport::set_can_hotswap_or_post_breakpoint( avail.can_generate_breakpoint_events || avail.can_redefine_classes || avail.can_retransform_classes); JvmtiExport::set_can_modify_any_class( avail.can_generate_breakpoint_events || avail.can_generate_all_class_hook_events); JvmtiExport::set_can_walk_any_space( avail.can_tag_objects); // disable sharing in onload phase // This controls whether the compilers keep extra locals live to // improve the debugging experience so only set them if the selected // capabilities look like a debugger. JvmtiExport::set_can_access_local_variables( avail.can_access_local_variables || avail.can_generate_breakpoint_events || avail.can_generate_frame_pop_events); JvmtiExport::set_can_post_on_exceptions( avail.can_generate_exception_events || avail.can_generate_frame_pop_events || avail.can_generate_method_exit_events); JvmtiExport::set_can_post_breakpoint(avail.can_generate_breakpoint_events); JvmtiExport::set_can_post_field_access(avail.can_generate_field_access_events); JvmtiExport::set_can_post_field_modification(avail.can_generate_field_modification_events); JvmtiExport::set_can_post_method_entry(avail.can_generate_method_entry_events); JvmtiExport::set_can_post_method_exit(avail.can_generate_method_exit_events || avail.can_generate_frame_pop_events); JvmtiExport::set_can_pop_frame(avail.can_pop_frame); JvmtiExport::set_can_force_early_return(avail.can_force_early_return); JvmtiExport::set_should_clean_up_heap_objects(avail.can_generate_breakpoint_events); }
void update() { CVMJvmtiGlobals *globals = &CVMglobals.jvmti; jvmtiCapabilities avail; jboolean interp_events; /* all capabilities */ either(&globals->capabilities.always, &globals->capabilities.always_solo, &avail); interp_events = avail.can_generate_field_access_events || avail.can_generate_field_modification_events || avail.can_generate_single_step_events || avail.can_generate_frame_pop_events || avail.can_generate_method_entry_events || avail.can_generate_method_exit_events; /* * If can_redefine_classes is enabled in the onload phase then we know that * the dependency information recorded by the compiler is complete. */ /* if ((avail.can_redefine_classes || avail.can_retransform_classes) && JvmtiEnv::get_phase() == JVMTI_PHASE_ONLOAD) { JvmtiExport::set_all_dependencies_are_recorded(true); } */ CVMjvmtiSetCanGetSourceDebugExtension(avail.can_get_source_debug_extension); CVMjvmtiSetCanExamineOrDeoptAnywhere( avail.can_generate_breakpoint_events || interp_events || avail.can_redefine_classes || avail.can_retransform_classes || avail.can_access_local_variables || avail.can_get_owned_monitor_info || avail.can_get_current_contended_monitor || avail.can_get_monitor_info || avail.can_get_owned_monitor_stack_depth_info); CVMjvmtiSetCanMaintainOriginalMethodOrder( avail.can_maintain_original_method_order); CVMjvmtiSetCanPostInterpreterEvents(interp_events); CVMjvmtiSetCanHotswapOrPostBreakpoint( avail.can_generate_breakpoint_events || avail.can_redefine_classes || avail.can_retransform_classes); CVMjvmtiSetCanModifyAnyClass( avail.can_generate_breakpoint_events || avail.can_retransform_classes || /* NOTE: remove when there is support for redefine with class sharing */ avail.can_retransform_any_class || avail.can_redefine_classes || /* NOTE: remove when there is support for redefine with class sharing */ avail.can_redefine_any_class || avail.can_generate_all_class_hook_events); CVMjvmtiSetCanWalkAnySpace(avail.can_tag_objects); /* NOTE: remove when IterateOverReachableObjects supports class sharing */ CVMjvmtiSetCanAccessLocalVariables( avail.can_access_local_variables || avail.can_redefine_classes || avail.can_retransform_classes); CVMjvmtiSetCanPostExceptions( avail.can_generate_exception_events || avail.can_generate_frame_pop_events || avail.can_generate_method_exit_events); CVMjvmtiSetCanPostBreakpoint(avail.can_generate_breakpoint_events); CVMjvmtiSetCanPostFieldAccess(avail.can_generate_field_access_events); CVMjvmtiSetCanPostFieldModification( avail.can_generate_field_modification_events); CVMjvmtiSetCanPostMethodEntry(avail.can_generate_method_entry_events); CVMjvmtiSetCanPostMethodExit(avail.can_generate_method_exit_events || avail.can_generate_frame_pop_events); CVMjvmtiSetCanPopFrame(avail.can_pop_frame); CVMjvmtiSetCanForceEarlyReturn(avail.can_force_early_return); CVMjvmtiSetShouldCleanUpHeapObjects(avail.can_generate_breakpoint_events); }