Пример #1
0
/*
 * Check the contents of a register for NULL and re-execute
 * the current instruction in the interpreter if it is.
 * If null check elmination is enabled, this function does nothing.
 */
static void CheckForNull(MDUnroll *unroll, int reg, unsigned char *pc,
						 unsigned char *label, int popReg)
{
#ifndef IL_USE_INTERRUPT_BASED_NULL_POINTER_CHECKS
	md_inst_ptr patch;

	/* Check the register's contents against NULL */
	md_reg_is_null(unroll->out, reg);
	patch = unroll->out;
#ifdef CVM_X86
	x86_branch8(unroll->out, X86_CC_NE, 0, 0);
#else
	md_branch_ne(unroll->out);
#endif

	/* Re-execute the current instruction in the interpreter */
	if(popReg)
	{
		--(unroll->pseudoStackSize);
		ReExecute(unroll, pc, label);
		++(unroll->pseudoStackSize);
	}
	else
	{
		ReExecute(unroll, pc, label);
	}

	/* Continue with real execution here */
	md_patch(patch, unroll->out);
#endif
}
Пример #2
0
static void Divide(MDUnroll *unroll, int isSigned, int wantRemainder,
				      unsigned char *pc, unsigned char *label)
{
#if !defined(IL_USE_INTERRUPT_BASED_INT_DIVIDE_BY_ZERO_CHECKS)
	#define IL_NEED_DIVIDE_REEXECUTE 1
#endif
	int reg, reg2;	
#ifdef IL_NEED_DIVIDE_REEXECUTE
	md_inst_ptr patch1 = NULL;
	md_inst_ptr patch2 = NULL;
	md_inst_ptr patch3 = NULL;
#endif
	GetTopTwoWordRegisters(unroll, &reg, &reg2, MD_REG1_32BIT | MD_REG2_32BIT);

#ifdef IL_NEED_DIVIDE_REEXECUTE
	md_reg_is_zero(unroll->out, reg2);
	patch1 = unroll->out;
	md_branch_eq(unroll->out);
	if(isSigned)
	{
		md_cmp_reg_imm_word_32(unroll->out, MD_CC_EQ, reg2, -1);
		patch2 = unroll->out;
		md_branch_ne(unroll->out);
		md_cmp_reg_imm_word_32(unroll->out, MD_CC_EQ, reg, IL_MIN_INT32);
		patch3 = unroll->out;
		md_branch_ne(unroll->out);
	}
	md_patch(patch1, unroll->out);	
	ReExecute(unroll, pc, label);
	if(isSigned)
	{
		md_patch(patch2, unroll->out);	
		md_patch(patch3, unroll->out);	
	}
#endif

	if(wantRemainder)
	{
		if(isSigned)
		{
			md_rem_reg_reg_word_32(unroll->out, reg, reg2);
		}
		else
		{
			md_urem_reg_reg_word_32(unroll->out, reg, reg2);
		}
	}
	else
	{
		if(isSigned)
		{
			md_div_reg_reg_word_32(unroll->out, reg, reg2);
		}
		else
		{
			md_udiv_reg_reg_word_32(unroll->out, reg, reg2);
		}
	}
	FreeTopRegister(unroll, -1);
}
Пример #3
0
/*
 * Check an array access operation for exception conditions.
 */
static void CheckArrayAccess(MDUnroll *unroll, int reg, int reg2,
							 unsigned char *pc, unsigned char *label)
{
#ifndef IL_USE_INTERRUPT_BASED_NULL_POINTER_CHECKS
	md_inst_ptr patch1;
#endif
	md_inst_ptr patch2;

#ifndef IL_USE_INTERRUPT_BASED_NULL_POINTER_CHECKS
	/* Check the array reference against NULL */
	md_reg_is_null(unroll->out, reg);
	patch1 = unroll->out;
#ifdef CVM_X86
	x86_branch8(unroll->out, X86_CC_EQ, 0, 0);
#else
	md_branch_eq(unroll->out);
#endif
#endif
	/* Check the array bounds */
	md_bounds_check(unroll->out, reg, reg2);
	patch2 = unroll->out;
	md_branch_lt_un(unroll->out);

#ifndef IL_USE_INTERRUPT_BASED_NULL_POINTER_CHECKS
	/* Re-execute the current instruction in the interpreter */
	md_patch(patch1, unroll->out);
#endif
	ReExecute(unroll, pc, label);

	/* Continue with real execution here */
	md_patch(patch2, unroll->out);
}
Пример #4
0
/*
 * Check a 2D array access operation for exception conditions.
 */
