Class DCRuntime
- Object
-
- DCRuntime
-
- All Implemented Interfaces:
ComparabilityProvider
public final class DCRuntime extends Object implements ComparabilityProvider
Runtime support for DynComp, a comparability front end for Chicory. This class is a collection of methods; it should never be instantiated.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
DCRuntime.FieldTag
Abstract base class for code that gets the tag associated with a particular field.static class
DCRuntime.PrimitiveArrayTag
Class that gets the list of tags for primitive arrays.static class
DCRuntime.PrimitiveTag
Class that gets the tag for a primitive instance field.static class
DCRuntime.ReferenceTag
Class that returns the tag for a reference instance field.static class
DCRuntime.StaticPrimitiveTag
Class that gets the tag for static primitive fields.static class
DCRuntime.StaticReferenceTag
Class that gets the tag for a static reference variable.
-
Field Summary
Fields Modifier and Type Field Description static boolean
debug
Control debug printing.static SimpleLog
debug_arr_index
Log array comparability operations.static SimpleLog
debug_decl_print
Log decl output.static SimpleLog
debug_merge_comp
Log comparability merges.static boolean
debug_objects
Log object compare operations.static SimpleLog
debug_primitive
Log primitive operations.static boolean
debug_tag_frame
Log comparability tage stack operations.static SimpleLog
debug_timing
Log excution time.static int
depth
Depth to follow fields in classes.static @Nullable Throwable
exit_exception
If the application exits with an exception, it should be placed here.static WeakIdentityHashMap<Object,Object[]>
field_map
Map from each object to the tags used for each primitive value in the object.static SimpleLog
map_info
Log internal data structure sizes.static SimpleLog
merge_dv
Log variable comparability operations.static Object
method_marker
Object used to mark procedure entries in the tag stack.static List<MethodInfo>
methods
List of all instrumented methods.static List<@Nullable Object>
static_tags
Storage for each static tag.static SimpleLog
time_decl
Log excution time.
-
Constructor Summary
Constructors Constructor Description DCRuntime()
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description static void
aastore(Object[] arr, int index, Object val)
Execute an aastore instruction and mark the array and its index as comparable.static void
bastore(byte[] arr, int index, byte val)
The JVM uses bastore for both boolean and byte data types.static void
binary_tag_op()
Handle a binary operation on the two items at the top of the tag stack.static void
castore(char[] arr, int index, char val)
Execute an castore instruction and manipulate the tags accordingly.static String
clean_decl_name(String decl_name)
Removes DCompMarker from the signature.static void
cmp_op()
Handles an i_cmpXX operation.static Object[]
create_tag_frame(String params)
Create the tag frame for this method.static void
dastore(double[] arr, int index, double val)
Execute an dastore instruction and manipulate the tags accordingly.static Object
dcomp_clone(Object orig_obj, Class<?> target_class)
Clone an object and return the cloned object.static Object
dcomp_clone_worker(Object orig_obj, Class<?> target_class)
Clone an object and return the cloned object.static boolean
dcomp_equals(Object o1, Object o2)
Handles calls to instrumented equals() methods.static Object
dcomp_super_clone(Object orig_obj, Class<?> target_class)
Handlessuper.clone()
calls.static boolean
dcomp_super_equals(Object o1, Object o2)
Handlessuper.equals(Object)
calls.static void
debug_print_call_stack()
static void
decl_stats()
Prints statistics about the number of decls to stdout.static void
discard_tag(int cnt)
Discard the tag on the top of the tag stack.static void
dup()
Handles a dup opcode on a primitive.static void
dup_x1()
Handles a dup_x1 opcode on a primitive.static void
dup_x2()
Handles a dup_x2 opcode on a primitive.static void
dup2()
Handles a dup2 opcode on a primitive.static void
dup2_x1()
Handles a dup2_x1 opcode on a primitive.static void
dup2_x2()
Handles a dup2_x2 opcode on a primitive.static void
enter(Object[] tag_frame, @Nullable Object obj, int mi_index, Object[] args)
Called when a user method is entered.static void
exception_exit(Object throwable)
Clean up the tag stack on an exception exit from a method.static void
exit(Object[] tag_frame, @Nullable Object obj, int mi_index, Object[] args, Object ret_val, int exit_line_number)
Called when a user method exits.static void
fastore(float[] arr, int index, float val)
Execute an fastore instruction and manipulate the tags accordingly.static Object
get_object_field(Field f, Object obj)
Gets the object in field f in object obj.String
getComparability(DaikonVariableInfo dv, DeclReader.DeclPpt compare_ppt)
Calculates a comparability value.static void
iastore(int[] arr, int index, int val)
Execute an iastore instruction and manipulate the tags accordingly.static void
init()
Perform any initialization required before instrumentation begins.static boolean
is_class_initialized(Class<?> clazz)
Returns whether or not the specified class is initialized.static void
lastore(long[] arr, int index, long val)
Execute an lastore instruction and manipulate the tags accordingly.static void
multianewarray2(int count1, int count2, Object[] arr)
Make the count arguments to multianewarray comparable to the corresponding array indices.static void
normal_exit(Object[] tag_frame)
Make sure the tag stack for this method is empty before exit.static void
normal_exit_primitive(Object[] tag_frame)
Called for exits from methods with a primitive return type.static int
num_prim_fields(Class<?> clazz)
Return the number of primitive fields in clazz and all of its superclasses.static boolean
object_eq(Object obj1, Object obj2)
Handle object comparison.static boolean
object_ne(Object obj1, Object obj2)
Handle object comparison.static void
pop_field_tag(Object obj, int field_num)
Pops the tag from the top of the tag stack and stores it in the tag storage for the specified field of the specified object.static void
pop_local_tag(Object[] tag_frame, int index)
Pops the top of the tag stack into tag_frame[index]static void
pop_static_tag(int static_num)
Pops the top of the tag stack into the tag storage for static_num.static void
primitive_array_load(Object arr_ref, int index)
Handles the various primitive (int, double, etc) array load instructions.static void
primitive_array_load_null_ok(Object arr_ref, int index)
Handles the various primitive (int, double, etc) array load instructions.static void
printAllComparable(PrintWriter pw)
Dumps out comparability information for all classes that were processed.static void
printClassDecl(PrintWriter pw, ClassInfo ci)
Calculates and prints the declarations for the specified class.static void
printComparable(PrintWriter pw, MethodInfo mi)
Prints comparability information for the enter and exit points of the specified method.static void
printComparableTraced(PrintWriter pw, MethodInfo mi)
Dumps out comparability trace information for a single method.static void
printDeclFile(PrintWriter pw)
Dumps out .decl file information for all classes that were processed.static void
printHeaderInfo(PrintWriter pw, String className)
Prints header information to the decls file.static List<DCRuntime.DVSet>
printMethod(PrintWriter pw, MethodInfo mi)
Prints a decl ENTER/EXIT records with comparability.static void
process_all_vars(MethodInfo mi, RootInfo root, Object[] tag_frame, Object obj, Object[] args, Object ret_val)
Process all of the daikon variables in the tree starting at root.static void
push_array_tag(Object arr_ref)
Pushes an array reference on the tag stack.static void
push_const()
Allocate a new tag for the constant and push it on the tag stack.static void
push_field_tag(Object obj, int field_num)
Pushes the tag associated with field_num in obj on the tag stack.static void
push_field_tag_null_ok(Object obj, int field_num)
Pushes the tag associated with field_num in obj on the tag stack.static void
push_local_tag(Object[] tag_frame, int index)
Pushes the tag at tag_frame[index] on the tag stack.static void
push_static_tag(int static_num)
Pushes the tag associated with the static static_num on the tag stack.static void
ref_array_load(Object arr_ref, int index)
Handles the aaload instruction.static void
sastore(short[] arr, int index, short val)
Execute an sastore instruction and manipulate the tags accordingly.static void
set_class_initialized(String classname)
Marks the specified class as initialized.static void
swap()
swaps the two elements on the top of the tag stackstatic String
tag_field_name(String field_name)
Returns the name of the tag field that corresponds to the specified field.static void
throw_op()
Cleans up the tag stack when an exception is thrown.static void
traceAllComparable(PrintWriter pw)
Dumps out comparability trace information for all classes that were processed.static void
zastore(boolean[] arr, int index, boolean val)
-
-
-
Field Detail
-
methods
public static final List<MethodInfo> methods
List of all instrumented methods.
-
depth
public static int depth
Depth to follow fields in classes.
-
exit_exception
public static @Nullable Throwable exit_exception
If the application exits with an exception, it should be placed here.
-
static_tags
public static List<@Nullable Object> static_tags
Storage for each static tag.
-
method_marker
public static Object method_marker
Object used to mark procedure entries in the tag stack. It is pushed on the stack at entry and checked on exit to make sure it is in on the top of the stack. That allows us to determine which method caused a tag stack problem.
-
debug
public static boolean debug
Control debug printing.
-
debug_tag_frame
public static boolean debug_tag_frame
Log comparability tage stack operations.
-
debug_objects
public static boolean debug_objects
Log object compare operations.
-
merge_dv
public static SimpleLog merge_dv
Log variable comparability operations.
-
debug_arr_index
public static SimpleLog debug_arr_index
Log array comparability operations.
-
debug_primitive
public static SimpleLog debug_primitive
Log primitive operations.
-
debug_merge_comp
public static SimpleLog debug_merge_comp
Log comparability merges.
-
debug_timing
public static SimpleLog debug_timing
Log excution time.
-
debug_decl_print
public static SimpleLog debug_decl_print
Log decl output.
-
time_decl
public static SimpleLog time_decl
Log excution time.
-
map_info
public static SimpleLog map_info
Log internal data structure sizes.
-
-
Constructor Detail
-
DCRuntime
public DCRuntime()
-
-
Method Detail
-
init
public static void init()
Perform any initialization required before instrumentation begins.
-
debug_print_call_stack
public static void debug_print_call_stack()
-
dcomp_equals
public static boolean dcomp_equals(Object o1, Object o2)
Handles calls to instrumented equals() methods. Makes the arguments comparable, and returns true if they are equals() to one another.- Parameters:
o1
- the first argument to equals()o2
- the second argument to equals()- Returns:
- whether the two values are equal
-
dcomp_super_equals
public static boolean dcomp_super_equals(Object o1, Object o2)
Handlessuper.equals(Object)
calls. Makes the arguments comparable, and returns true if super.equals() returns true for them- Parameters:
o1
- the first argument to super.equals()o2
- the second argument to super.equals()- Returns:
- whether the two values are equal, according to super.equals()
- See Also:
active_equals_calls
-
dcomp_clone
public static Object dcomp_clone(Object orig_obj, Class<?> target_class) throws Throwable
Clone an object and return the cloned object.DCInstrument guarantees we will not see a clone of an array. If the object has been instrumented, call the instrumented version of clone; if not, call the uninstrumented version and make the objects comparable. Really should make all of their fields comparable instead.
- Parameters:
orig_obj
- object being clonedtarget_class
- class to search for clone method- Returns:
- the result of the clone
- Throws:
Throwable
- if unable to clone object
-
dcomp_super_clone
public static Object dcomp_super_clone(Object orig_obj, Class<?> target_class) throws Throwable
Handlessuper.clone()
calls.Clone an object using its superclass, and returns the cloned object.
DCInstrument guarantees we will not see a clone of an array. If the object has been instrumented, call the instrumented version of clone; if not, call the uninstrumented version and make the objects comparable. TODO: This really should make all of their fields comparable instead.
- Parameters:
orig_obj
- object being clonedtarget_class
- class to search for clone method- Returns:
- the result of the clone
- Throws:
Throwable
- if unable to clone object- See Also:
active_clone_calls
-
dcomp_clone_worker
public static Object dcomp_clone_worker(Object orig_obj, Class<?> target_class) throws Throwable
Clone an object and return the cloned object. Throws an exception if unable to clone object.DCInstrument guarantees we will not see a clone of an array. If the object has been instrumented, call the instrumented version of clone; if not, call the uninstrumented version.
Note: we use getDeclaredMethod as clone is often protected; also, in the case of dcomp_super_clone we do not want to automatically find clone in a superclass. We will search the hierarchy ourselves.
- Parameters:
orig_obj
- object being clonedtarget_class
- class to search for clone method- Returns:
- the result of the clone
- Throws:
Throwable
- if unable to clone object
-
object_eq
public static boolean object_eq(Object obj1, Object obj2)
Handle object comparison. Marks the two objects as comparable and returns whether or not they are equal. Used as part of a replacement for IF_ACMPEQ.
-
object_ne
public static boolean object_ne(Object obj1, Object obj2)
Handle object comparison. Marks the two objects as comparable and returns whether or not they are equal. Used as part of a replacement for IF_ACMPNE.
-
create_tag_frame
public static Object[] create_tag_frame(String params)
Create the tag frame for this method. Pop the tags for any primitive parameters off of the tag stack and store them in the tag frame.- Parameters:
params
- encodes the position of the primitive parameters into a string. The first character is size of the tag frame. The remaining characters indicate where each parameter on the tag stack should be stored into the frame. For example "20" allocates a tag frame with two elements and stores the top of the tag stack into element 0. A string is used for simplicity in code generation since strings can easily be placed into the constant portion of the class file. Note that characters are determined by adding the integer value to '0'. Values greater than 9 will have unintuitive (but printable) values.- Returns:
- the allocated and initialized tag frame
-
normal_exit
public static void normal_exit(Object[] tag_frame)
Make sure the tag stack for this method is empty before exit.- Parameters:
tag_frame
- the tag frame
-
normal_exit_primitive
public static void normal_exit_primitive(Object[] tag_frame)
Called for exits from methods with a primitive return type. Pop the return type off of the tag stack, make sure the tags stack is empty for this method and then put the return value back on the tag stack.- Parameters:
tag_frame
- the tag frame
-
exception_exit
public static void exception_exit(Object throwable)
Clean up the tag stack on an exception exit from a method. Pops items off of the tag stack until the method marker is found.- Parameters:
throwable
- cause of the exception
-
throw_op
public static void throw_op()
Cleans up the tag stack when an exception is thrown.
-
push_local_tag
public static void push_local_tag(Object[] tag_frame, int index)
Pushes the tag at tag_frame[index] on the tag stack.
-
pop_local_tag
public static void pop_local_tag(Object[] tag_frame, int index)
Pops the top of the tag stack into tag_frame[index]
-
push_static_tag
public static void push_static_tag(int static_num)
Pushes the tag associated with the static static_num on the tag stack.
-
push_array_tag
public static void push_array_tag(Object arr_ref)
Pushes an array reference on the tag stack.- Parameters:
arr_ref
- array being accessed
-
pop_static_tag
public static void pop_static_tag(int static_num)
Pops the top of the tag stack into the tag storage for static_num.- Parameters:
static_num
- identifies the static variable being accessed
-
discard_tag
public static void discard_tag(int cnt)
Discard the tag on the top of the tag stack. Called when primitives are pushed but not used in expressions (such as when allocating arrays). (No longer used?)- Parameters:
cnt
- number of tags to discard
-
aastore
public static void aastore(Object[] arr, int index, Object val)
Execute an aastore instruction and mark the array and its index as comparable.
-
bastore
public static void bastore(byte[] arr, int index, byte val)
The JVM uses bastore for both boolean and byte data types. With the addition of StackMap verification in Java 7 we can no longer use the same runtime routine for both data types. Hence, the addition of zastore below for boolean.Execute an bastore instruction and manipulate the tags accordingly. The tag at the top of stack is stored into the tag storage for the array.
-
zastore
public static void zastore(boolean[] arr, int index, boolean val)
-
castore
public static void castore(char[] arr, int index, char val)
Execute an castore instruction and manipulate the tags accordingly. The tag at the top of stack is stored into the tag storage for the array.
-
dastore
public static void dastore(double[] arr, int index, double val)
Execute an dastore instruction and manipulate the tags accordingly. The tag at the top of stack is stored into the tag storage for the array.
-
fastore
public static void fastore(float[] arr, int index, float val)
Execute an fastore instruction and manipulate the tags accordingly. The tag at the top of stack is stored into the tag storage for the array.
-
iastore
public static void iastore(int[] arr, int index, int val)
Execute an iastore instruction and manipulate the tags accordingly. The tag at the top of stack is stored into the tag storage for the array.
-
lastore
public static void lastore(long[] arr, int index, long val)
Execute an lastore instruction and manipulate the tags accordingly. The tag at the top of stack is stored into the tag storage for the array.
-
sastore
public static void sastore(short[] arr, int index, short val)
Execute an sastore instruction and manipulate the tags accordingly. The tag at the top of stack is stored into the tag storage for the array.
-
multianewarray2
public static void multianewarray2(int count1, int count2, Object[] arr)
Make the count arguments to multianewarray comparable to the corresponding array indices. count1 is made comparable to the index of the given array (arr), and count2 is made comparable to the index of each array that is an element of arr.- Parameters:
count1
- number items in 1st dimension (unused, associated tag value is on tag stack)count2
- number items in 2nd dimension (unused, associated tag value is on tag stack)arr
- the new array
-
enter
public static void enter(Object[] tag_frame, @Nullable Object obj, int mi_index, Object[] args)
Called when a user method is entered. Any daikon variables whose current values are comparable are marked as comparable.- Parameters:
tag_frame
- tag_frame containing the tags for the primitive arguments of this methodobj
- value of 'this', or null if the method is staticmi_index
- index into the list of all methods (methods)args
- array of the arguments to the method
-
exit
public static void exit(Object[] tag_frame, @Nullable Object obj, int mi_index, Object[] args, Object ret_val, int exit_line_number)
Called when a user method exits. Any daikon variables whose current values are comparable are marked as comparable.- Parameters:
tag_frame
- tag_frame containing the tags for the primitive arguments of this methodobj
- value of 'this', or null if the method is staticmi_index
- index into the list of all methods (methods)args
- array of the arguments to the methodret_val
- value returned by the method, or null if the method is a constructor or voidexit_line_number
- the source line number of this exit point
-
process_all_vars
public static void process_all_vars(MethodInfo mi, RootInfo root, Object[] tag_frame, Object obj, Object[] args, Object ret_val)
Process all of the daikon variables in the tree starting at root. If the values referenced by those variables are comparable mark the variables as comparable.
-
get_object_field
public static Object get_object_field(Field f, Object obj)
Gets the object in field f in object obj. Exceptions are turned into Errors.- Parameters:
f
- which field to returnobj
- the object that contains the field- Returns:
- the specified object
-
printAllComparable
public static void printAllComparable(PrintWriter pw)
Dumps out comparability information for all classes that were processed.- Parameters:
pw
- PrintWriter to write on
-
traceAllComparable
public static void traceAllComparable(PrintWriter pw)
Dumps out comparability trace information for all classes that were processed.- Parameters:
pw
- PrintWriter to write on
-
printHeaderInfo
public static void printHeaderInfo(PrintWriter pw, String className)
Prints header information to the decls file. Should be called once before emitting any other declarations.- Parameters:
pw
- where to write outputclassName
- name of the top-level class (used only for printing comments)
-
printDeclFile
public static void printDeclFile(PrintWriter pw)
Dumps out .decl file information for all classes that were processed.- Parameters:
pw
- where to write output
-
decl_stats
public static void decl_stats()
Prints statistics about the number of decls to stdout.
-
printClassDecl
public static void printClassDecl(PrintWriter pw, ClassInfo ci)
Calculates and prints the declarations for the specified class.- Parameters:
pw
- where to produce outputci
- the class to write
-
printMethod
public static List<DCRuntime.DVSet> printMethod(PrintWriter pw, MethodInfo mi)
Prints a decl ENTER/EXIT records with comparability. Returns the list of comparabile DVSets for the exit.- Parameters:
pw
- where to produce outputmi
- the class to output- Returns:
- the list of comparabile DVSets for the exit
-
getComparability
public String getComparability(DaikonVariableInfo dv, DeclReader.DeclPpt compare_ppt)
Calculates a comparability value.- Specified by:
getComparability
in interfaceComparabilityProvider
- Parameters:
dv
- variable to calculate comparability forcompare_ppt
- (not used)- Returns:
- string containing comparability value
-
printComparable
public static void printComparable(PrintWriter pw, MethodInfo mi)
Prints comparability information for the enter and exit points of the specified method. By default, outputs tofoo.txt-cset
.- Parameters:
pw
- where to produce outputmi
- the method whose comparability to output
-
printComparableTraced
public static void printComparableTraced(PrintWriter pw, MethodInfo mi)
Dumps out comparability trace information for a single method.- Parameters:
pw
- where to write outputmi
- the method to process
-
push_field_tag
public static void push_field_tag(Object obj, int field_num)
Pushes the tag associated with field_num in obj on the tag stack. A tag value must have been previously stored for this field.- Parameters:
obj
- where to store tagfield_num
- which field within obj to store into
-
push_field_tag_null_ok
public static void push_field_tag_null_ok(Object obj, int field_num)
Pushes the tag associated with field_num in obj on the tag stack. If tag storage for this object has not been previously allocated it is allocated now and a tag is allocated for this field. This should only be called for objects whose fields can be read without having been previously written (in Java).- Parameters:
obj
- where to store tagfield_num
- which field within obj to store into
-
pop_field_tag
public static void pop_field_tag(Object obj, int field_num)
Pops the tag from the top of the tag stack and stores it in the tag storage for the specified field of the specified object. If tag storage was not previously allocated, it is allocated now.- Parameters:
obj
- where to store tagfield_num
- which field within obj to store into
-
num_prim_fields
public static int num_prim_fields(Class<?> clazz)
Return the number of primitive fields in clazz and all of its superclasses.
-
binary_tag_op
public static void binary_tag_op()
Handle a binary operation on the two items at the top of the tag stack. Binary operations pop the two items off of the top of the stack perform an operation and push the result back on the stack. The tags of the two items on the top of the stack must thus be merged and a representative tag pushed back on the stack.
-
cmp_op
public static void cmp_op()
Handles an i_cmpXX operation. This opcode compares the two integers on the top of the stack and jumps accordingly. Thus the two tags on the top of the stack are popped from the tag stack and merged. Very similar to binary_tag_op except that nothing is pushed back on the tag stack.
-
dup
public static void dup()
Handles a dup opcode on a primitive.
-
dup_x1
public static void dup_x1()
Handles a dup_x1 opcode on a primitive.
-
dup_x2
public static void dup_x2()
Handles a dup_x2 opcode on a primitive. Currently only support category 1 computational types.
-
dup2
public static void dup2()
Handles a dup2 opcode on a primitive.
-
dup2_x1
public static void dup2_x1()
Handles a dup2_x1 opcode on a primitive.
-
dup2_x2
public static void dup2_x2()
Handles a dup2_x2 opcode on a primitive.
-
swap
public static void swap()
swaps the two elements on the top of the tag stack
-
primitive_array_load
public static void primitive_array_load(Object arr_ref, int index)
Handles the various primitive (int, double, etc) array load instructions. The array and its index are made comparable. The tag for the index is removed from the tag stack and the tag for the array element is pushed on the stack.- Parameters:
arr_ref
- array referenceindex
- index into array
-
primitive_array_load_null_ok
public static void primitive_array_load_null_ok(Object arr_ref, int index)
Handles the various primitive (int, double, etc) array load instructions. The array and its index are made comparable. The tag for the index is removed from the tag stack and the tag for the array element is pushed on the stack. Unlike primitive_array_load(), this method handles array elements whose tags have not previously been set. This can happen when the JVM sets an array element directly and there is no corresponding java code that can set the tag.- Parameters:
arr_ref
- array referenceindex
- index into array
-
ref_array_load
public static void ref_array_load(Object arr_ref, int index)
Handles the aaload instruction. The arry and its index are made comparable. The tag for the index is removed from the tag stack.- Parameters:
arr_ref
- array referenceindex
- index into array
-
push_const
public static void push_const()
Allocate a new tag for the constant and push it on the tag stack. Note that this allocates a new tag each time the constant is pushed. If the same code is executed multiple time (eg, in a loop), and different values interact with the constant each time, those values will not end up comparable to each other.
-
set_class_initialized
public static void set_class_initialized(String classname)
Marks the specified class as initialized. We don't look at static variables in classes until they are initialized.- Parameters:
classname
- class to mark initialized
-
is_class_initialized
@Pure public static boolean is_class_initialized(Class<?> clazz)
Returns whether or not the specified class is initialized.- Parameters:
clazz
- class to check- Returns:
- true if clazz has been initialized
-
tag_field_name
public static String tag_field_name(String field_name)
Returns the name of the tag field that corresponds to the specified field.- Parameters:
field_name
- field name- Returns:
- tag field name
-
clean_decl_name
public static String clean_decl_name(String decl_name)
Removes DCompMarker from the signature.
-
-