diff options
author | John Wiegley <johnw@newartisans.com> | 2007-05-19 02:59:05 +0000 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2008-04-13 03:38:53 -0400 |
commit | 565d8eeb876e69a38076033cdd09c89e8f10940b (patch) | |
tree | 4f90e66bde53711e8d0c741592a0c717dab6baea | |
parent | 7ddf6baf2c741f631dbbb4491d3cc21c648f80bf (diff) | |
download | fork-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.cc | 42 | ||||
-rw-r--r-- | src/value.h | 59 |
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 { |