FuncNode::FuncNode(ModelHistory * history) :
history(history),
- predicate_tree_initialized(false),
exit_count(0),
func_inst_map(),
inst_list(),
entry_insts(),
- predicate_tree_position()
+ predicate_tree_position(),
+ edge_table(32),
+ out_edges(),
+ in_edges()
{
predicate_tree_entry = new Predicate(NULL, true);
predicate_tree_entry->add_predicate_expr(NOPREDICATE, NULL, true);
return (*thrd_inst_act_map)[thread_id];
}
+/* Add FuncNodes that this node may follow */
+void FuncNode::add_out_edge(FuncNode * other)
+{
+ if ( !edge_table.contains(other) ) {
+ edge_table.put(other, OUT_EDGE);
+ out_edges.push_back(other);
+ return;
+ }
+
+ edge_type_t edge = edge_table.get(other);
+ if (edge == IN_EDGE) {
+ edge_table.put(other, BI_EDGE);
+ out_edges.push_back(other);
+ }
+}
+
+/* Add FuncNodes that come before this node */
+void FuncNode::add_in_edge(FuncNode * other)
+{
+ if ( !edge_table.contains(other) ) {
+ edge_table.put(other, IN_EDGE);
+ in_edges.push_back(other);
+ return;
+ }
+
+ edge_type_t edge = edge_table.get(other);
+ if (edge == OUT_EDGE) {
+ edge_table.put(other, BI_EDGE);
+ in_edges.push_back(other);
+ }
+}
+
+
void FuncNode::print_predicate_tree()
{
model_print("digraph function_%s {\n", func_name);
typedef ModelList<FuncInst *> func_inst_list_mt;
typedef HashTable<FuncInst *, ModelAction *, uintptr_t, 0> inst_act_map_t;
+typedef enum edge_type {
+ IN_EDGE, OUT_EDGE, BI_EDGE
+} edge_type_t;
+
class FuncNode {
public:
FuncNode(ModelHistory * history);
void update_inst_act_map(thread_id_t tid, ModelAction * read_act);
inst_act_map_t * get_inst_act_map(thread_id_t tid);
+ void add_out_edge(FuncNode * other);
+ void add_in_edge(FuncNode * other);
+
void print_predicate_tree();
void print_val_loc_map();
void print_last_read(thread_id_t tid);
uint32_t func_id;
const char * func_name;
ModelHistory * history;
- bool predicate_tree_initialized;
Predicate * predicate_tree_entry; // a dummy node whose children are the real entries
uint32_t exit_count;
/* A run-time map from FuncInst to ModelAction for each thread; needed by NewFuzzer */
SnapVector<inst_act_map_t *> * thrd_inst_act_map;
+
+ /* Store the relation between this FuncNode and other FuncNodes */
+ HashTable<FuncNode *, edge_type_t, uintptr_t, 0, model_malloc, model_calloc, model_free> edge_table;
+ ModelList<FuncNode *> out_edges; /* FuncNodes that follow this node */
+ ModelList<FuncNode *> in_edges; /* FuncNodes that comes before this node */
};
#endif /* __FUNCNODE_H__ */
}
SnapList<action_list_t *> * func_act_lists = (*thrd_func_act_lists)[id];
+ func_act_lists->push_back( new action_list_t() );
+ uint32_t last_func_id = (*thrd_func_list)[id].back();
(*thrd_func_list)[id].push_back(func_id);
- func_act_lists->push_back( new action_list_t() );
if ( func_nodes.size() <= func_id )
resize_func_nodes( func_id + 1 );
FuncNode * func_node = func_nodes[func_id];
func_node->init_predicate_tree_position(tid);
func_node->init_inst_act_map(tid);
+
+ /* Add edges between FuncNodes */
+ if (last_func_id != 0) {
+ FuncNode * last_func_node = func_nodes[last_func_id];
+ add_edges_between(last_func_node, func_node);
+ }
}
/* @param func_id a non-zero value */
if (act->is_read()) {
func_node->update_inst_act_map(tid, act);
+ // Update predicate tree position
Fuzzer * fuzzer = model->get_execution()->getFuzzer();
Predicate * selected_branch = fuzzer->get_selected_child_branch(tid);
func_node->set_predicate_tree_position(tid, selected_branch);
}
}
+/* Add edges between FuncNodes */
+void ModelHistory::add_edges_between(FuncNode * prev_node, FuncNode * next_node)
+{
+ prev_node->add_out_edge(next_node);
+ next_node->add_in_edge(prev_node);
+}
+
void ModelHistory::print_write()
{
}
/* Map a location to FuncNodes that may read from it */
HashTable<void *, SnapList<FuncNode *> *, uintptr_t, 4> loc_func_nodes_map;
+
+ void add_edges_between(FuncNode * prev_node, FuncNode * next_node);
};
#endif /* __HISTORY_H__ */