diff options
author | Michi Henning <michi@zeroc.com> | 2003-05-19 03:17:25 +0000 |
---|---|---|
committer | Michi Henning <michi@zeroc.com> | 2003-05-19 03:17:25 +0000 |
commit | 909089235a53d8650d4cc95fe31a9a839403f328 (patch) | |
tree | 771e5ad90afc10b3e5e4f41c52594f4abd55e1c0 /cpp/src | |
parent | Use communicator->getLogger() instead of caching the logger to eventually (diff) | |
download | ice-909089235a53d8650d4cc95fe31a9a839403f328.tar.bz2 ice-909089235a53d8650d4cc95fe31a9a839403f328.tar.xz ice-909089235a53d8650d4cc95fe31a9a839403f328.zip |
Fixed bug in unmarshalling code for sequences: the code has to make sure
that the allocated vector cannot move in memory during unmarshaling not
only for sequence elements that are classes, but also for sequence
elements that (recursively) contain class members.
The code now unconditionally preallocates the vector, regardless of the
element type of the sequence.
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/slice2cpp/Gen.cpp | 54 |
1 files changed, 16 insertions, 38 deletions
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp index f5f2b8d0510..74f0fcd42b7 100644 --- a/cpp/src/slice2cpp/Gen.cpp +++ b/cpp/src/slice2cpp/Gen.cpp @@ -717,26 +717,17 @@ Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p) // be checked whether sz is a reasonable value. // // Michi: I don't think it matters -- if the size is unreasonable, we just fall over after having - // unmarshaled a whole lot of stuff instead of falling over straight away. + // unmarshaled a whole lot of stuff instead of falling over straight away. I need to preallocate + // space for the entire sequence up-front because, otherwise, resizing the sequence may move it in + // memory and cause the wrong locations to be patched for classes. Also, doing a single large allocation + // up-front will be faster the repeatedly growing the vector. // - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(type)) - { - C << nl << "v.resize(sz);"; - C << nl << "for(int i = 0; i < sz; ++i)"; - C << sb; - writeMarshalUnmarshalCode(C, type, "v[i]", false); - C << eb; - C << eb; - } - else - { - C << nl << "while(sz--)"; - C << sb; - C << nl << "v.resize(v.size() + 1);"; - writeMarshalUnmarshalCode(C, type, "v.back()", false); - C << eb; - C << eb; - } + C << nl << "v.resize(sz);"; + C << nl << "for(int i = 0; i < sz; ++i)"; + C << sb; + writeMarshalUnmarshalCode(C, type, "v[i]", false); + C << eb; + C << eb; C << sp << nl << "void" << nl << scope.substr(2) << "ice_marshal(const ::std::string& __name, const ::Ice::StreamPtr& __os, const " @@ -763,25 +754,12 @@ Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p) // Michi: I don't think it matters -- if the size is unreasonable, we just fall over after having // unmarshaled a whole lot of stuff instead of falling over straight away. // - if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(type)) - { - C << nl << "v.resize(sz);"; - C << nl << "for(int i = 0; i < sz; ++i)"; - C << sb; - writeGenericMarshalUnmarshalCode(C, type, "v[i]", false); - C << eb; - C << eb; - } - else - { - C << nl << "while(sz--)"; - C << sb; - C << nl << "v.resize(v.size() + 1);"; - writeGenericMarshalUnmarshalCode(C, type, "v.back()", false, "\"e\""); - C << eb; - C << nl << "__is->endReadSequence();"; - C << eb; - } + C << nl << "v.resize(sz);"; + C << nl << "for(int i = 0; i < sz; ++i)"; + C << sb; + writeGenericMarshalUnmarshalCode(C, type, "v[i]", false); + C << eb; + C << eb; C << sp << nl << "void" << nl << scope.substr(2) << name << "Helper::" << "ice_marshal(const ::std::string& __name, const ::Ice::StreamPtr& __os, const " |