47 #define BC_ESCAPE_VERBOSE !defined(NDEBUG)
51 #if BC_ESCAPE_VERBOSE && 0
66 #define dprintf(x, ...) printf(__VA_ARGS__)
152 #if BC_ESCAPE_VERBOSE
153 printf(
"%s: error.\n", __FUNCTION__);
161 }
else if (!(pos < stack->end)) {
199 *(stack->
ptr) = element;
206 return *(stack->
ptr - offset);
214 *(stack->
ptr - offset) = value;
226 for (it = stack->
bottom; it < stack->ptr; ++it) {
227 if (it == stack->
start) {
233 fprintf(f,
"%c----", sep);
235 fprintf(f,
"%cP%3d", sep, it->
index);
267 assert(0 <= bit && bit < bv->
size);
272 assert(0 <= bit && bit < bv->
size);
293 #define FOR_EACH_BASICBLOCK_WORK_LIST(lst, it) \
294 for ((it) = (lst)->first; (it); (it) = (it)->next)
311 if (lst->
first == NULL) {
348 #if BC_ESCAPE_VERBOSE
349 printf(
"%s: error.\n", __FUNCTION__);
358 return (jc->
pos >= jc->
end);
379 jc->
pos += (aidx - idx);
391 if ((jc->
pos + n) <= jc->
end) {
417 ret = (jc->
pos[0] << 8) | (jc->
pos[1]);
428 ret = (jc->
pos[0] << 8) | (jc->
pos[1]);
439 ret = (jc->
pos[0] << 24) | (jc->
pos[1] << 16) | (jc->
pos[2] << 8) | (jc->
pos[3]);
483 #if BC_ESCAPE_VERBOSE
538 n = a + ret_val_is_adr;
552 if (ret_val_is_adr) {
564 #if BC_ESCAPE_VERBOSE
587 if (old < escape_state) {
609 if (0 <= local && local < be->local_to_adr_param_size) {
637 if (0 <= local && local < be->local_to_adr_param_size) {
687 u1 *paramescape = mi->paramescape;
689 unsigned num_params_returned = 0;
699 if (*paramescape & 0x80) {
700 num_params_returned += 1;
729 if ((num_params_returned == 1) && (mi->paramescape[-1] <
ESCAPE_GLOBAL)) {
790 #if BC_ESCAPE_VERBOSE
794 "Succefully resolved callee %s/%s. Recursing.\n",
802 #if BC_ESCAPE_VERBOSE
806 "Failed to resolve callee %s/%s.\n",
820 if (mi->paramescape == NULL) {
824 if (mi->paramescape == NULL) {
853 for (i = 0; i < (high - low + 1); ++
i) {
885 for (i = 0; i < npairs; ++
i) {
904 #if BC_ESCAPE_VERBOSE
923 #if BC_ESCAPE_VERBOSE
1672 #if BC_ESCAPE_VERBOSE
1680 #if BC_ESCAPE_VERBOSE
1687 #if BC_ESCAPE_VERBOSE
1695 #if BC_ESCAPE_VERBOSE
1704 #if BC_ESCAPE_VERBOSE
1706 printf(
"Fatal error while processing basic block. Aborting.\n");
1791 #if BC_ESCAPE_VERBOSE
1795 "=== BC escape analysis of %s/%s at depth %d ===\n",
1807 if (m->paramescape != NULL) {
1808 #if BC_ESCAPE_VERBOSE
1810 dprintf(depth,
"Escape info for method already available.\n");
1817 #if BC_ESCAPE_VERBOSE
1819 dprintf(depth,
"Detected recursion, aborting.\n");
1825 if (m->
jcode == NULL) {
1826 #if BC_ESCAPE_VERBOSE
1828 dprintf(depth,
"No bytecode for callee.\n");
1835 #if BC_ESCAPE_VERBOSE
1850 #if BC_ESCAPE_VERBOSE
1854 "%s/%s: Non-escaping params: %d\n",
static op_stack_slot_t op_stack_pop(op_stack_t *stack)
static void bit_vector_set(bit_vector_t *bv, s4 bit)
jlong jlong jlong jlong jint jmethodID jint slot
static void op_stack_set_error(op_stack_t *stack)
static u2 jcode_get_u2(jcode_t *jc)
static void op_stack_push(op_stack_t *stack, op_stack_slot_t element)
static s4 jcode_get_branch_target(jcode_t *jc)
static void bc_escape_analysis_dirty(bc_escape_analysis_t *be, s4 local)
static s4 jcode_get_branch_target_wide(jcode_t *jc)
void * class_getconstant(classinfo *c, u4 pos, ConstantPoolTag ctype)
static bool op_stack_test_position(op_stack_t *stack, op_stack_slot_t *pos)
static void bc_escape_analysis_process_basicblock(bc_escape_analysis_t *be, jcode_t *jc)
struct basicblock_work_item basicblock_work_item_t
static void bc_escape_analysis_branch_target(bc_escape_analysis_t *be, s4 branch_target)
static void op_stack_reset(op_stack_t *stack)
s4 rawexceptiontablelength
s4 non_escaping_adr_params
basicblock_work_item_t * first
static s2 jcode_get_s2(jcode_t *jc)
void basicblock_work_list_insert(basicblock_work_list_t *lst, s4 bytecode_index)
static void bc_escape_analysis_init(bc_escape_analysis_t *be, methodinfo *m, bool verbose, int depth)
static void bc_escape_analysis_adjust_invoke_parameters(bc_escape_analysis_t *be, methodinfo *mi)
static u1 jcode_get_u1(jcode_t *jc)
static bool op_stack_is_empty(const op_stack_t *stack)
union constant_FMIref::@26 p
static s4 bit_vector_size(const bit_vector_t *bv)
bool bv_get_bit(bitvector bv, int bit)
bit_vector_t * adr_param_returned
static void jcode_align_bytecode_index(jcode_t *jc, s4 align)
static s4 jcode_get_s4(jcode_t *jc)
value_category_t bc_escape_analysis_value_category(bc_escape_analysis_t *be, s4 index)
static bool jcode_end(const jcode_t *jc)
JNIEnv jthread jobject jclass jlong size
bool jcode_test_has_bytes(jcode_t *jc, s4 n)
static void op_stack_init(op_stack_t *stack, unsigned max, bool *perror_flag)
bool escape_is_monomorphic(methodinfo *caller, methodinfo *callee)
#define IS_2_WORD_TYPE(a)
raw_exception_entry * rawexceptiontable
static bool op_stack_slot_is_param(const op_stack_slot_t slot)
const op_stack_slot_t OP_STACK_SLOT_UNKNOWN
static s4 jcode_get_fall_through_target(jcode_t *jc)
jlong jlong jlong jlong jint depth
static void bc_escape_analysis_adjust_return_value(bc_escape_analysis_t *be)
static void bit_vector_init(bit_vector_t *bv, s4 size)
static void bc_escape_analysis_escape_invoke_parameters(bc_escape_analysis_t *be, methoddesc *md)
op_stack_slot_t bc_escape_analysis_address_local(bc_escape_analysis_t *be, s4 local)
static void bc_escape_analysis_push_return_value(bc_escape_analysis_t *be, methoddesc *md)
static void op_stack_print(const op_stack_t *stack, FILE *f)
resolve_result_t resolve_method_lazy(methodinfo *refmethod, constant_FMIref *methodref, bool invokespecial)
static void jcode_set_error(jcode_t *jc)
static void bc_escape_analysis_adjust_state(bc_escape_analysis_t *be, op_stack_slot_t adr_param, escape_state_t escape_state)
static void jcode_record_instruction_start(jcode_t *jc)
static void bc_escape_analysis_parse_lookupswitch(bc_escape_analysis_t *be, jcode_t *jc)
static ByteCode jcode_get_bytecode(jcode_t *jc)
static void bc_escape_analysis_returned(bc_escape_analysis_t *be, op_stack_slot_t value)
alloc::list< PassInfo::IDTy >::type & stack
#define FOR_EACH_BASICBLOCK_WORK_LIST(lst, it)
basicblock_work_item_t * last
static op_stack_slot_t op_stack_slot_create_param(s4 index)
static u1 escape_state_to_u1(escape_state_t x)
Fieldref, Methodref and InterfaceMethodref.
static void bc_escape_analysis_parse_invoke(bc_escape_analysis_t *be, jcode_t *jc)
void basicblock_work_list_init(basicblock_work_list_t *lst)
static void bc_escape_analysis_perform_intern(methodinfo *m, int depth)
s4 local_to_adr_param_size
static bool bit_vector_get(const bit_vector_t *bv, s4 bit)
byte_iterator begin() const
op_stack_slot_t * local_to_adr_param
static op_stack_slot_t op_stack_get(op_stack_t *stack, int offset)
static escape_state_t escape_state_from_u1(u1 x)
static void bc_escape_analysis_analyze(bc_escape_analysis_t *be)
static void jcode_rewind_instruction(jcode_t *jc)
struct basicblock_work_item * next
#define MEMORY_ALIGN(pos, size)
constant_classref * classref
static void jcode_move_to_index(jcode_t *jc, s4 index)
void bc_escape_analysis_perform(methodinfo *m)
bit_vector_t * adr_param_dirty
static void jcode_forward_instruction_relative(jcode_t *jc, s4 n)
const parseddesc_t parseddesc
static void bc_escape_analysis_dirty_2(bc_escape_analysis_t *be, s4 local)
bitvector bv_new(int size)
void bv_set_bit(bitvector bv, int bit)
static bool op_stack_slot_is_unknown(const op_stack_slot_t slot)
static s4 jcode_get_instruction_length(const jcode_t *jc)
static s4 op_stack_element_count(const op_stack_t *stack)
static void bc_escape_analysis_parse_tableswitch(bc_escape_analysis_t *be, jcode_t *jc)
const char const void jint length
static void jcode_init(jcode_t *jc, u1 *start, s4 length, s4 offset, bool *perror_flag)
static void op_stack_push_unknown(op_stack_t *stack)
static void op_stack_set(op_stack_t *stack, int offset, op_stack_slot_t value)
op_stack_slot_t * elements
static s4 jcode_get_index(const jcode_t *jc)
basicblock_work_list_t * basicblocks