void parse_ifClause() { expression_t expr; size_t conv_expr; size_t jc_addr; size_t jmp_addr; size_t stack_frame; bool jmp_used = true; switch(next_token.type) { case TT_KW_IF: match(TT_KW_IF); match(TT_PARENTHESES_OPEN); expr = parse_expr(); match(TT_PARENTHESES_CLOSE); jc_addr = get_code_seg_top(); switch (expr.type) { case DOUBLE_LIT_DT: if(!((int)expr.double_val)) generate_jump(0); //address is unknown yet else jmp_used = false; break; case INT_LIT_DT: if(!expr.int_val) generate_jump(0); //address is unknown yet else jmp_used = false; break; case DOUBLE_DT: conv_expr = generate_double_to_int(expr.addr); generate_neg_cond_jump(0, conv_expr); //address is unknown yet break; case INT_DT: generate_neg_cond_jump(0, expr.addr); //address is unknown yet break; case STRING_LIT_DT: case STRING_DT: error("String value in a if statement", ERROR_TYPE_COMPAT); break; default: ; } stack_frame = store_stack_frame(); parse_block(true); load_stack_frame(stack_frame); generate_data_seg_restore(stack_frame); jmp_addr = get_code_seg_top(); generate_jump(0); //address is unknown yet if (jmp_used) set_jump_addr(jc_addr, get_code_seg_top()); match(TT_KW_ELSE); stack_frame = store_stack_frame(); parse_block(true); load_stack_frame(stack_frame); generate_data_seg_restore(stack_frame); set_jump_addr(jmp_addr, get_code_seg_top()); break; default: error("Syntactic error: Failed to parse the program", ERROR_SYN); } }
void sendDesc::link(CacheStub* s) { set_jump_addr(s->insts()); assert(dependency()->isEmpty(), "not empty"); dependency()->add(&s->cacheLink); MachineCache::flush_instruction_cache_for_debugging(); }
void parse_forClause() { expression_t expr; size_t conv_expr; size_t loop_start; size_t loop_end; size_t asgn_start; size_t block_start; size_t jc_addr; size_t jmp_to_block_addr; size_t asgn_frame; size_t block_frame; bool jmp_used = true; switch(next_token.type) { case TT_KW_FOR: match(TT_KW_FOR); match(TT_PARENTHESES_OPEN); var_table_scope_enter(); block_frame = store_stack_frame(); parse_varDef(); match(TT_SEMICOLON); //loop start loop_start = get_code_seg_top(); generate_data_seg_restore(store_stack_frame()); expr = parse_expr(); match(TT_SEMICOLON); //gen jc jc_addr = get_code_seg_top(); switch (expr.type) { case DOUBLE_LIT_DT: if(!((int)expr.double_val)) generate_jump(0); //address is unknown yet else jmp_used = false; break; case INT_LIT_DT: if(!expr.int_val) generate_jump(0); //address is unknown yet else jmp_used = false; break; case DOUBLE_DT: conv_expr = generate_double_to_int(expr.addr); generate_neg_cond_jump(0, conv_expr); //address is unknown yet break; case INT_DT: generate_neg_cond_jump(0, expr.addr); //address is unknown yet break; case STRING_LIT_DT: case STRING_DT: error("String value in a if statement", ERROR_TYPE_COMPAT); break; default: ; } //jump to block start jmp_to_block_addr = get_code_seg_top(); generate_jump(0); //address is unknown yet //assignment start asgn_start = get_code_seg_top(); asgn_frame = store_stack_frame(); parse_asgn(); load_stack_frame(asgn_frame); //jump to loop start generate_jump(loop_start); match(TT_PARENTHESES_CLOSE); //block start block_start = get_code_seg_top(); set_jump_addr(jmp_to_block_addr, block_start); parse_block(false); //jump to assignment generate_jump(asgn_start); //loop end loop_end = get_code_seg_top(); if (jmp_used) set_jump_addr(jc_addr, loop_end); break; load_stack_frame(block_frame); generate_data_seg_restore(block_frame); default: error("Syntactic error: Failed to parse the program", ERROR_SYN); } }
// rebind the sendDesc to nm at addr, with cs_from_pic if non-NULL void sendDesc::rebind(nmethod* nm, char* addr, CountStub *cs_from_pic) { if (VerifyZoneOften) { nm->linkedSends.verify_list_integrity(); if (dependency()->next == NULL && dependency()->prev == NULL) ; // not initted yet else verify(); } if (addr == NULL) addr= nm->entryPointFor(this); assert(pic() == NULL, "shouldn't call"); assert(nm->key.selector == static_or_dynamic_selector(nm->key.selector, nm->key.lookupType), "mismatched selector"); nmethod* current= target(); assert( RecompilationInProgress || current != nm || nm->isYoung(), // rebind to insert aging stub "why rebind?? (maybe I-cache did not get flushed)"); if (nm->isDI() && countType() != NonCounting) { // turn off counting/comparing flag - cannot inline DI nmethods yet setCounting(NonCounting); assert(countType() == NonCounting, "oops"); } CountStub *oldcs= countStub(); assert(cs_from_pic == NULL || oldcs == NULL, "got count stub from pic and count stub from sendDesc"); if (cs_from_pic) { assert( nm->isYoung() && cs_from_pic->isAgingStub() || isCounting() && cs_from_pic->isCountStub(), "count stub from pic doesn't match send desc"); set_jump_addr(cs_from_pic->insts()); dependency()->rebind(&cs_from_pic->sdLink); cs_from_pic->set_callee((int32)addr); } else if (UseAgingStubs && nm->isYoung()) { // need to insert an aging stub if (oldcs) { oldcs->deallocate(); } else if (current) { dependency()->remove(); } CountStub *newcs= new AgingStub(nm, addr, dependency()); set_jump_addr(newcs->insts()); } else if (UseAgingStubs && oldcs) { // change target of existing count stub oldcs->rebind(nm, addr); } else if (UseAgingStubs && isCounting()) { // create count stub if (current) dependency()->remove(); // unlink current target CountStub *newcs = CountStub::new_CountStub(nm, addr, dependency(), countType()); set_jump_addr(newcs->insts()); } else { // rebind inline cache set_jump_addr(addr); dependency()->rebind(&nm->linkedSends); } if (VerifyZoneOften) verify(); MachineCache::flush_instruction_cache_for_debugging(); }