mirror of https://gitee.com/bigwinds/arangodb
Fix memory leak, AqlValues must be destroyed explicitly.
This commit is contained in:
parent
fb9481c208
commit
6f22f5529a
|
@ -110,7 +110,21 @@ void AqlItemBlock::shrink (size_t nrItems) {
|
|||
// erase all stored values in the region that we freed
|
||||
for (size_t i = nrItems; i < _nrItems; ++i) {
|
||||
for (RegisterId j = 0; j < _nrRegs; ++j) {
|
||||
eraseValue(i, j);
|
||||
AqlValue& a(_data[_nrRegs * i + j]);
|
||||
if (! a.isEmpty()) {
|
||||
auto it = _valueCount.find(a);
|
||||
if (it != _valueCount.end()) {
|
||||
if (--it->second == 0) {
|
||||
a.destroy();
|
||||
try {
|
||||
_valueCount.erase(it);
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
}
|
||||
}
|
||||
a.erase();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,13 +145,11 @@ void AqlItemBlock::clearRegisters (std::unordered_set<RegisterId>& toClear) {
|
|||
auto it = _valueCount.find(a);
|
||||
if (it != _valueCount.end()) {
|
||||
if (--it->second == 0) {
|
||||
a.destroy();
|
||||
try {
|
||||
_valueCount.erase(it);
|
||||
a.destroy();
|
||||
}
|
||||
catch (...) {
|
||||
it->second++;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,8 +130,6 @@ namespace triagens {
|
|||
_valueCount.erase(it);
|
||||
}
|
||||
catch (...) {
|
||||
it->second++;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,7 +184,8 @@ void Expression::analyzeExpression () {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute an expression of type SIMPLE
|
||||
/// @brief execute an expression of type SIMPLE, the convention is that
|
||||
/// the resulting AqlValue will be destroyed outside eventually
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue Expression::executeSimpleExpression (AstNode const* node,
|
||||
|
@ -207,6 +208,7 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node,
|
|||
AqlValue result = executeSimpleExpression(member, &myCollection, trx, docColls, argv, startPos, vars, regs);
|
||||
|
||||
auto j = result.extractArrayMember(trx, myCollection, name);
|
||||
result.destroy();
|
||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, j.steal()));
|
||||
}
|
||||
|
||||
|
@ -228,6 +230,7 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node,
|
|||
if (result.isList()) {
|
||||
if (index->isNumericValue()) {
|
||||
auto j = result.extractListMember(trx, myCollection, index->getIntValue());
|
||||
result.destroy();
|
||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, j.steal()));
|
||||
}
|
||||
else if (index->isStringValue()) {
|
||||
|
@ -238,6 +241,7 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node,
|
|||
// stoll() might throw an exception if the string is not a number
|
||||
int64_t position = static_cast<int64_t>(std::stoll(p));
|
||||
auto j = result.extractListMember(trx, myCollection, position);
|
||||
result.destroy();
|
||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, j.steal()));
|
||||
}
|
||||
catch (...) {
|
||||
|
@ -250,6 +254,7 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node,
|
|||
if (index->isNumericValue()) {
|
||||
std::string const indexString = std::to_string(index->getIntValue());
|
||||
auto j = result.extractArrayMember(trx, myCollection, indexString.c_str());
|
||||
result.destroy();
|
||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, j.steal()));
|
||||
}
|
||||
else if (index->isStringValue()) {
|
||||
|
@ -257,10 +262,12 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node,
|
|||
TRI_ASSERT(p != nullptr);
|
||||
|
||||
auto j = result.extractArrayMember(trx, myCollection, p);
|
||||
result.destroy();
|
||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, j.steal()));
|
||||
}
|
||||
// fall-through to returning null
|
||||
}
|
||||
result.destroy();
|
||||
|
||||
return AqlValue(new Json(Json::Null));
|
||||
}
|
||||
|
@ -276,6 +283,7 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node,
|
|||
|
||||
AqlValue result = executeSimpleExpression(member, &myCollection, trx, docColls, argv, startPos, vars, regs);
|
||||
list->add(result.toJson(trx, myCollection));
|
||||
result.destroy();
|
||||
}
|
||||
return AqlValue(list);
|
||||
}
|
||||
|
@ -300,6 +308,7 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node,
|
|||
|
||||
AqlValue result = executeSimpleExpression(member, &myCollection, trx, docColls, argv, startPos, vars, regs);
|
||||
resultArray->set(key, result.toJson(trx, myCollection));
|
||||
result.destroy();
|
||||
}
|
||||
return AqlValue(resultArray);
|
||||
}
|
||||
|
@ -344,7 +353,9 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node,
|
|||
auto member = node->getMember(0);
|
||||
AqlValue result = executeSimpleExpression(member, &myCollection, trx, docColls, argv, startPos, vars, regs);
|
||||
|
||||
return func->implementation(trx, myCollection, result);
|
||||
auto res2 = func->implementation(trx, myCollection, result);
|
||||
result.destroy();
|
||||
return res2;
|
||||
}
|
||||
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unhandled type in simple expression");
|
||||
|
|
Loading…
Reference in New Issue