static void Check2DArrayAccess(MDUnroll *unroll, int reg, int reg2, int reg3,
							   unsigned char *pc, unsigned char *label)
{
#ifndef IL_USE_INTERRUPT_BASED_NULL_POINTER_CHECKS
	md_inst_ptr patch1;
#endif
	md_inst_ptr patch2;
	md_inst_ptr patch3;

#ifndef IL_USE_INTERRUPT_BASED_NULL_POINTER_CHECKS
	/* Check the array reference against NULL */
	arm_test_reg_imm8(unroll->out, ARM_CMP, reg, 0);
	patch1 = unroll->out;
	arm_branch_imm(unroll->out, ARM_CC_EQ, 0);
#endif

	/* Check the array bounds.  We assume that we can use the link
	   register as a work register because "lr" would have been
	   saved on entry to "_ILCVMInterpreter" */
	arm_load_membase(unroll->out, ARM_WORK, reg, 12);
	arm_alu_reg_reg(unroll->out, ARM_SUB, reg2, reg2, ARM_WORK);
	arm_load_membase(unroll->out, ARM_LINK, reg, 16);
	arm_test_reg_reg(unroll->out, ARM_CMP, reg2, ARM_LINK);
	patch2 = unroll->out;
	arm_branch_imm(unroll->out, ARM_CC_LT_UN, 0);
	arm_alu_reg_reg(unroll->out, ARM_ADD, reg2, reg2, ARM_WORK);
	patch3 = unroll->out;
	arm_jump_imm(unroll->out, 0);
	arm_patch(patch2, unroll->out);
	arm_load_membase(unroll->out, ARM_WORK, reg, 24);
	arm_alu_reg_reg(unroll->out, ARM_SUB, reg3, reg3, ARM_WORK);
	arm_load_membase(unroll->out, ARM_LINK, reg, 28);
	arm_test_reg_reg(unroll->out, ARM_CMP, reg3, ARM_LINK);
	patch2 = unroll->out;
	arm_branch_imm(unroll->out, ARM_CC_LT_UN, 0);
	arm_alu_reg_reg(unroll->out, ARM_ADD, reg3, reg3, ARM_WORK);
	arm_load_membase(unroll->out, ARM_WORK, reg, 12);
	arm_alu_reg_reg(unroll->out, ARM_ADD, reg2, reg2, ARM_WORK);

	/* Re-execute the current instruction in the interpreter */
#ifndef IL_USE_INTERRUPT_BASED_NULL_POINTER_CHECKS
	arm_patch(patch1, unroll->out);
#endif
	arm_patch(patch3, unroll->out);
	ReExecute(unroll, pc, label);

	/* Compute the address of the array element */
	arm_patch(patch2, unroll->out);
	arm_load_membase(unroll->out, ARM_WORK, reg, 20);
	arm_mul_reg_reg(unroll->out, reg2, reg2, ARM_WORK);
	arm_load_membase(unroll->out, ARM_WORK, reg, 32);
	arm_mul_reg_reg(unroll->out, reg3, reg3, ARM_WORK);
	arm_alu_reg_reg(unroll->out, ARM_ADD, reg2, reg2, reg3);
	arm_load_membase(unroll->out, ARM_WORK, reg, 4);
	arm_mul_reg_reg(unroll->out, reg2, reg2, ARM_WORK);
	arm_load_membase(unroll->out, reg, reg, 8);
	arm_alu_reg_reg(unroll->out, ARM_ADD, reg, reg, reg2);
}
Пример #5
0
// Thread that waits for forfig change and then restarts the program
static void * Config_Monitor_Watchthread( void * v)
{
	DETACH_THREAD ;
	// Blocking call until a config change detected
	Config_Monitor_Block() ;
	LEVEL_DEBUG("Configuration file change detected. Will restart %s",Globals.argv[0]);
	// Restart the program
	ReExecute(v) ;
	return v ;
}
Пример #6
0
/*
 * Check a 2D array access operation for exception conditions.
 */
