Avoid unnecessary allocations in ScriptFrame::SetCurrentFrame

This commit is contained in:
Gunnar Beutner 2015-03-29 22:26:07 +02:00
parent a5c5569324
commit 339b8aef48
2 changed files with 33 additions and 17 deletions

View File

@ -22,39 +22,54 @@
using namespace icinga; using namespace icinga;
boost::thread_specific_ptr<ScriptFrame *> ScriptFrame::m_CurrentFrame; boost::thread_specific_ptr<std::stack<ScriptFrame *> > ScriptFrame::m_ScriptFrames;
ScriptFrame::ScriptFrame(void) ScriptFrame::ScriptFrame(void)
: Locals(new Dictionary()), Self(ScriptGlobal::GetGlobals()) : Locals(new Dictionary()), Self(ScriptGlobal::GetGlobals())
{ {
NextFrame = GetCurrentFrame(); PushFrame(this);
SetCurrentFrame(this);
} }
ScriptFrame::ScriptFrame(const Value& self) ScriptFrame::ScriptFrame(const Value& self)
: Locals(new Dictionary()), Self(self) : Locals(new Dictionary()), Self(self)
{ {
NextFrame = GetCurrentFrame(); PushFrame(this);
SetCurrentFrame(this);
} }
ScriptFrame::~ScriptFrame(void) ScriptFrame::~ScriptFrame(void)
{ {
ASSERT(GetCurrentFrame() == this); ScriptFrame *frame = PopFrame();
SetCurrentFrame(NextFrame); ASSERT(frame == this);
} }
ScriptFrame *ScriptFrame::GetCurrentFrame(void) ScriptFrame *ScriptFrame::GetCurrentFrame(void)
{ {
ScriptFrame **pframe = m_CurrentFrame.get(); std::stack<ScriptFrame *> *frames = m_ScriptFrames.get();
if (pframe) ASSERT(!frames->empty());
return *pframe; return frames->top();
else
return NULL;
} }
void ScriptFrame::SetCurrentFrame(ScriptFrame *frame) ScriptFrame *ScriptFrame::PopFrame(void)
{ {
m_CurrentFrame.reset(new ScriptFrame *(frame)); std::stack<ScriptFrame *> *frames = m_ScriptFrames.get();
ASSERT(!frames->empty());
ScriptFrame *frame = frames->top();
frames->pop();
return frame;
}
void ScriptFrame::PushFrame(ScriptFrame *frame)
{
std::stack<ScriptFrame *> *frames = m_ScriptFrames.get();
if (!frames) {
frames = new std::stack<ScriptFrame *>();
m_ScriptFrames.reset(frames);
}
frames->push(frame);
} }

View File

@ -23,6 +23,7 @@
#include "config/i2-config.hpp" #include "config/i2-config.hpp"
#include "base/dictionary.hpp" #include "base/dictionary.hpp"
#include <boost/thread/tss.hpp> #include <boost/thread/tss.hpp>
#include <stack>
namespace icinga namespace icinga
{ {
@ -31,7 +32,6 @@ struct I2_BASE_API ScriptFrame
{ {
Dictionary::Ptr Locals; Dictionary::Ptr Locals;
Value Self; Value Self;
ScriptFrame *NextFrame;
ScriptFrame(void); ScriptFrame(void);
ScriptFrame(const Value& self); ScriptFrame(const Value& self);
@ -40,9 +40,10 @@ struct I2_BASE_API ScriptFrame
static ScriptFrame *GetCurrentFrame(void); static ScriptFrame *GetCurrentFrame(void);
private: private:
static boost::thread_specific_ptr<ScriptFrame *> m_CurrentFrame; static boost::thread_specific_ptr<std::stack<ScriptFrame *> > m_ScriptFrames;
static void SetCurrentFrame(ScriptFrame *frame); inline static void PushFrame(ScriptFrame *frame);
inline static ScriptFrame *PopFrame(void);
}; };
} }