Merge pull request #5882 from Icinga/feature/avoid-allocations

Avoid unnecessary allocations
This commit is contained in:
Michael Friedrich 2017-12-18 17:11:27 +01:00 committed by GitHub
commit 4fa42a81f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 81 additions and 72 deletions

View File

@ -38,14 +38,13 @@ Function::Function(const String& name, const Callback& function, const std::vect
Value Function::Invoke(const std::vector<Value>& arguments) Value Function::Invoke(const std::vector<Value>& arguments)
{ {
ScriptFrame frame; ScriptFrame frame(false);
return m_Callback(arguments); return m_Callback(arguments);
} }
Value Function::InvokeThis(const Value& otherThis, const std::vector<Value>& arguments) Value Function::InvokeThis(const Value& otherThis, const std::vector<Value>& arguments)
{ {
ScriptFrame frame; ScriptFrame frame(otherThis, false);
frame.Self = otherThis;
return m_Callback(arguments); return m_Callback(arguments);
} }

View File

@ -40,14 +40,14 @@ INITIALIZE_ONCE_WITH_PRIORITY([]() {
ScriptFrame::AddImport(deprecatedNS); ScriptFrame::AddImport(deprecatedNS);
}, 50); }, 50);
ScriptFrame::ScriptFrame(void) ScriptFrame::ScriptFrame(bool allocLocals)
: Locals(new Dictionary()), Self(ScriptGlobal::GetGlobals()), Sandboxed(false), Depth(0) : Locals(allocLocals ? new Dictionary() : nullptr), Self(ScriptGlobal::GetGlobals()), Sandboxed(false), Depth(0)
{ {
InitializeFrame(); InitializeFrame();
} }
ScriptFrame::ScriptFrame(const Value& self) ScriptFrame::ScriptFrame(const Value& self, bool allocLocals)
: Locals(new Dictionary()), Self(self), Sandboxed(false), Depth(0) : Locals(allocLocals ? new Dictionary() : nullptr), Self(self), Sandboxed(false), Depth(0)
{ {
InitializeFrame(); InitializeFrame();
} }

View File

@ -36,8 +36,8 @@ struct I2_BASE_API ScriptFrame
bool Sandboxed; bool Sandboxed;
int Depth; int Depth;
ScriptFrame(void); ScriptFrame(bool allocLocals = true);
ScriptFrame(const Value& self); ScriptFrame(const Value& self, bool allocLocals = true);
~ScriptFrame(void); ~ScriptFrame(void);
void IncreaseStackDepth(void); void IncreaseStackDepth(void);

View File