static void Check2DArrayAccess(MDUnroll *unroll, int reg, int reg2, int reg3,
							   unsigned char *pc, unsigned char *label)
{
#ifndef IL_USE_INTERRUPT_BASED_NULL_POINTER_CHECKS
	unsigned char *patch1;
#endif
	unsigned char *patch2;
	unsigned char *patch3;

#ifndef IL_USE_INTERRUPT_BASED_NULL_POINTER_CHECKS
	/* Check the array reference against NULL */
	x86_alu_reg_reg(unroll->out, X86_OR, reg, reg);
	patch1 = unroll->out;
	x86_branch8(unroll->out, X86_CC_EQ, 0, 0);
#endif

	/* Check the array bounds */
	x86_alu_reg_membase(unroll->out, X86_SUB, reg2, reg, 12);
	x86_alu_reg_membase(unroll->out, X86_CMP, reg2, reg, 16);
	patch2 = unroll->out;
	x86_branch32(unroll->out, X86_CC_LT, 0, 0);
	x86_alu_reg_membase(unroll->out, X86_ADD, reg2, reg, 12);
	patch3 = unroll->out;
	x86_jump8(unroll->out, 0);
	x86_patch(patch2, unroll->out);
	x86_alu_reg_membase(unroll->out, X86_SUB, reg3, reg, 24);
	x86_alu_reg_membase(unroll->out, X86_CMP, reg3, reg, 28);
	patch2 = unroll->out;
	x86_branch32(unroll->out, X86_CC_LT, 0, 0);
	x86_alu_reg_membase(unroll->out, X86_ADD, reg2, reg, 12);
	x86_alu_reg_membase(unroll->out, X86_ADD, reg3, reg, 28);

	/* Re-execute the current instruction in the interpreter */
#ifndef IL_USE_INTERRUPT_BASED_NULL_POINTER_CHECKS
	x86_patch(patch1, unroll->out);
#endif
	x86_patch(patch3, unroll->out);
	ReExecute(unroll, pc, label);

	/* Compute the address of the array element */
	x86_patch(patch2, unroll->out);
	x86_imul_reg_membase(unroll->out, reg2, reg, 20);
	x86_imul_reg_membase(unroll->out, reg3, reg, 32);
	x86_alu_reg_reg(unroll->out, X86_ADD, reg2, reg3);
	x86_imul_reg_membase(unroll->out, reg2, reg, 4);
	x86_mov_reg_membase(unroll->out, reg, reg, 8, 4);
	x86_alu_reg_reg(unroll->out, X86_ADD, reg, reg2);
}
Пример #7
0
/*
 * Perform an integer division or remainder.
 */
