]> granicus.if.org Git - icinga2/commitdiff
Avoid unnecessary allocations in ScriptFrame::SetCurrentFrame
authorGunnar Beutner <gunnar@beutner.name>
Sun, 29 Mar 2015 20:26:07 +0000 (22:26 +0200)
committerGunnar Beutner <gunnar@beutner.name>
Sun, 29 Mar 2015 20:26:07 +0000 (22:26 +0200)
lib/base/scriptframe.cpp
lib/base/scriptframe.hpp

index 8e976c9b274d615d80b14a829f6620aadf50cc2c..da03a99a0f1963ce3a6da203385d367f37cafb7c 100644 (file)
 
 using namespace icinga;
 
-boost::thread_specific_ptr<ScriptFrame *> ScriptFrame::m_CurrentFrame;
+boost::thread_specific_ptr<std::stack<ScriptFrame *> > ScriptFrame::m_ScriptFrames;
 
 ScriptFrame::ScriptFrame(void)
        : Locals(new Dictionary()), Self(ScriptGlobal::GetGlobals())
 {
-       NextFrame = GetCurrentFrame();
-       SetCurrentFrame(this);
+       PushFrame(this);
 }
 
 ScriptFrame::ScriptFrame(const Value& self)
        : Locals(new Dictionary()), Self(self)
 {
-       NextFrame = GetCurrentFrame();
-       SetCurrentFrame(this);
+       PushFrame(this);
 }
 
 ScriptFrame::~ScriptFrame(void)
 {
-       ASSERT(GetCurrentFrame() == this);
-       SetCurrentFrame(NextFrame);
+       ScriptFrame *frame = PopFrame();
+       ASSERT(frame == this);
 }
 
 ScriptFrame *ScriptFrame::GetCurrentFrame(void)
 {
-       ScriptFrame **pframe = m_CurrentFrame.get();
+       std::stack<ScriptFrame *> *frames = m_ScriptFrames.get();
 
-       if (pframe)
-               return *pframe;
-       else
-               return NULL;
+       ASSERT(!frames->empty());
+       return frames->top();
 }
 
-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);
 }
index 73a67d24859aa3d83bf6225d5a468e51feaaad0f..f4e47151acfb5d6018b57feea4ffeb0bfc8315ee 100644 (file)
@@ -23,6 +23,7 @@
 #include "config/i2-config.hpp"
 #include "base/dictionary.hpp"
 #include <boost/thread/tss.hpp>
+#include <stack>
 
 namespace icinga
 {
@@ -31,7 +32,6 @@ struct I2_BASE_API ScriptFrame
 {
        Dictionary::Ptr Locals;
        Value Self;
-       ScriptFrame *NextFrame;
 
        ScriptFrame(void);
        ScriptFrame(const Value& self);
@@ -40,9 +40,10 @@ struct I2_BASE_API ScriptFrame
        static ScriptFrame *GetCurrentFrame(void);
 
 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);
 };
 
 }