This commit is contained in:
jfrijters 2006-04-20 13:20:57 +00:00
Родитель 2e97873a92
Коммит 5b0dcf1146
4 изменённых файлов: 33 добавлений и 2 удалений

Просмотреть файл

@ -59,6 +59,11 @@ public final class WeakIdentityMap
{ {
if (key == null) if (key == null)
throw new NullPointerException(); throw new NullPointerException();
putImpl(key, value, true);
}
private void putImpl(Object key, Object value, boolean tryGC)
{
int emptySlot = -1; int emptySlot = -1;
int keySlot = -1; int keySlot = -1;
for (int i = 0; i < keys.length; i++) for (int i = 0; i < keys.length; i++)
@ -85,6 +90,12 @@ public final class WeakIdentityMap
} }
else else
{ {
if (tryGC)
{
GC.Collect(0);
putImpl(key, value, false);
return;
}
int len = keys.length; int len = keys.length;
WeakReference[] newkeys = new WeakReference[len * 2]; WeakReference[] newkeys = new WeakReference[len * 2];
Object[] newvalues = new Object[newkeys.length]; Object[] newvalues = new Object[newkeys.length];

Просмотреть файл

@ -379,6 +379,7 @@ enum NormalizedByteCode : byte
__ifnull = 198, __ifnull = 198,
__ifnonnull = 199, __ifnonnull = 199,
// This is where the pseudo-bytecodes start // This is where the pseudo-bytecodes start
__athrow_no_unmap = 244,
__dynamic_getstatic = 245, __dynamic_getstatic = 245,
__dynamic_putstatic = 246, __dynamic_putstatic = 246,
__dynamic_getfield = 247, __dynamic_getfield = 247,

Просмотреть файл

@ -2497,6 +2497,14 @@ namespace IKVM.Internal
} }
} }
internal bool IsBranchTarget
{
get
{
return (flags & InstructionFlags.BranchTarget) != 0;
}
}
internal void PatchOpCode(NormalizedByteCode bc) internal void PatchOpCode(NormalizedByteCode bc)
{ {
this.normopcode = bc; this.normopcode = bc;

Просмотреть файл

@ -1382,7 +1382,7 @@ class Compiler
// if there was a forward branch to this instruction, it is forward reachable // if there was a forward branch to this instruction, it is forward reachable
instructionIsForwardReachable |= block.HasLabel(i); instructionIsForwardReachable |= block.HasLabel(i);
if(block.HasLabel(i) || (instr.flags & ClassFile.Method.InstructionFlags.BranchTarget) != 0) if(block.HasLabel(i) || instr.IsBranchTarget)
{ {
block.MarkLabel(i); block.MarkLabel(i);
} }
@ -1714,6 +1714,10 @@ class Compiler
&& thisType.GetMethodWrapper("fillInStackTrace", "()Ljava.lang.Throwable;", true).DeclaringType == java_lang_Throwable) && thisType.GetMethodWrapper("fillInStackTrace", "()Ljava.lang.Throwable;", true).DeclaringType == java_lang_Throwable)
{ {
ilGenerator.Emit(OpCodes.Call, suppressFillInStackTraceMethod); ilGenerator.Emit(OpCodes.Call, suppressFillInStackTraceMethod);
if(!code[i + 1].IsBranchTarget)
{
code[i + 1].PatchOpCode(NormalizedByteCode.__athrow_no_unmap);
}
} }
} }
method.EmitNewobj(ilGenerator); method.EmitNewobj(ilGenerator);
@ -2766,8 +2770,14 @@ class Compiler
case NormalizedByteCode.__monitorexit: case NormalizedByteCode.__monitorexit:
ilGenerator.Emit(OpCodes.Call, monitorExitMethod); ilGenerator.Emit(OpCodes.Call, monitorExitMethod);
break; break;
case NormalizedByteCode.__athrow_no_unmap:
if(ma.GetRawStackTypeWrapper(i, 0).IsUnloadable)
{
ilGenerator.Emit(OpCodes.Castclass, typeof(Exception));
}
ilGenerator.Emit(OpCodes.Throw);
break;
case NormalizedByteCode.__athrow: case NormalizedByteCode.__athrow:
// TODO we shouldn't call unmap when we know it isn't needed
if(ma.GetRawStackTypeWrapper(i, 0).IsUnloadable) if(ma.GetRawStackTypeWrapper(i, 0).IsUnloadable)
{ {
ilGenerator.Emit(OpCodes.Castclass, typeof(Exception)); ilGenerator.Emit(OpCodes.Castclass, typeof(Exception));
@ -2948,6 +2958,7 @@ class Compiler
case NormalizedByteCode.__areturn: case NormalizedByteCode.__areturn:
case NormalizedByteCode.__return: case NormalizedByteCode.__return:
case NormalizedByteCode.__athrow: case NormalizedByteCode.__athrow:
case NormalizedByteCode.__athrow_no_unmap:
case NormalizedByteCode.__static_error: case NormalizedByteCode.__static_error:
instructionIsForwardReachable = false; instructionIsForwardReachable = false;
break; break;