diff --git a/src/code/amd64.c b/src/code/amd64.c index 850e50f01aa45dbb438b3253c63c81e55a95b9f7..2fe4ba5e8251fd5747a184f5dc7447ce19189e4e 100644 --- a/src/code/amd64.c +++ b/src/code/amd64.c @@ -996,12 +996,12 @@ void amd64_ins_entry(void) void amd64_flush_code_generator_state(void) { - sp_reg = -1; - fp_reg = -1; + amd64_prev_stored_pc = -1; ret_for_func = 0; + fp_reg = -1; + sp_reg = -1; mark_sp_reg = -1; dirty_regs = 0; - amd64_prev_stored_pc = -1; } static void flush_dirty_regs(void) @@ -1061,6 +1061,7 @@ static void mov_sval_type(enum amd64_reg src, enum amd64_reg dst ) } +#if 0 static void svalue_is_referenced(enum amd64_reg in, struct label *not ) { /* bit 4 set, and no higher bit set (all with 8bit values). */ @@ -1078,7 +1079,7 @@ static void mem_svalue_is_referenced(enum amd64_reg in, struct label *not ) mov_sval_type(in,P_REG_RAX); svalue_is_referenced(P_REG_RAX, not ); } - +#endif static void update_arg1(INT32 value) { @@ -2610,6 +2611,7 @@ void ins_f_byte_with_arg(unsigned int a, INT32 b) amd64_add_sp(-1); return; + case F_ASSIGN_PRIVATE_GLOBAL_AND_POP: case F_ASSIGN_PRIVATE_GLOBAL: { @@ -2741,10 +2743,7 @@ void ins_f_byte_with_arg(unsigned int a, INT32 b) mov_mem16_reg(ARG3_REG, OFFSETOF(inherit, identifier_level), ARG3_REG); add_reg_imm(ARG3_REG, b); - flush_dirty_regs(); /* In case an error is thrown. */ - call_imm(low_object_index_no_free); - /* NB: We know that low_object_index_no_free() doesn't - * mess with the stack pointer. */ + amd64_call_c_function(low_object_index_no_free); amd64_add_sp(1); return; @@ -3145,6 +3144,68 @@ void ins_f_byte_with_2_args(unsigned int a, INT32 b, INT32 c) /* done */ } return; + case F_PRIVATE_IF_DIRECT_GLOBAL: + { + LABELS(); + amd64_load_sp_reg(); + ins_debug_instr_prologue(a-F_OFFSET, b, c); + /* do not assign if this object is destructed. */ + mov_mem_reg( fp_reg, OFFSETOF(pike_frame,current_object), ARG2_REG ); + mov_mem_reg( fp_reg, OFFSETOF(pike_frame,context), ARG3_REG ); + /* if ctx->prog != arg1->prog */ + mov_mem_reg( ARG3_REG, OFFSETOF(inherit,prog), P_REG_R8 ); + mov_mem_reg( ARG2_REG, OFFSETOF(object,prog), P_REG_RAX ); + cmp_reg_reg(P_REG_R8,P_REG_RAX); + je(&label_A); + mov_reg_reg(sp_reg, ARG1_REG); + mov_mem16_reg(ARG3_REG, OFFSETOF(inherit, identifier_level), + ARG3_REG); + add_reg_imm(ARG3_REG, c); + amd64_call_c_function(low_object_index_no_free); + amd64_add_sp(1); + jmp(&label_B); + + LABEL_A; + mov_mem_reg(ARG2_REG, OFFSETOF(object,storage), P_REG_RBX ); + add_reg_mem(P_REG_RBX, ARG3_REG, OFFSETOF(inherit,storage_offset)); + add_reg_imm(P_REG_RBX, b ); + amd64_push_svaluep( P_REG_RBX ); + LABEL_B; + return; + } + + case F_ASSIGN_PRIVATE_IF_DIRECT_GLOBAL: + { + LABELS(); + amd64_load_sp_reg(); + ins_debug_instr_prologue(a-F_OFFSET, b, c); + /* do not assign if this object is destructed. */ + mov_mem_reg( fp_reg, OFFSETOF(pike_frame,current_object), ARG1_REG ); + mov_mem_reg( fp_reg, OFFSETOF(pike_frame,context), ARG2_REG ); + /* if ctx->prog != arg1->prog */ + mov_mem_reg( ARG1_REG, OFFSETOF(object,prog), P_REG_RAX ); + mov_mem_reg( ARG2_REG, OFFSETOF(inherit,prog), P_REG_R8 ); + cmp_reg_reg(P_REG_R8,P_REG_RAX); + je(&label_A); + + /* arg1 = object */ + /* arg2 = c + identifier_level */ + /* arg3 = Pike_sp-1 */ + mov_mem16_reg( ARG2_REG, OFFSETOF(inherit,identifier_level), ARG2_REG); + add_reg_imm( ARG2_REG, c ); + add_reg_imm_reg( sp_reg, -1*sizeof(struct svalue), ARG3_REG ); + amd64_call_c_function(object_low_set_index); + jmp(&label_B); + LABEL_A; + mov_mem_reg(ARG1_REG, OFFSETOF(object,storage), P_REG_RBX ); + add_reg_mem(P_REG_RBX, ARG2_REG, OFFSETOF(inherit,storage_offset)); + add_reg_imm(P_REG_RBX, b ); + amd64_free_svalue( P_REG_RBX, 0 ); + amd64_assign_svalue_no_free( P_REG_RBX, sp_reg, -sizeof(struct svalue)); + amd64_ref_svalue(P_REG_RBX,0); + LABEL_B; + } + return; case F_ASSIGN_PRIVATE_TYPED_GLOBAL_AND_POP: case F_ASSIGN_PRIVATE_TYPED_GLOBAL: { diff --git a/src/docode.c b/src/docode.c index 153127d1bf5b9417186cdfd38ebe1d8a941a2dab..b62f643d613094251b8ee820afe1c18836910b57 100644 --- a/src/docode.c +++ b/src/docode.c @@ -702,20 +702,36 @@ static void emit_global( int n ) struct reference *ref = PTR_FROM_INT(Pike_compiler->new_program, n); struct identifier *id = ID_FROM_PTR(Pike_compiler->new_program, ref); - if( (ref->id_flags & (ID_PRIVATE|ID_FINAL)) - && !(id->identifier_flags & IDENTIFIER_NO_THIS_REF) - && !IDENTIFIER_IS_ALIAS(id->identifier_flags) - && IDENTIFIER_IS_VARIABLE(id->identifier_flags) - && !ref->inherit_offset) + if(!(id->identifier_flags & IDENTIFIER_NO_THIS_REF) + && !IDENTIFIER_IS_ALIAS(id->identifier_flags) + && IDENTIFIER_IS_VARIABLE(id->identifier_flags)) { /* fprintf( stderr, "private global %d\n", (INT32)id->func.offset ); */ - if( id->run_time_type == PIKE_T_MIXED ) - emit1(F_PRIVATE_GLOBAL, id->func.offset); - else - emit2(F_PRIVATE_TYPED_GLOBAL, id->func.offset, id->run_time_type); + if( ref->id_flags & (ID_PRIVATE|ID_FINAL) ) + { + if( id->run_time_type == PIKE_T_MIXED ) + emit1(F_PRIVATE_GLOBAL, id->func.offset); + else + emit2(F_PRIVATE_TYPED_GLOBAL, id->func.offset, id->run_time_type); + return; + } + + if( (id->func.offset < 65536) && (n<65536) ) + { + + if( id->run_time_type == PIKE_T_MIXED ) + { + emit2(F_PRIVATE_IF_DIRECT_GLOBAL, id->func.offset, n); + return; + } +/* else */ +/* { */ +/* INT32 mix = id->func.offset | (n<<16); */ +/* emit2(F_PRIVATE_IF_DIRECT_TYPED_GLOBAL, mix, id->run_time_type); */ + } } - else - emit1(F_GLOBAL, n); + + emit1(F_GLOBAL, n); } static void emit_assign_global( int n, int and_pop ) @@ -724,23 +740,29 @@ static void emit_assign_global( int n, int and_pop ) struct reference *ref = PTR_FROM_INT(Pike_compiler->new_program, n); struct identifier *id = ID_FROM_PTR(Pike_compiler->new_program, ref); - if( (ref->id_flags & (ID_PRIVATE|ID_FINAL)) - && !(id->identifier_flags & IDENTIFIER_NO_THIS_REF) + if( !(id->identifier_flags & IDENTIFIER_NO_THIS_REF) && !IDENTIFIER_IS_ALIAS(id->identifier_flags) - && IDENTIFIER_IS_VARIABLE(id->identifier_flags) - && !ref->inherit_offset ) + && IDENTIFIER_IS_VARIABLE(id->identifier_flags)) { - if( id->run_time_type == PIKE_T_MIXED ) + if( (ref->id_flags & (ID_PRIVATE|ID_FINAL)) ) + { + if( id->run_time_type == PIKE_T_MIXED ) emit1((and_pop?F_ASSIGN_PRIVATE_GLOBAL_AND_POP:F_ASSIGN_PRIVATE_GLOBAL), id->func.offset); - else + else emit2((and_pop?F_ASSIGN_PRIVATE_TYPED_GLOBAL_AND_POP:F_ASSIGN_PRIVATE_TYPED_GLOBAL), id->func.offset, id->run_time_type); + return; + } + if( id->run_time_type == PIKE_T_MIXED ) + { + emit2(F_ASSIGN_PRIVATE_IF_DIRECT_GLOBAL, id->func.offset, n ); + if( and_pop ) + emit0(F_POP_VALUE); + return; + } } - else - { - emit1((and_pop?F_ASSIGN_GLOBAL_AND_POP:F_ASSIGN_GLOBAL), n); - } + emit1((and_pop?F_ASSIGN_GLOBAL_AND_POP:F_ASSIGN_GLOBAL), n); } static int emit_ltosval_call_and_assign( node *lval, node *func, node *args ) diff --git a/src/interpret_functions.h b/src/interpret_functions.h index 3540740c7c9a2a3904be1e69d8f816b5ba23b114..a81d20c1f4107470f96d6aa7013fdd0e9fbde6c9 100644 --- a/src/interpret_functions.h +++ b/src/interpret_functions.h @@ -365,6 +365,45 @@ OPCODE1(F_PRIVATE_GLOBAL, "global <private>", I_UPDATE_SP, { print_return_value(); }); +OPCODE2(F_PRIVATE_IF_DIRECT_GLOBAL, "global <private if direct>", + I_UPDATE_SP, { + struct object *co = Pike_fp->current_object; + struct inherit *cx = Pike_fp->context; + if(!co->prog) /* note: generate an error. */ + object_low_set_index(co,0,0); + if( co->prog != cx->prog ) + { + low_index_current_object_no_free(Pike_sp, arg2); + Pike_sp++; + print_return_value(); + } + else + { + struct svalue *sp; + sp = (struct svalue *)(co->storage + cx->storage_offset + arg1); + push_svalue( sp ); + print_return_value(); + } +}); + +OPCODE2(F_ASSIGN_PRIVATE_IF_DIRECT_GLOBAL, + "assign global <private if direct>", 0, + { + struct object *co = Pike_fp->current_object; + struct inherit *cx = Pike_fp->context; + + if( co->prog != cx->prog ) + { + object_low_set_index(co, arg2 + cx->identifier_level, Pike_sp-1); + } + else + { + struct svalue *tmp; + tmp = (struct svalue *)(co->storage + cx->storage_offset + arg1); + assign_svalue(tmp,Pike_sp-1); + } + }); + OPCODE2(F_ASSIGN_PRIVATE_TYPED_GLOBAL_AND_POP, "assign global <private,typed> and pop", I_UPDATE_SP, { /* lazy mode. */ LOCAL_VAR(union anything *tmp); @@ -1111,7 +1150,8 @@ OPCODE1(F_ASSIGN_ALL_INDICES, "assign[*]", I_UPDATE_SP, { pop_stack(); /* leaves arr on stack. */ }); -OPCODE2(F_APPLY_ASSIGN_LOCAL_AND_POP, "apply, assign local and pop", I_UPDATE_SP|I_UPDATE_M_SP, { +OPCODE2(F_APPLY_ASSIGN_LOCAL_AND_POP, + "apply, assign local and pop", I_UPDATE_SP|I_UPDATE_M_SP, { apply_svalue(&((Pike_fp->context->prog->constants + arg1)->sval), DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp))); free_svalue(Pike_fp->locals+arg2); @@ -1154,7 +1194,8 @@ OPCODE1(F_ASSIGN_GLOBAL_AND_POP, "assign global and pop", I_UPDATE_SP, { pop_stack(); }); -OPCODE1(F_ASSIGN_PRIVATE_GLOBAL_AND_POP, "assign private global and pop", I_UPDATE_SP, { +OPCODE1(F_ASSIGN_PRIVATE_GLOBAL_AND_POP, + "assign private global and pop", I_UPDATE_SP, { LOCAL_VAR(struct svalue *tmp); LOCAL_VAR(struct object *co); co = Pike_fp->current_object; @@ -1171,7 +1212,7 @@ OPCODE1(F_ASSIGN_PRIVATE_GLOBAL, "assign private global", I_UPDATE_SP, { co = Pike_fp->current_object; if(!co->prog) /* note: generate an error. */ object_low_set_index(co,0,0); - tmp = (struct svalue *)(Pike_fp->current_object->storage + Pike_fp->context->storage_offset + arg1); + tmp = (struct svalue *)(co->storage +Pike_fp->context->storage_offset +arg1); assign_svalue( tmp, Pike_sp-1 ); });