static void Divide(MDUnroll *unroll, int isSigned, int wantRemainder,
				      unsigned char *pc, unsigned char *label)
{
#if !defined(IL_USE_INTERRUPT_BASED_INT_DIVIDE_BY_ZERO_CHECKS)
	#define IL_NEED_DIVIDE_REEXECUTE 1
	unsigned char *patch1;
#endif

#if !defined(IL_USE_INTERRUPT_BASED_INT_OVERFLOW_CHECKS)
	#define IL_NEED_DIVIDE_REEXECUTE 1
	unsigned char  *patch2, *patch3;
#endif

	/* Get the arguments into EAX and ECX so we know where they are */
	if(unroll->pseudoStackSize != 2 ||
	   unroll->pseudoStack[0] != X86_EAX ||
	   unroll->pseudoStack[1] != X86_ECX)
	{
		FlushRegisterStack(unroll);
		unroll->stackHeight -= 8;
		x86_mov_reg_membase(unroll->out, X86_EAX, MD_REG_STACK,
							unroll->stackHeight, 4);
		x86_mov_reg_membase(unroll->out, X86_ECX, MD_REG_STACK,
							unroll->stackHeight + 4, 4);
		unroll->pseudoStack[0] = X86_EAX;
		unroll->pseudoStack[1] = X86_ECX;
		unroll->pseudoStackSize = 2;
		unroll->regsUsed |= ((1 << X86_EAX) | (1 << X86_ECX));
	}

	/* Check for conditions that may cause an exception */
#if !defined(IL_USE_INTERRUPT_BASED_INT_DIVIDE_BY_ZERO_CHECKS)
	x86_alu_reg_imm(unroll->out, X86_CMP, X86_ECX, 0);
	patch1 = unroll->out;
	x86_branch8(unroll->out, X86_CC_EQ, 0, 0);
#endif

#if !defined(IL_USE_INTERRUPT_BASED_INT_OVERFLOW_CHECKS)
	x86_alu_reg_imm(unroll->out, X86_CMP, X86_ECX, -1);
	patch2 = unroll->out;
	x86_branch32(unroll->out, X86_CC_NE, 0, 0);

	x86_alu_reg_imm(unroll->out, X86_CMP, X86_EAX, (int)0x80000000);
	patch3 = unroll->out;
	x86_branch32(unroll->out, X86_CC_NE, 0, 0);
#endif

#if !defined(IL_USE_INTERRUPT_BASED_INT_DIVIDE_BY_ZERO_CHECKS)
	x86_patch(patch1, unroll->out);
#endif

#if defined(IL_NEED_DIVIDE_REEXECUTE)
	/* Re-execute the division instruction to throw the exception */
	ReExecute(unroll, pc, label);
#endif

#if !defined(IL_USE_INTERRUPT_BASED_INT_OVERFLOW_CHECKS)
	x86_patch(patch2, unroll->out);
	x86_patch(patch3, unroll->out);
#endif

	/* Perform the division */
	if(isSigned)
	{
		x86_cdq(unroll->out);
	}
	else
	{
		x86_clear_reg(unroll->out, X86_EDX);
	}
	x86_div_reg(unroll->out, X86_ECX, isSigned);

	/* Pop ECX from the pseudo stack */
	FreeTopRegister(unroll, -1);

	/* If we want the remainder, then replace EAX with EDX on the stack */
	if(wantRemainder)
	{
		unroll->pseudoStack[0] = X86_EDX;
		unroll->regsUsed = (1 << X86_EDX);
	}
}
Пример #8
0
static void Check2DArrayAccess(MDUnroll *unroll, int reg, int reg2, int reg3,
							   unsigned char *pc, unsigned char *label)
{
#ifndef IL_USE_INTERRUPT_BASED_NULL_POINTER_CHECKS
	md_inst_ptr patch1;
#endif
	md_inst_ptr patch2;
	md_inst_ptr patch3;

	/* redefinitions to make it a lot clearer for me to debug */
	int array  = reg;
	int i = reg2;
	int j = reg3;
	int work = PPC_WORK;

	/*
	  Algorithm of calc_address:
		
	  a->data + (((i - a->bounds[0].lower) * a->bounds[0].multiplier) +
	  	(j - a->bounds[1].lower) * a->bounds[0].multiplier)) * a->elemSize)
	  
	  I've tried to pre-compute a->bounds into bounds (or MD_REG_PC)
	*/
#ifndef IL_USE_INTERRUPT_BASED_NULL_POINTER_CHECKS
	md_reg_is_null(unroll->out, reg);
	patch1 = unroll->out;
	md_branch_eq(unroll->out);
#endif

	md_load_membase_word_32(unroll->out, work, array, 
									offsetof(System_MArray, bounds) 
									+ offsetof(MArrayBounds, lower));
	md_sub_reg_reg_word_32(unroll->out, i, work); 
	
	md_load_membase_word_32(unroll->out, work, array, 
									offsetof(System_MArray, bounds)
									+ offsetof(MArrayBounds, size));

	md_cmp_cc_reg_reg_word_32(unroll->out, MD_CC_GE_UN, i, work);

	patch2 = unroll->out;
	md_branch_ge_un(unroll->out);

	
	md_load_membase_word_32(unroll->out, work, array, 
									offsetof(System_MArray, bounds)
									+ sizeof(MArrayBounds)
									+ offsetof(MArrayBounds, lower));
									
	md_sub_reg_reg_word_32(unroll->out, j, work); 
	
	md_load_membase_word_32(unroll->out, work, array, 
									offsetof(System_MArray, bounds)
									+ sizeof(MArrayBounds)
									+ offsetof(MArrayBounds, size));

	md_cmp_cc_reg_reg_word_32(unroll->out, MD_CC_GE_UN, j, work);

	patch3 = unroll->out;
	md_branch_lt_un(unroll->out);

	md_load_membase_word_32(unroll->out, work, array, 
									offsetof(System_MArray, bounds)
									+ sizeof(MArrayBounds)
									+ offsetof(MArrayBounds, lower));
									
	md_add_reg_reg_word_32(unroll->out, j, work); 
	
	md_patch(patch2, unroll->out);	

	md_load_membase_word_32(unroll->out, work, array, 
									offsetof(System_MArray, bounds)
									+ offsetof(MArrayBounds, lower));
									
	md_add_reg_reg_word_32(unroll->out, i, work); 
#ifndef IL_USE_INTERRUPT_BASED_NULL_POINTER_CHECKS
	md_patch(patch1, unroll->out);	
#endif
	ReExecute(unroll, pc, label);

	/* calculate address */
	md_patch(patch3, unroll->out);	
	
	md_load_membase_word_32(unroll->out, work, array, 
									offsetof(System_MArray, bounds)
									+ offsetof(MArrayBounds, multiplier));
	md_mul_reg_reg_word_32(unroll->out, i, work);

	md_load_membase_word_32(unroll->out, work, array, 
									offsetof(System_MArray, bounds)
									+ sizeof(MArrayBounds)
									+ offsetof(MArrayBounds, multiplier));
	md_mul_reg_reg_word_32(unroll->out, j, work);

	md_load_membase_word_32(unroll->out, work, array, 
									offsetof(System_MArray, elemSize));

	md_add_reg_reg_word_32(unroll->out, i, j);
	
	md_load_membase_word_native(unroll->out, reg, array, 
									offsetof(System_MArray,	data));
	
	md_mul_reg_reg_word_32(unroll->out, i, work);
	
	ppc_cache_prefetch(unroll->out, reg, i);

	md_reg_to_word_native(unroll->out, i);
	md_add_reg_reg_word_native(unroll->out, reg, i);
}
Пример #9
0
/*
 * Check a 2D array access operation for exception conditions.
 */
