Ejemplo n.º 1
0
 private static bool Object_getClass(EmitIntrinsicContext eic)
 {
     // this is the null-check idiom that javac uses (both in its own source and in the code it generates)
     if (eic.MatchRange(0, 2) &&
         eic.Match(1, NormalizedByteCode.__pop))
     {
         eic.Emitter.Emit(OpCodes.Dup);
         eic.Emitter.EmitNullCheck();
         return(true);
     }
     // this optimizes obj1.getClass() ==/!= obj2.getClass()
     else if (eic.MatchRange(0, 4) &&
              eic.Match(1, NormalizedByteCode.__aload) &&
              eic.Match(2, NormalizedByteCode.__invokevirtual) &&
              (eic.Match(3, NormalizedByteCode.__if_acmpeq) || eic.Match(3, NormalizedByteCode.__if_acmpne)) &&
              (IsSafeForGetClassOptimization(eic.GetStackTypeWrapper(0, 0)) || IsSafeForGetClassOptimization(eic.GetStackTypeWrapper(2, 0))))
     {
         ClassFile.ConstantPoolItemMI cpi = eic.GetMethodref(2);
         if (cpi.Class == "java.lang.Object" && cpi.Name == "getClass" && cpi.Signature == "()Ljava.lang.Class;")
         {
             // we can't patch the current opcode, so we have to emit the first call to GetTypeHandle here
             eic.Emitter.Emit(OpCodes.Callvirt, Compiler.getTypeMethod);
             eic.PatchOpCode(2, NormalizedByteCode.__intrinsic_gettype);
             return(true);
         }
     }
     // this optimizes obj.getClass() == Xxx.class
     else if (eic.MatchRange(0, 3) &&
              eic.Match(1, NormalizedByteCode.__ldc) && eic.GetConstantType(1) == ClassFile.ConstantType.Class &&
              (eic.Match(2, NormalizedByteCode.__if_acmpeq) || eic.Match(2, NormalizedByteCode.__if_acmpne)))
     {
         TypeWrapper tw = eic.GetClassLiteral(1);
         if (tw.IsGhost || tw.IsGhostArray || tw.IsUnloadable || (tw.IsRemapped && tw.IsFinal && tw is DotNetTypeWrapper))
         {
             return(false);
         }
         eic.Emitter.Emit(OpCodes.Callvirt, Compiler.getTypeMethod);
         eic.Emitter.Emit(OpCodes.Ldtoken, (tw.IsRemapped && tw.IsFinal) ? tw.TypeAsTBD : tw.TypeAsBaseType);
         eic.Emitter.Emit(OpCodes.Call, Compiler.getTypeFromHandleMethod);
         eic.PatchOpCode(1, NormalizedByteCode.__nop);
         return(true);
     }
     return(false);
 }