Program: 149652
Project: 149652
Buggy source:
/** 
 * Check a single use, to see if this use may cause the object referenced to escape from this thread.
 * @param use the use to check
 * @param ir the governing IR
 * @return {@code true} if it may escape, {@code false} otherwise
 */
private static boolean checkEscapesThread(RegisterOperand use,IR ir,Set<Register> visited){
  Instruction inst=use.instruction;
switch (inst.getOpcode()) {
case INT_ASTORE_opcode:
case LONG_ASTORE_opcode:
case FLOAT_ASTORE_opcode:
case DOUBLE_ASTORE_opcode:
case BYTE_ASTORE_opcode:
case SHORT_ASTORE_opcode:
case REF_ASTORE_opcode:
    Operand value=AStore.getValue(inst);
  return value == use;
case GETFIELD_opcode:
case GETSTATIC_opcode:
case INT_ALOAD_opcode:
case LONG_ALOAD_opcode:
case FLOAT_ALOAD_opcode:
case DOUBLE_ALOAD_opcode:
case BYTE_ALOAD_opcode:
case UBYTE_ALOAD_opcode:
case BYTE_LOAD_opcode:
case UBYTE_LOAD_opcode:
case SHORT_ALOAD_opcode:
case USHORT_ALOAD_opcode:
case SHORT_LOAD_opcode:
case USHORT_LOAD_opcode:
case REF_ALOAD_opcode:
case INT_LOAD_opcode:
case LONG_LOAD_opcode:
case FLOAT_LOAD_opcode:
case DOUBLE_LOAD_opcode:
case REF_LOAD_opcode:
Operand result=ResultCarrier.getResult(inst);
return result == use;
case PUTFIELD_opcode:
value=PutField.getValue(inst);
return value == use;
case PUTSTATIC_opcode:
value=PutStatic.getValue(inst);
return value == use;
case BYTE_STORE_opcode:
case SHORT_STORE_opcode:
case REF_STORE_opcode:
case INT_STORE_opcode:
case LONG_STORE_opcode:
case FLOAT_STORE_opcode:
case DOUBLE_STORE_opcode:
value=Store.getValue(inst);
return value == use;
case BOUNDS_CHECK_opcode:
case MONITORENTER_opcode:
case MONITOREXIT_opcode:
case NULL_CHECK_opcode:
case ARRAYLENGTH_opcode:
case REF_IFCMP_opcode:
case INT_IFCMP_opcode:
case IG_PATCH_POINT_opcode:
case IG_CLASS_TEST_opcode:
case IG_METHOD_TEST_opcode:
case BOOLEAN_CMP_INT_opcode:
case BOOLEAN_CMP_ADDR_opcode:
case OBJARRAY_STORE_CHECK_opcode:
case OBJARRAY_STORE_CHECK_NOTNULL_opcode:
case GET_OBJ_TIB_opcode:
case GET_TYPE_FROM_TIB_opcode:
case NEW_opcode:
case NEWARRAY_opcode:
case NEWOBJMULTIARRAY_opcode:
case NEW_UNRESOLVED_opcode:
case NEWARRAY_UNRESOLVED_opcode:
case INSTANCEOF_opcode:
case INSTANCEOF_NOTNULL_opcode:
case INSTANCEOF_UNRESOLVED_opcode:
case CHECKCAST_opcode:
case MUST_IMPLEMENT_INTERFACE_opcode:
case CHECKCAST_NOTNULL_opcode:
case CHECKCAST_UNRESOLVED_opcode:
case GET_CAUGHT_EXCEPTION_opcode:
case IR_PROLOGUE_opcode:
return false;
case RETURN_opcode:
return !ir.isParameter(use);
case CALL_opcode:
MethodOperand mop=Call.getMethod(inst);
if (mop == null) {
return true;
}
if (!mop.hasPreciseTarget()) {
return true;
}
if (mop.getTarget().isPure()) {
return false;
}
if (mop.getTarget().isNative()) {
return false;
}
MethodSummary summ=findOrCreateMethodSummary(mop.getTarget(),ir.options);
if (summ == null) {
return true;
}
if (use == Call.getResult(inst)) {
return summ.resultMayEscapeThread();
}
int p=getParameterIndex(use,inst);
return summ.parameterMayEscapeThread(p);
case REF_MOVE_opcode:
{
Register copy=Move.getResult(inst).getRegister();
if (!copy.isSSA()) {
return true;
}
 else {
if (visited == null) {
visited=new HashSet<Register>();
}
visited.add(use.getRegister());
if (visited.contains(copy)) {
return false;
}
 else {
return checkIfUseEscapesThread(copy,ir,visited);
}
}
}
case ATHROW_opcode:
case PREPARE_INT_opcode:
case PREPARE_ADDR_opcode:
case PREPARE_LONG_opcode:
case ATTEMPT_LONG_opcode:
case ATTEMPT_INT_opcode:
case ATTEMPT_ADDR_opcode:
case INT_MOVE_opcode:
case INT_ADD_opcode:
case REF_ADD_opcode:
case INT_MUL_opcode:
case INT_DIV_opcode:
case INT_REM_opcode:
case INT_NEG_opcode:
case INT_ZERO_CHECK_opcode:
case INT_OR_opcode:
case INT_AND_opcode:
case INT_XOR_opcode:
case REF_OR_opcode:
case REF_AND_opcode:
case REF_XOR_opcode:
case INT_SUB_opcode:
case REF_SUB_opcode:
case INT_SHL_opcode:
case INT_SHR_opcode:
case INT_USHR_opcode:
case SYSCALL_opcode:
case REF_SHL_opcode:
case REF_SHR_opcode:
case REF_USHR_opcode:
case SET_CAUGHT_EXCEPTION_opcode:
case PHI_opcode:
case INT_2LONG_opcode:
case REF_COND_MOVE_opcode:
case INT_COND_MOVE_opcode:
case INT_2ADDRSigExt_opcode:
case INT_2ADDRZerExt_opcode:
case ADDR_2INT_opcode:
case ADDR_2LONG_opcode:
case YIELDPOINT_OSR_opcode:
return true;
default :
return Operators.helper.mayEscapeThread(inst);
}
}

