Byteman 2.1.2 is for the most part a maintenance update to release 2.1.0, fixing about half a dozen bugs. However, it does include a few new features. In particular:
- Allow downcasts when initialising local vars in the BIND clause
- Support computing object size as a standard method in Helper
class Foo { void foo(Listnames) . . . }
downcasting allows you to bind elements of the argument list using the type String rather than the generic type Object
RULE access name as a name CLASS Foo METHOD foo BIND first : String = $names.get(0); second : String = $names.get(1); IF first == "Andrew" && second == "Dinn" DO throw new Exception("Won't get fooed again!") ENDRULE
Of course, Byteman performs a checkcast before binding the variables so when the rule executes if you try to downcast a value which is not an instance of the subtype your program will see a ClassCastException.
If you want to disable downcasting and revert to the old behaviour where the type checker flags this as a type error the simply set system property
org.jboss.byteman.disallow.downcasts
in the JVM running the Byteman agent.
Hi,
ReplyDeleteyou are writing about new feature of byteman:
Support computing object size as a standard method in Helper
Can you provide any sample code for this functionality?
Thanks
Hi,
ReplyDeleteThis functionality is available with the latest release (2.1.2). The default helper class now provides a method with signature
public long getObjectSize(Object o);
This means that you can call this method as a built-in operation in your rules. Lets assume you havea class ByteArrayCache which hands out byte[] arrays on demand and then caches them when a client releases them for reuse. i.e.
class ByteArrayCache
{
public byte[] allocate(int minimumSize) { ... }
public void reuse(byte[] byteArray) { ... }
. . .
}
So, you might write some rules like this:
CLASS ByteArrayCache
METHOD allocate(int)
AT EXIT
BIND size = getObjectSize($!)
IF TRUE
DO traceln("allocated = " + incrementCounter("allocateCount", size))
ENDRULE
CLASS ByteArrayCache
METHOD reuse(byte[])
AT EXIT
BIND size = getObjectSize($1)
IF TRUE
DO traceln("allocated = " + decrementCounter("allocateCount", size))
ENDRULE
These rules trace how much byte[] storage has been handed out by class ByteArrayCache. In the first rule $! refers to a byte[] returned by allocate(). In the second rule $1 refers to the byte[] returned to the cache in the call to release().
Notice that in rule 1 you cannot use the size argument as the byte[] may be bigger than the required size. You could estimate the size using $!.length in the first rule and $1.length in the second rule but that only counts the number of bytes in the byte[]. It does not take account of how much space is used by the object header. getObjectSize returns an estimate of the total size of the byte[] including any Object header words which precede the byte contents. It is only an estimate but it is probably more accurate than just counting the bytes in the array.
This blog is really informative i really had fun reading it.
ReplyDeleteThanks, Raul. It's nice to be appreciated :-) I hope you have as much fun trying out Byteman.
ReplyDelete