summaryrefslogtreecommitdiff
path: root/cpp/src/slice2cpp
diff options
context:
space:
mode:
authorMichi Henning <michi@zeroc.com>2003-05-19 03:17:25 +0000
committerMichi Henning <michi@zeroc.com>2003-05-19 03:17:25 +0000
commit909089235a53d8650d4cc95fe31a9a839403f328 (patch)
tree771e5ad90afc10b3e5e4f41c52594f4abd55e1c0 /cpp/src/slice2cpp
parentUse communicator->getLogger() instead of caching the logger to eventually (diff)
downloadice-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/slice2cpp')
-rw-r--r--cpp/src/slice2cpp/Gen.cpp54
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 "