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 );
 });