// ------------------------------------------------------------------ // ciMethod::uses_balanced_monitors // // Does this method use monitors in a strict stack-disciplined manner? bool ciMethod::has_balanced_monitors() { check_is_loaded(); if (_balanced_monitors) return true; // Analyze the method to see if monitors are used properly. VM_ENTRY_MARK; methodHandle method(THREAD, get_Method()); assert(method->has_monitor_bytecodes(), "should have checked this"); // Check to see if a previous compilation computed the // monitor-matching analysis. if (method->guaranteed_monitor_matching()) { _balanced_monitors = true; return true; } { EXCEPTION_MARK; ResourceMark rm(THREAD); GeneratePairingInfo gpi(method); gpi.compute_map(CATCH); if (!gpi.monitor_safe()) { return false; } method->set_guaranteed_monitor_matching(); _balanced_monitors = true; } return true; }
// ------------------------------------------------------------------ // ciMethod::itable_index // // Get the position of this method's entry in the itable, if any. int ciMethod::itable_index() { check_is_loaded(); assert(holder()->is_linked(), "must be linked"); VM_ENTRY_MARK; Method* m = get_Method(); if (!m->has_itable_index()) return Method::nonvirtual_vtable_index; return m->itable_index(); }
// ------------------------------------------------------------------ // ciMethod::native_entry // // Get the address of this method's native code, if any. address ciMethod::native_entry() { check_is_loaded(); assert(flags().is_native(), "must be native method"); VM_ENTRY_MARK; Method* method = get_Method(); address entry = method->native_function(); assert(entry != NULL, "must be valid entry point"); return entry; }
BitMap ciMethod::live_local_oops_at_bci(int bci) { VM_ENTRY_MARK; InterpreterOopMap mask; OopMapCache::compute_one_oop_map(get_Method(), bci, &mask); int mask_size = max_locals(); BitMap result(mask_size); result.clear(); int i; for (i = 0; i < mask_size ; i++ ) { if (mask.is_oop(i)) result.set_bit(i); } return result; }
// ------------------------------------------------------------------ // ciMethod::load_code // // Load the bytecodes and exception handler table for this method. void ciMethod::load_code() { VM_ENTRY_MARK; assert(is_loaded(), "only loaded methods have code"); Method* me = get_Method(); Arena* arena = CURRENT_THREAD_ENV->arena(); // Load the bytecodes. _code = (address)arena->Amalloc(code_size()); memcpy(_code, me->code_base(), code_size()); // Revert any breakpoint bytecodes in ci's copy if (me->number_of_breakpoints() > 0) { BreakpointInfo* bp = me->method_holder()->breakpoints(); for (; bp != NULL; bp = bp->next()) { if (bp->match(me)) { code_at_put(bp->bci(), bp->orig_bytecode()); } } } // And load the exception table. ExceptionTable exc_table(me); // Allocate one extra spot in our list of exceptions. This // last entry will be used to represent the possibility that // an exception escapes the method. See ciExceptionHandlerStream // for details. _exception_handlers = (ciExceptionHandler**)arena->Amalloc(sizeof(ciExceptionHandler*) * (_handler_count + 1)); if (_handler_count > 0) { for (int i=0; i<_handler_count; i++) { _exception_handlers[i] = new (arena) ciExceptionHandler( holder(), /* start */ exc_table.start_pc(i), /* limit */ exc_table.end_pc(i), /* goto pc */ exc_table.handler_pc(i), /* cp index */ exc_table.catch_type_index(i)); } } // Put an entry at the end of our list to represent the possibility // of exceptional exit. _exception_handlers[_handler_count] = new (arena) ciExceptionHandler(holder(), 0, code_size(), -1, 0); if (CIPrintMethodCodes) { print_codes(); } }
// ------------------------------------------------------------------ // ciMethod::resolve_invoke // // Given a known receiver klass, find the target for the call. // Return NULL if the call has no target or the target is abstract. ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver) { check_is_loaded(); VM_ENTRY_MARK; KlassHandle caller_klass (THREAD, caller->get_Klass()); KlassHandle h_recv (THREAD, exact_receiver->get_Klass()); KlassHandle h_resolved (THREAD, holder()->get_Klass()); Symbol* h_name = name()->get_symbol(); Symbol* h_signature = signature()->get_symbol(); methodHandle m; // Only do exact lookup if receiver klass has been linked. Otherwise, // the vtable has not been setup, and the LinkResolver will fail. if (h_recv->oop_is_array() || InstanceKlass::cast(h_recv())->is_linked() && !exact_receiver->is_interface()) { if (holder()->is_interface()) { m = LinkResolver::resolve_interface_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass); } else { m = LinkResolver::resolve_virtual_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass); } } if (m.is_null()) { // Return NULL only if there was a problem with lookup (uninitialized class, etc.) return NULL; } ciMethod* result = this; if (m() != get_Method()) { result = CURRENT_THREAD_ENV->get_method(m()); } // Don't return abstract methods because they aren't // optimizable or interesting. if (result->is_abstract()) { return NULL; } else { return result; } }
// ------------------------------------------------------------------ // ciMethod::interpreter_entry // // Get the entry point for running this method in the interpreter. address ciMethod::interpreter_entry() { check_is_loaded(); VM_ENTRY_MARK; methodHandle mh(THREAD, get_Method()); return Interpreter::entry_for_method(mh); }
bool force_inline() const { return get_Method()->force_inline(); }
// ------------------------------------------------------------------ // ciMethod::line_number_from_bci int ciMethod::line_number_from_bci(int bci) const { check_is_loaded(); VM_ENTRY_MARK; return get_Method()->line_number_from_bci(bci); }
// ------------------------------------------------------------------ // ciMethod::compressed_linenumber_table u_char* ciMethod::compressed_linenumber_table() const { check_is_loaded(); VM_ENTRY_MARK; return get_Method()->compressed_linenumber_table(); }
// ------------------------------------------------------------------ // ciMethod::has_linenumber_table // // length unknown until decompression bool ciMethod::has_linenumber_table() const { check_is_loaded(); VM_ENTRY_MARK; return get_Method()->has_linenumber_table(); }
bool intrinsic_candidate() const { return get_Method()->intrinsic_candidate(); }
bool dont_inline() const { return get_Method()->dont_inline(); }
// ------------------------------------------------------------------ // ciMethod::is_special_get_caller_class_method // bool ciMethod::is_ignored_by_security_stack_walk() const { check_is_loaded(); VM_ENTRY_MARK; return get_Method()->is_ignored_by_security_stack_walk(); }
// ------------------------------------------------------------------ // ciMethod::vtable_index // // Get the position of this method's entry in the vtable, if any. int ciMethod::vtable_index() { check_is_loaded(); assert(holder()->is_linked(), "must be linked"); VM_ENTRY_MARK; return get_Method()->vtable_index(); }
// public, retroactive version bool ciMethod::ensure_method_data() { bool result = true; if (_method_data == NULL || _method_data->is_empty()) { GUARDED_VM_ENTRY({ result = ensure_method_data(get_Method()); });
bool caller_sensitive() const { return get_Method()->caller_sensitive(); }