static void Check2DArrayAccess(MDUnroll *unroll, int reg, int reg2, int reg3,
							   unsigned char *pc, unsigned char *label)
{
#ifndef IL_USE_INTERRUPT_BASED_NULL_POINTER_CHECKS
	unsigned char *patch1;
#endif
	unsigned char *patch2;
	unsigned char *patch3;

#ifndef IL_USE_INTERRUPT_BASED_NULL_POINTER_CHECKS
	/* Check the array reference against NULL */
	amd64_alu_reg_reg(unroll->out, X86_OR, reg, reg);
	patch1 = unroll->out;
	amd64_branch8(unroll->out, X86_CC_EQ, 0, 0);
#endif

	/*
	  a->data + (((i - a->bounds[0].lower) * a->bounds[0].multiplier) +
	  	(j - a->bounds[1].lower) * a->bounds[0].multiplier)) * a->elemSize)

	  as follows

	  i = i - a->bounds[0].lower 
	  j = j - a->bounds[1].lower
	  i = i * a->bounds[0].multiplier
	  j = j * a->bounds[1].multiplier
	  i = i + j
	  i = i * a->elemSize
	  a = a->data
	  a = a + i
	*/

	/* Check the array bounds (all of which are ILInt32) */
	amd64_alu_reg_membase_size(unroll->out, X86_SUB, reg2, reg, 
							offsetof(System_MArray, bounds)
							+ offsetof(MArrayBounds, lower),
							4); /* i = i - a->bounds[0].lower */
	
	amd64_alu_reg_membase_size(unroll->out, X86_CMP, reg2, reg,
							offsetof(System_MArray, bounds)
							+ offsetof(MArrayBounds, size),
							4);
	patch2 = unroll->out;
	amd64_branch32(unroll->out, X86_CC_LT, 0, 0);
	amd64_alu_reg_membase_size(unroll->out, X86_ADD, reg2, reg, 
							offsetof(System_MArray, bounds)
							+ offsetof(MArrayBounds, lower),
							4);
	patch3 = unroll->out;
	amd64_jump8(unroll->out, 0);
	amd64_patch(patch2, unroll->out);

	amd64_alu_reg_membase_size(unroll->out, X86_SUB, reg3, reg,
							offsetof(System_MArray, bounds)
							+ sizeof(MArrayBounds)
							+ offsetof(MArrayBounds, lower),
							4); /* j = j - a->bounds[1].lower */
	
	amd64_alu_reg_membase_size(unroll->out, X86_CMP, reg3, reg, 
							offsetof(System_MArray, bounds)
							+ sizeof(MArrayBounds)
							+ offsetof(MArrayBounds, size),
							4);
	patch2 = unroll->out;
	amd64_branch32(unroll->out, X86_CC_LT, 0, 0);
	amd64_alu_reg_membase_size(unroll->out, X86_ADD, reg2, reg,
							offsetof(System_MArray, bounds) +
							offsetof(MArrayBounds, lower),
							4);
	amd64_alu_reg_membase_size(unroll->out, X86_ADD, reg3, reg,
							offsetof(System_MArray, bounds) 
							+ sizeof(MArrayBounds)
							+ offsetof(MArrayBounds, lower),
							4);

	/* Re-execute the current instruction in the interpreter */
#ifndef IL_USE_INTERRUPT_BASED_NULL_POINTER_CHECKS
	amd64_patch(patch1, unroll->out);
#endif
	amd64_patch(patch3, unroll->out);
	ReExecute(unroll, pc, label);

	/* Compute the address of the array element */
	amd64_patch(patch2, unroll->out);
	
	amd64_imul_reg_membase_size(unroll->out, reg2, reg, 
									offsetof(System_MArray, bounds)
									+ offsetof(MArrayBounds, multiplier),
									4); /* i = i * a->bounds[0].multiplier */
	amd64_imul_reg_membase_size(unroll->out, reg3, reg,
									offsetof(System_MArray, bounds)
									+ sizeof(MArrayBounds)
									+ offsetof(MArrayBounds, multiplier),
									4); /* j = j * a->bounds[1].multiplier */
	amd64_alu_reg_reg(unroll->out, X86_ADD, reg2, reg3); /* i = i + j */
	amd64_imul_reg_membase_size(unroll->out, reg2, reg,
									offsetof(System_MArray, elemSize),
									4); /* i = i * a->elemSize */
	amd64_mov_reg_membase(unroll->out, reg, reg, 
									offsetof(System_MArray, data), 
									8); /* a = a->data */
	
	/* up-convert to 32 bit */
	amd64_movsxd_reg_reg(unroll->out, reg2, reg2);
	amd64_alu_reg_reg(unroll->out, X86_ADD, reg, reg2); /* a = a + i */
}