Updates.cpp

Go to the documentation of this file.
00001 //===-- Updates.cpp -------------------------------------------------------===//
00002 //
00003 //                     The KLEE Symbolic Virtual Machine
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "klee/Expr.h"
00011 
00012 #include <cassert>
00013 
00014 using namespace klee;
00015 
00017 
00018 UpdateNode::UpdateNode(const UpdateNode *_next, 
00019                        const ref<Expr> &_index, 
00020                        const ref<Expr> &_value) 
00021   : refCount(0),
00022     stpArray(0),
00023     next(_next),
00024     index(_index),
00025     value(_value) {
00026   assert(_value->getWidth() == Expr::Int8 && 
00027          "Update value should be 8-bit wide.");
00028   computeHash();
00029   if (next) {
00030     ++next->refCount;
00031     size = 1 + next->size;
00032   }
00033   else size = 1;
00034 }
00035 
00036 extern "C" void vc_DeleteExpr(void*);
00037 
00038 UpdateNode::~UpdateNode() {
00039   // XXX gross
00040   if (stpArray)
00041     ::vc_DeleteExpr(stpArray);
00042 }
00043 
00044 int UpdateNode::compare(const UpdateNode &b) const {
00045   if (int i = index.compare(b.index)) 
00046     return i;
00047   return value.compare(b.value);
00048 }
00049 
00050 unsigned UpdateNode::computeHash() {
00051   hashValue = index->hash() ^ value->hash();
00052   if (next)
00053     hashValue ^= next->hash();
00054   return hashValue;
00055 }
00056 
00058 
00059 UpdateList::UpdateList(const Array *_root, bool _isRooted,
00060                        const UpdateNode *_head)
00061   : root(_root),
00062     head(_head),
00063     isRooted(_isRooted) {
00064   if (head) ++head->refCount;
00065 }
00066 
00067 UpdateList::UpdateList(const UpdateList &b)
00068   : root(b.root),
00069     head(b.head),
00070     isRooted(b.isRooted) {
00071   if (head) ++head->refCount;
00072 }
00073 
00074 UpdateList::~UpdateList() {
00075   // We need to be careful and avoid recursion here. We do this in
00076   // cooperation with the private dtor of UpdateNode which does not
00077   // recursively free its tail.
00078   while (head && --head->refCount==0) {
00079     const UpdateNode *n = head->next;
00080     delete head;
00081     head = n;
00082   }
00083 }
00084 
00085 UpdateList &UpdateList::operator=(const UpdateList &b) {
00086   if (b.head) ++b.head->refCount;
00087   if (head && --head->refCount==0) delete head;
00088   root = b.root;
00089   head = b.head;
00090   isRooted = b.isRooted;
00091   return *this;
00092 }
00093 
00094 void UpdateList::extend(const ref<Expr> &index, const ref<Expr> &value) {
00095   if (head) --head->refCount;
00096   head = new UpdateNode(head, index, value);
00097   ++head->refCount;
00098 }
00099 
00100 int UpdateList::compare(const UpdateList &b) const {
00101   // use object id to increase determinism
00102   if (root->id != b.root->id) 
00103     return root->id < b.root->id ? -1 : 1;
00104   
00105   if (getSize() < b.getSize()) return -1;
00106   else if (getSize() > b.getSize()) return 1;    
00107 
00108   // XXX build comparison into update, make fast
00109   const UpdateNode *an=head, *bn=b.head;
00110   for (; an && bn; an=an->next,bn=bn->next) {
00111     if (an==bn) { // exploit shared list structure
00112       return 0;
00113     } else {
00114       if (int res = an->compare(*bn))
00115         return res;
00116     }
00117   }
00118   assert(!an && !bn);
00119   return 0;
00120 }
00121 
00122 unsigned UpdateList::hash() const {
00123   unsigned res = root->id * Expr::MAGIC_HASH_CONSTANT;
00124   if (head)
00125     res ^= head->hash();
00126   return res;
00127 }

Generated on Fri Jun 5 03:31:32 2009 for klee by  doxygen 1.5.8