Index: vm/port/include/lil.h =================================================================== --- vm/port/include/lil.h (revision 579932) +++ vm/port/include/lil.h (working copy) @@ -523,6 +523,8 @@ virtual void m2n_save_all() = 0; virtual void pop_m2n() = 0; virtual void print(char *, LilOperand *) = 0; + virtual void hse() {} + virtual void hsd() {} }; @@ -557,6 +559,8 @@ void m2n_save_all() {} void pop_m2n() {} void print(char *, LilOperand *) {} + void hse() {} + void hsd() {} }; Index: vm/port/src/lil/lil.cpp =================================================================== --- vm/port/src/lil/lil.cpp (revision 579932) +++ vm/port/src/lil/lil.cpp (working copy) @@ -62,7 +62,7 @@ enum LilInstructionTag { LIT_Label, LIT_Locals, LIT_StdPlaces, LIT_Alloc, LIT_Asgn, LIT_Ts, LIT_Handles, LIT_Ld, LIT_St, LIT_Inc, LIT_Cas, LIT_J, LIT_Jc, LIT_Out, LIT_In2Out, LIT_Call, LIT_Ret, - LIT_PushM2N, LIT_M2NSaveAll, LIT_PopM2N, LIT_Print + LIT_PushM2N, LIT_M2NSaveAll, LIT_PopM2N, LIT_Print, LIT_HSE, LIT_HSD }; struct LilInstruction { @@ -782,10 +782,21 @@ if (!lil_parse_operand(src, va, &(i->u.call.target))) return NULL; break; case 'h': // handles - i->tag = LIT_Handles; - if (!lil_parse_kw(src, "handles")) return NULL; - if (!lil_parse_kw(src, "=")) return NULL; - if (!lil_parse_operand(src, va, &(i->u.handles))) return NULL; + if ((*src)[1]=='a') { + i->tag = LIT_Handles; + if (!lil_parse_kw(src, "handles")) return NULL; + if (!lil_parse_kw(src, "=")) return NULL; + if (!lil_parse_operand(src, va, &(i->u.handles))) return NULL; + } + if ((*src)[1]=='s' && ((*src)[2])=='e') { + i->tag = LIT_HSE; + if (!lil_parse_kw(src, "hse")) return NULL; + } + if ((*src)[1]=='s' && ((*src)[2])=='d') { + i->tag = LIT_HSD; + if (!lil_parse_kw(src, "hsd")) return NULL; + } + break; case 'i': // =, in2out, inc if (num((*src)[1]) || (*src)[1]=='%') goto asgn; @@ -1371,6 +1382,9 @@ case LIT_Print: // nothing to do here break; + case LIT_HSE: + case LIT_HSD: + break; default: ASSERT(0, "Unknown instruction tag"); } } @@ -1749,6 +1763,12 @@ case LIT_Print: v->print(i->u.print.str, &i->u.print.arg); break; + case LIT_HSE: + v->hse(); + break; + case LIT_HSD: + v->hsd(); + break; default: ASSERT(0, "Unknown instruction tag"); } } @@ -2059,6 +2079,9 @@ if (!lil_is_valid_operand(cs, c, &i->u.print.arg)) ERR("invalid argument to print"); break; + case LIT_HSE: + case LIT_HSD: + break; default: ERR("unknown instruction"); } @@ -2410,6 +2433,12 @@ lil_print_operand(out, &i->u.print.arg); fprintf(out, "\n"); break; + case LIT_HSE: + fprintf(out, "hse\n"); + break; + case LIT_HSD: + fprintf(out, "hsd\n"); + break; default: ASSERT(0, "Unknown instruction tag"); }; Index: vm/port/src/lil/ia32/pim/lil_code_generator_ia32.cpp =================================================================== --- vm/port/src/lil/ia32/pim/lil_code_generator_ia32.cpp (revision 579932) +++ vm/port/src/lil/ia32/pim/lil_code_generator_ia32.cpp (working copy) @@ -858,6 +858,15 @@ if (!info->short_jumps) info->size += 3*js+4*jcs; } + void hse() { + info->size += 25; + } + + void hsd() { + info->size += 35; + } + + private: tl::MemoryPool* mem; LilCodeStub* cs; @@ -1426,6 +1435,42 @@ // not implemented on ia32 } + void hse() { + int32 disable_count_offset = (unsigned) &(((HyThread_public *) (0))->disable_count); + *buf = m2n_gen_ts_to_register(*buf, &eax_opnd); + *buf = alu(*buf, sub_opc, M_Base_Opnd(eax_reg, disable_count_offset), Imm_Opnd(1)); + } + + void hsd() { + int32 disable_count_offset = (unsigned) &(((HyThread_public *) (0))->disable_count); + int32 request_offset = (unsigned) &(((HyThread_public *) (0))->request); + + *buf = m2n_gen_ts_to_register(*buf, &eax_opnd); + + *buf = alu(*buf, add_opc, M_Base_Opnd(eax_reg, disable_count_offset), Imm_Opnd(1)); + + // (((HyThread_public *)thread)->request) + *buf = alu(*buf, cmp_opc, M_Base_Opnd(eax_reg, request_offset), Imm_Opnd(0)); + *buf = branch8(*buf, Condition_E, Imm_Opnd(0x0D + 6)); + + // ((HyThread_public *)thread)->disable_count == 1) + *buf = alu(*buf, cmp_opc, M_Base_Opnd(eax_reg, disable_count_offset), Imm_Opnd(1)); + *buf = branch8(*buf, Condition_NE, Imm_Opnd(0x06 + 7)); + // hythread_safe_point_other(thread); + + // TODO: optimize push-pop before hythread_safe_point_other + *buf = push(*buf, eax_opnd); + *buf = push(*buf, ebx_opnd); + *buf = push(*buf, ecx_opnd); + *buf = push(*buf, edx_opnd); + *buf = ::call(*buf, (char*)hythread_safe_point_other); + *buf = pop(*buf, edx_opnd); + *buf = pop(*buf, ecx_opnd); + *buf = pop(*buf, ebx_opnd); + *buf = pop(*buf, eax_opnd); + } + + tl::MemoryPool* mem; char** buf; LilCguLabelAddresses la_tab; Index: vm/vmcore/src/jit/compile.cpp =================================================================== --- vm/vmcore/src/jit/compile.cpp (revision 579932) +++ vm/vmcore/src/jit/compile.cpp (working copy) @@ -326,10 +326,14 @@ } //***** Part 4: Enable GC - cs = lil_parse_onto_end(cs, +/* + cs = lil_parse_onto_end(cs, "out platform::void;" "call %0i;", hythread_suspend_enable); +*/ + cs = lil_parse_onto_end(cs, + "hse;"); assert(cs); //***** Part 5: Set up arguments @@ -413,10 +417,15 @@ assert(cs); //***** Part 8: Disable GC +/* cs = lil_parse_onto_end(cs, "out platform::void;" "call %0i;", hythread_suspend_disable); +*/ + cs = lil_parse_onto_end(cs, + "hsd;"); + assert(cs); // Exception offsets