summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2007-05-19 02:59:05 +0000
committerJohn Wiegley <johnw@newartisans.com>2008-04-13 03:38:53 -0400
commit565d8eeb876e69a38076033cdd09c89e8f10940b (patch)
tree4f90e66bde53711e8d0c741592a0c717dab6baea
parent7ddf6baf2c741f631dbbb4491d3cc21c648f80bf (diff)
downloadfork-ledger-565d8eeb876e69a38076033cdd09c89e8f10940b.tar.gz
fork-ledger-565d8eeb876e69a38076033cdd09c89e8f10940b.tar.bz2
fork-ledger-565d8eeb876e69a38076033cdd09c89e8f10940b.zip
Changed the value object to allocate its larger members.
-rw-r--r--src/value.cc42
-rw-r--r--src/value.h59
2 files changed, 73 insertions, 28 deletions
diff --git a/src/value.cc b/src/value.cc
index 88b8949e..25145695 100644
--- a/src/value.cc
+++ b/src/value.cc
@@ -44,16 +44,16 @@ void value_t::storage_t::destroy()
((amount_t *)data)->~amount_t();
break;
case BALANCE:
- ((balance_t *)data)->~balance_t();
+ checked_delete(*(balance_t **)data);
break;
case BALANCE_PAIR:
- ((balance_pair_t *)data)->~balance_pair_t();
+ checked_delete(*(balance_pair_t **)data);
break;
case STRING:
((string *)data)->~string();
break;
case SEQUENCE:
- ((sequence_t *)data)->~sequence_t();
+ checked_delete(*(sequence_t **)data);
break;
case POINTER:
((boost::any *)data)->~any();
@@ -67,6 +67,10 @@ void value_t::storage_t::destroy()
void value_t::initialize()
{
+#if 0
+ LOGGER("value.initialize");
+#endif
+
true_value = new storage_t;
true_value->type = BOOLEAN;
*(bool *) true_value->data = true;
@@ -74,6 +78,38 @@ void value_t::initialize()
false_value = new storage_t;
false_value->type = BOOLEAN;
*(bool *) false_value->data = false;
+
+ BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(bool));
+ BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(moment_t));
+ BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(long));
+ BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(amount_t));
+ BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(balance_t *));
+ BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(balance_pair_t *));
+ BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(string));
+ BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(sequence_t *));
+ BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(xml::node_t *));
+ BOOST_STATIC_ASSERT(sizeof(amount_t) >= sizeof(boost::any));
+
+#if 0
+ DEBUG_(std::setw(3) << std::right << sizeof(bool)
+ << " sizeof(bool)");
+ DEBUG_(std::setw(3) << std::right << sizeof(moment_t)
+ << " sizeof(moment_t)");
+ DEBUG_(std::setw(3) << std::right << sizeof(long)
+ << " sizeof(long)");
+ DEBUG_(std::setw(3) << std::right << sizeof(amount_t)
+ << " sizeof(amount_t)");
+ DEBUG_(std::setw(3) << std::right << sizeof(balance_t *)
+ << " sizeof(balance_t *)");
+ DEBUG_(std::setw(3) << std::right << sizeof(balance_pair_t *)
+ << " sizeof(balance_pair_t *)");
+ DEBUG_(std::setw(3) << std::right << sizeof(string)
+ << " sizeof(string)");
+ DEBUG_(std::setw(3) << std::right << sizeof(sequence_t *)
+ << " sizeof(sequence_t *)");
+ DEBUG_(std::setw(3) << std::right << sizeof(boost::any)
+ << " sizeof(boost::any)");
+#endif
}
void value_t::shutdown()
diff --git a/src/value.h b/src/value.h
index 8fa3f8c9..47db1a31 100644
--- a/src/value.h
+++ b/src/value.h
@@ -82,25 +82,16 @@ public:
private:
class storage_t
{
- char data[sizeof(balance_pair_t)];
+ char data[sizeof(amount_t)];
type_t type;
- BOOST_STATIC_ASSERT(sizeof(balance_pair_t) > sizeof(bool));
- BOOST_STATIC_ASSERT(sizeof(balance_pair_t) > sizeof(moment_t));
- BOOST_STATIC_ASSERT(sizeof(balance_pair_t) > sizeof(long));
- BOOST_STATIC_ASSERT(sizeof(balance_pair_t) > sizeof(amount_t));
- BOOST_STATIC_ASSERT(sizeof(balance_pair_t) > sizeof(balance_t));
- BOOST_STATIC_ASSERT(sizeof(balance_pair_t) > sizeof(string));
- BOOST_STATIC_ASSERT(sizeof(balance_pair_t) > sizeof(sequence_t));
- BOOST_STATIC_ASSERT(sizeof(balance_pair_t) > sizeof(xml::node_t *));
-
explicit storage_t() : type(VOID), refc(0) {
TRACE_CTOR(value_t::storage_t, "");
}
explicit storage_t(const storage_t& rhs)
: type(rhs.type), refc(0) {
TRACE_CTOR(value_t::storage_t, "");
- std::memcpy(data, rhs.data, sizeof(balance_pair_t));
+ std::memcpy(data, rhs.data, sizeof(data));
}
public: // so `checked_delete' can access it
@@ -114,7 +105,7 @@ private:
private:
storage_t& operator=(const storage_t& rhs) {
type = rhs.type;
- std::memcpy(data, rhs.data, sizeof(balance_pair_t));
+ std::memcpy(data, rhs.data, sizeof(data));
return *this;
}
@@ -244,8 +235,28 @@ public:
*/
void _dup() {
assert(storage);
- if (storage->refc > 1)
+ if (storage->refc > 1) {
storage = new storage_t(*storage.get());
+
+ // If the data referenced by storage is an allocated pointer, we
+ // need to create a new object in order to achieve duplication.
+ switch (storage->type) {
+ case BALANCE:
+ *(balance_t **) storage->data =
+ new balance_t(**(balance_t **) storage->data);
+ break;
+ case BALANCE_PAIR:
+ *(balance_pair_t **) storage->data =
+ new balance_pair_t(**(balance_pair_t **) storage->data);
+ break;
+ case SEQUENCE:
+ *(sequence_t **) storage->data =
+ new sequence_t(**(sequence_t **) storage->data);
+ break;
+ default:
+ break; // everything else has been duplicated
+ }
+ }
}
void _clear() {
if (! storage || storage->refc > 1)
@@ -254,10 +265,8 @@ public:
storage->destroy();
}
void _reset() {
- if (storage) {
- storage->destroy();
+ if (storage)
storage = intrusive_ptr<storage_t>();
- }
}
operator bool() const;
@@ -367,15 +376,15 @@ public:
balance_t& as_balance_lval() {
assert(is_balance());
_dup();
- return *(balance_t *) storage->data;
+ return **(balance_t **) storage->data;
}
const balance_t& as_balance() const {
assert(is_balance());
- return *(balance_t *) storage->data;
+ return **(balance_t **) storage->data;
}
void set_balance(const balance_t& val) {
set_type(BALANCE);
- new((balance_t *) storage->data) balance_t(val);
+ *(balance_t **) storage->data = new balance_t(val);
}
bool is_balance_pair() const {
@@ -384,15 +393,15 @@ public:
balance_pair_t& as_balance_pair_lval() {
assert(is_balance_pair());
_dup();
- return *(balance_pair_t *) storage->data;
+ return **(balance_pair_t **) storage->data;
}
const balance_pair_t& as_balance_pair() const {
assert(is_balance_pair());
- return *(balance_pair_t *) storage->data;
+ return **(balance_pair_t **) storage->data;
}
void set_balance_pair(const balance_pair_t& val) {
set_type(BALANCE_PAIR);
- new((balance_pair_t *) storage->data) balance_pair_t(val);
+ *(balance_pair_t **) storage->data = new balance_pair_t(val);
}
bool is_string() const {
@@ -418,15 +427,15 @@ public:
sequence_t& as_sequence_lval() {
assert(is_sequence());
_dup();
- return *(sequence_t *) storage->data;
+ return **(sequence_t **) storage->data;
}
const sequence_t& as_sequence() const {
assert(is_sequence());
- return *(sequence_t *) storage->data;
+ return **(sequence_t **) storage->data;
}
void set_sequence(const sequence_t& val) {
set_type(SEQUENCE);
- new((sequence_t *) storage->data) sequence_t(val);
+ *(sequence_t **) storage->data = new sequence_t(val);
}
bool is_xml_node() const {