@ -110,10 +110,8 @@ bool ScriptUtils::Regex(const std::vector<Value>& args)
if (args.size() < 2) if (args.size() < 2)
BOOST_THROW_EXCEPTION(std::invalid_argument("Regular expression and text must be specified.")); BOOST_THROW_EXCEPTION(std::invalid_argument("Regular expression and text must be specified."));
Array::Ptr texts = new Array();
String pattern = args[0]; String pattern = args[0];
Value argTexts = args[1]; const Value& argTexts = args[1];
MatchType mode; MatchType mode;
if (args.size() > 2) if (args.size() > 2)
@ -121,34 +119,40 @@ bool ScriptUtils::Regex(const std::vector<Value>& args)
else else
mode = MatchAll; mode = MatchAll;
if (argTexts.IsObjectType<Array>()) boost::regex expr(pattern.GetData());
Array::Ptr texts;
if (argTexts.IsObject())
texts = argTexts; texts = argTexts;
else {
texts = new Array();
texts->Add(argTexts);
}
if (texts->GetLength() == 0) if (texts) {
return false; ObjectLock olock(texts);
ObjectLock olock(texts); if (texts->GetLength() == 0)
for (const String& text : texts) { return false;
bool res = false;
try { for (const String& text : texts) {
boost::regex expr(pattern.GetData()); bool res = false;
boost::smatch what; try {
res = boost::regex_search(text.GetData(), what, expr); boost::smatch what;
} catch (boost::exception&) { res = boost::regex_search(text.GetData(), what, expr);
res = false; /* exception means something went terribly wrong */ } catch (boost::exception&) {
res = false; /* exception means something went terribly wrong */
}
if (mode == MatchAny && res)
return true;
else if (mode == MatchAll && !res)
return false;
} }
if (mode == MatchAny && res) return true;
return true; } else {
else if (mode == MatchAll && !res) String text = argTexts;
return false; boost::smatch what;
return boost::regex_search(text.GetData(), what, expr);
} }
return mode == MatchAll;
} }
bool ScriptUtils::Match(const std::vector<Value>& args) bool ScriptUtils::Match(const std::vector<Value>& args)
@ -156,10 +160,8 @@ bool ScriptUtils::Match(const std::vector<Value>& args)
if (args.size() < 2) if (args.size() < 2)
BOOST_THROW_EXCEPTION(std::invalid_argument("Pattern and text must be specified.")); BOOST_THROW_EXCEPTION(std::invalid_argument("Pattern and text must be specified."));
Array::Ptr texts = new Array();
String pattern = args[0]; String pattern = args[0];
Value argTexts = args[1]; const Value& argTexts = args[1];
MatchType mode; MatchType mode;
if (args.size() > 2) if (args.size() > 2)
@ -167,27 +169,31 @@ bool ScriptUtils::Match(const std::vector<Value>& args)
else else
mode = MatchAll; mode = MatchAll;
if (argTexts.IsObjectType<Array>()) Array::Ptr texts;
if (argTexts.IsObject())
texts = argTexts; texts = argTexts;
else {
texts = new Array();
texts->Add(argTexts);
}
if (texts->GetLength() == 0) if (texts) {
return false; ObjectLock olock(texts);
ObjectLock olock(texts); if (texts->GetLength() == 0)
for (const String& text : texts) {
bool res = Utility::Match(pattern, text);
if (mode == MatchAny && res)
return true;
else if (mode == MatchAll && !res)
return false; return false;
}
return mode == MatchAll; for (const String& text : texts) {
bool res = Utility::Match(pattern, text);
if (mode == MatchAny && res)
return true;
else if (mode == MatchAll && !res)
return false;
}
return true;
} else {
String text = argTexts;
return Utility::Match(pattern, argTexts);
}
} }
bool ScriptUtils::CidrMatch(const std::vector<Value>& args) bool ScriptUtils::CidrMatch(const std::vector<Value>& args)
@ -195,10 +201,8 @@ bool ScriptUtils::CidrMatch(const std::vector<Value>& args)
if (args.size() < 2) if (args.size() < 2)
BOOST_THROW_EXCEPTION(std::invalid_argument("CIDR and IP address must be specified.")); BOOST_THROW_EXCEPTION(std::invalid_argument("CIDR and IP address must be specified."));
Array::Ptr ips = new Array();
String pattern = args[0]; String pattern = args[0];
Value argIps = args[1]; const Value& argIps = args[1];
MatchType mode; MatchType mode;
if (args.size() > 2) if (args.size() > 2)
@ -206,27 +210,31 @@ bool ScriptUtils::CidrMatch(const std::vector<Value>& args)
else else
mode = MatchAll; mode = MatchAll;
if (argIps.IsObjectType<Array>()) Array::Ptr ips;
if (argIps.IsObject())
ips = argIps; ips = argIps;
else {
ips = new Array();
ips->Add(argIps);
}
if (ips->GetLength() == 0) if (ips) {
return false; ObjectLock olock(ips);
ObjectLock olock(ips); if (ips->GetLength() == 0)
for (const String& ip : ips) {
bool res = Utility::CidrMatch(pattern, ip);
if (mode == MatchAny && res)
return true;
else if (mode == MatchAll && !res)
return false; return false;
}
return mode == MatchAll; for (const String& ip : ips) {
bool res = Utility::CidrMatch(pattern, ip);
if (mode == MatchAny && res)
return true;
else if (mode == MatchAll && !res)
return false;
}
return true;
} else {
String ip = argIps;
return Utility::CidrMatch(pattern, ip);
}
} }
double ScriptUtils::Len(const Value& value) double ScriptUtils::Len(const Value& value)

View File

@ -119,6 +119,8 @@ public:
ScriptFrame *frame = ScriptFrame::GetCurrentFrame(); ScriptFrame *frame = ScriptFrame::GetCurrentFrame();
frame->Locals = new Dictionary();
if (evaluatedClosedVars) if (evaluatedClosedVars)
evaluatedClosedVars->CopyTo(frame->Locals); evaluatedClosedVars->CopyTo(frame->Locals);