Fixed version (ground truth):
/** 
 * Check a single use, to see if this use may cause the object referenced to escape from this thread.
 * @param use the use to check
 * @param ir the governing IR
 * @return {@code true} if it may escape, {@code false} otherwise
 */
private static boolean checkEscapesThread(RegisterOperand use,IR ir,Set<Register> visited){
  Instruction inst=use.instruction;
switch (inst.getOpcode()) {
case INT_ASTORE_opcode:
case LONG_ASTORE_opcode:
case FLOAT_ASTORE_opcode:
case DOUBLE_ASTORE_opcode:
case BYTE_ASTORE_opcode:
case SHORT_ASTORE_opcode:
case REF_ASTORE_opcode:
    Operand value=AStore.getValue(inst);
  return value == use;
case GETFIELD_opcode:
case GETSTATIC_opcode:
case INT_ALOAD_opcode:
case LONG_ALOAD_opcode:
case FLOAT_ALOAD_opcode:
case DOUBLE_ALOAD_opcode:
case BYTE_ALOAD_opcode:
case UBYTE_ALOAD_opcode:
case BYTE_LOAD_opcode:
case UBYTE_LOAD_opcode:
case SHORT_ALOAD_opcode:
case USHORT_ALOAD_opcode:
case SHORT_LOAD_opcode:
case USHORT_LOAD_opcode:
case REF_ALOAD_opcode:
case INT_LOAD_opcode:
case LONG_LOAD_opcode:
case FLOAT_LOAD_opcode:
case DOUBLE_LOAD_opcode:
case REF_LOAD_opcode:
Operand result=ResultCarrier.getResult(inst);
return result == use;
case PUTFIELD_opcode:
value=PutField.getValue(inst);
return value == use;
case PUTSTATIC_opcode:
value=PutStatic.getValue(inst);
return value == use;
case BYTE_STORE_opcode:
case SHORT_STORE_opcode:
case REF_STORE_opcode:
case INT_STORE_opcode:
case LONG_STORE_opcode:
case FLOAT_STORE_opcode:
case DOUBLE_STORE_opcode:
value=Store.getValue(inst);
return value == use;
case BOUNDS_CHECK_opcode:
case MONITORENTER_opcode:
case MONITOREXIT_opcode:
case NULL_CHECK_opcode:
case ARRAYLENGTH_opcode:
case REF_IFCMP_opcode:
case INT_IFCMP_opcode:
case IG_PATCH_POINT_opcode:
case IG_CLASS_TEST_opcode:
case IG_METHOD_TEST_opcode:
case BOOLEAN_CMP_INT_opcode:
case BOOLEAN_CMP_ADDR_opcode:
case OBJARRAY_STORE_CHECK_opcode:
case OBJARRAY_STORE_CHECK_NOTNULL_opcode:
case GET_OBJ_TIB_opcode:
case GET_TYPE_FROM_TIB_opcode:
case NEW_opcode:
case NEWARRAY_opcode:
case NEWOBJMULTIARRAY_opcode:
case NEW_UNRESOLVED_opcode:
case NEWARRAY_UNRESOLVED_opcode:
case INSTANCEOF_opcode:
case INSTANCEOF_NOTNULL_opcode:
case INSTANCEOF_UNRESOLVED_opcode:
case MUST_IMPLEMENT_INTERFACE_opcode:
case GET_CAUGHT_EXCEPTION_opcode:
case IR_PROLOGUE_opcode:
return false;
case RETURN_opcode:
return !ir.isParameter(use);
case CALL_opcode:
MethodOperand mop=Call.getMethod(inst);
if (mop == null) {
return true;
}
if (!mop.hasPreciseTarget()) {
return true;
}
if (mop.getTarget().isPure()) {
return false;
}
if (mop.getTarget().isNative()) {
return false;
}
MethodSummary summ=findOrCreateMethodSummary(mop.getTarget(),ir.options);
if (summ == null) {
return true;
}
if (use == Call.getResult(inst)) {
return summ.resultMayEscapeThread();
}
int p=getParameterIndex(use,inst);
return summ.parameterMayEscapeThread(p);
case CHECKCAST_opcode:
case CHECKCAST_NOTNULL_opcode:
case CHECKCAST_UNRESOLVED_opcode:
case REF_MOVE_opcode:
{
Register copy=ResultCarrier.getResult(inst).getRegister();
if (!copy.isSSA()) {
return true;
}
 else {
if (visited == null) {
visited=new HashSet<Register>();
}
visited.add(use.getRegister());
if (visited.contains(copy)) {
return false;
}
 else {
return checkIfUseEscapesThread(copy,ir,visited);
}
}
}
case ATHROW_opcode:
case PREPARE_INT_opcode:
case PREPARE_ADDR_opcode:
case PREPARE_LONG_opcode:
case ATTEMPT_LONG_opcode:
case ATTEMPT_INT_opcode:
case ATTEMPT_ADDR_opcode:
case INT_MOVE_opcode:
case INT_ADD_opcode:
case REF_ADD_opcode:
case INT_MUL_opcode:
case INT_DIV_opcode:
case INT_REM_opcode:
case INT_NEG_opcode:
case INT_ZERO_CHECK_opcode:
case INT_OR_opcode:
case INT_AND_opcode:
case INT_XOR_opcode:
case REF_OR_opcode:
case REF_AND_opcode:
case REF_XOR_opcode:
case INT_SUB_opcode:
case REF_SUB_opcode:
case INT_SHL_opcode:
case INT_SHR_opcode:
case INT_USHR_opcode:
case SYSCALL_opcode:
case REF_SHL_opcode:
case REF_SHR_opcode:
case REF_USHR_opcode:
case SET_CAUGHT_EXCEPTION_opcode:
case PHI_opcode:
case INT_2LONG_opcode:
case REF_COND_MOVE_opcode:
case INT_COND_MOVE_opcode:
case INT_2ADDRSigExt_opcode:
case INT_2ADDRZerExt_opcode:
case ADDR_2INT_opcode:
case ADDR_2LONG_opcode:
case YIELDPOINT_OSR_opcode:
return true;
default :
return Operators.helper.mayEscapeThread(inst);
}
}