Ticket #2127: scriptinterface_performance+style.patch
File scriptinterface_performance+style.patch, 10.2 KB (added by , 11 years ago) |
---|
-
source/contributors.txt
45 45 # Other contributors: 46 46 47 47 André Puel 48 Jonas Platte <jonasplatte@myopera.com> 48 49 Lars Kemmann 49 50 Nick Owens <digitalseraphim@gmail.com> 50 51 Quentin Pradet <quentin.pradet@gmail.com> -
source/scriptinterface/DebuggingServer.cpp
33 33 void CDebuggingServer::GetAllCallstacks(std::stringstream& response) 34 34 { 35 35 CScopeLock lock(m_Mutex); 36 response.str( "");36 response.str(std::string()); 37 37 std::stringstream stream; 38 38 uint nbrCallstacksWritten = 0; 39 39 std::list<CThreadDebugger*>::iterator itr; … … 44 44 { 45 45 if ((*itr)->GetIsInBreak()) 46 46 { 47 stream.str(""); 48 std::string str = stream.str(); 47 stream.str(std::string()); 49 48 (*itr)->GetCallstack(stream); 50 str = stream.str(); 51 if (stream.str() != "") 49 if ((int)stream.tellp() != 0) 52 50 { 53 51 if (nbrCallstacksWritten != 0) 54 52 response << ","; 55 response << "{" << "\"ThreadDebuggerID\" : " << (*itr)->GetID() << ", \"CallStack\" : " << stream.str()<< "}";53 response << "{" << "\"ThreadDebuggerID\" : " << (*itr)->GetID() << ", \"CallStack\" : " << stream << "}"; 56 54 nbrCallstacksWritten++; 57 55 } 58 56 … … 65 63 void CDebuggingServer::GetStackFrameData(std::stringstream& response, uint nestingLevel, uint threadDebuggerID, STACK_INFO stackInfoKind) 66 64 { 67 65 CScopeLock lock(m_Mutex); 68 response.str( "");66 response.str(std::string()); 69 67 std::stringstream stream; 70 68 std::list<CThreadDebugger*>::iterator itr; 71 69 for (itr = m_ThreadDebuggers.begin(); itr != m_ThreadDebuggers.end(); ++itr) 72 70 { 73 if ( 71 if ((*itr)->GetID() == threadDebuggerID && (*itr)->GetIsInBreak()) 74 72 { 75 73 (*itr)->GetStackFrameData(stream, nestingLevel, stackInfoKind); 76 if ( stream.str() != "")74 if ((int)stream.tellp() != 0) 77 75 { 78 response << stream.str();76 response << stream; 79 77 } 80 78 } 81 79 } … … 114 112 std::list<CThreadDebugger*>::iterator itr; 115 113 for (itr = m_ThreadDebuggers.begin(); itr != m_ThreadDebuggers.end(); ++itr) 116 114 { 117 if ( 115 if ((*itr)->GetID() == threadDebuggerID || threadDebuggerID == 0) 118 116 { 119 117 if (DBG_CMD_NONE == (*itr)->GetNextDbgCmd() && (*itr)->GetIsInBreak()) 120 118 { … … 188 186 { 189 187 VfsPath path = L""; 190 188 VfsPaths pathnames; 191 response.str( "");189 response.str(std::string()); 192 190 193 191 std::vector<std::string> templates; 194 192 vfs::ForEachFile(g_VFS, "", AddFileResponse, (uintptr_t)&templates, L"*.js", vfs::DIR_RECURSIVE); … … 438 436 int len = mg_get_var(request_info->query_string, strlen(request_info->query_string), argName.c_str(), buf, ARRAY_SIZE(buf)); 439 437 if (len < 0) 440 438 { 441 442 439 mg_printf(conn, "%s (no '%s')", header400, argName.c_str()); 440 return false; 443 441 } 444 442 arg = atoi(buf); 445 443 return true; … … 492 490 void CDebuggingServer::GetThreadDebuggerStatus(std::stringstream& response) 493 491 { 494 492 CScopeLock lock(m_Mutex); 495 response.str( "");493 response.str(std::string()); 496 494 std::list<CThreadDebugger*>::iterator itr; 497 495 498 496 response << "["; … … 529 527 // If the breakpoint isn't handled yet search the breakpoints registered in this class 530 528 std::list<CBreakPoint>* pBreakPoints = NULL; 531 529 double breakPointsLockID = AquireBreakPointAccess(&pBreakPoints); 532 std::list<CBreakPoint>::iterator itr;533 530 534 531 // If set, delete 535 532 bool deleted = false; 536 for ( itr = pBreakPoints->begin(); itr != pBreakPoints->end(); ++itr)533 for (std::list<CBreakPoint>::iterator itr = pBreakPoints->begin(); itr != pBreakPoints->end(); ++itr) 537 534 { 538 535 if ((*itr).m_Filename == filename && (*itr).m_UserLine == line) 539 536 { … … 560 557 { 561 558 int ret; 562 559 ret = SDL_SemWait(m_BreakPointsSem); 563 ENSURE( 0 == ret);560 ENSURE(ret == 0); 564 561 (*breakPoints) = &m_BreakPoints; 565 562 m_BreakPointsLockID = timer_Time(); 566 563 return m_BreakPointsLockID; -
source/scriptinterface/ScriptInterface.cpp
1092 1092 JS_ClearPendingException(m->m_cx); 1093 1093 LOGERROR(L"StringifyJSON failed"); 1094 1094 JS_ClearPendingException(m->m_cx); 1095 return "";1095 return std::string(); 1096 1096 } 1097 1097 1098 1098 return str.stream.str(); -
source/scriptinterface/ThreadDebugger.cpp
168 168 uint m_ID; 169 169 }; 170 170 171 ThreadDebugger_impl::ThreadDebugger_impl() : 172 m_NextDbgCmd(DBG_CMD_NONE), m_IsInBreak(false), m_pLastBreakFrame(new JSStackFrame*) 173 { 174 } 171 ThreadDebugger_impl::ThreadDebugger_impl() 172 : m_NextDbgCmd(DBG_CMD_NONE) 173 , m_pScriptInterface(NULL) 174 , m_pDebuggingServer(NULL) 175 , m_pLastBreakFrame(new JSStackFrame*) 176 , m_IsInBreak(false) 177 { } 175 178 176 179 ThreadDebugger_impl::~ThreadDebugger_impl() 177 180 { … … 188 191 { 189 192 if ((*itr)->m_ToRemove) 190 193 { 191 ClearTrap((*itr)); 192 // Remove the breakpoint 193 delete (*itr); 194 itr = m->m_ActiveBreakPoints.erase(itr); 195 194 ClearTrap((*itr)); 195 // Remove the breakpoint 196 delete (*itr); 197 itr = m->m_ActiveBreakPoints.erase(itr); 196 198 } 197 199 else 198 200 ++itr; … … 527 529 SetAllNewTraps(); 528 530 SetNextDbgCmd(DBG_CMD_NONE); 529 531 SetIsInBreak(false); 530 SetBreakFileName( "");532 SetBreakFileName(std::string()); 531 533 532 534 // All saved stack data becomes invalid 533 535 { … … 542 544 { 543 545 uint scriptExtent = JS_GetScriptLineExtent (cx, script); 544 546 std::string stringFileName(filename); 545 if (stringFileName == "")547 if (stringFileName.empty()) 546 548 return; 547 549 548 550 for (uint line = lineno; line < scriptExtent + lineno; ++line) … … 648 650 649 651 JSStackFrame *fp; 650 652 JSStackFrame *iter = 0; 651 std::string functionName;652 653 jsint counter = 0; 653 654 654 655 JSObject* jsArray; … … 676 677 counter++; 677 678 } 678 679 679 m->m_Callstack = "";680 m->m_Callstack.clear(); 680 681 m->m_Callstack = m->m_pScriptInterface->StringifyJSON(OBJECT_TO_JSVAL(jsArray), false).c_str(); 681 682 } 682 683 … … 699 700 700 701 CScopeLock lock(m->m_Mutex); 701 702 { 702 response.str( "");703 response.str(std::string()); 703 704 response << m->m_StackFrameData[stackInfoKind][nestingLevel]; 704 705 } 705 706 } … … 718 719 ENSURE(GetIsInBreak()); 719 720 720 721 CScopeLock lock(m->m_Mutex); 721 JSStackFrame *fp;722 722 JSStackFrame *iter = 0; 723 723 uint counter = 0; 724 724 jsval val; … … 731 731 } 732 732 else 733 733 { 734 fp = JS_FrameIterator(m->m_pScriptInterface->GetContext(), &iter);734 JSStackFrame *fp = JS_FrameIterator(m->m_pScriptInterface->GetContext(), &iter); 735 735 while (fp) 736 736 { 737 737 if (counter == nestingLevel) … … 766 766 * Unfortunately this seems to require writing (or embedding) a new serializer to JSON or something similar. 767 767 * 768 768 * Some things about the implementation which aren't optimal: 769 * 1. It uses globa bl variables (they are limited to a namespace though)769 * 1. It uses global variables (they are limited to a namespace though). 770 770 * 2. It has to work around a bug in Spidermonkey. 771 771 * 3. It copies code from CScriptInterface. I did this to separate it cleanly because the debugger should not affect 772 772 * the rest of the game and because this part of code should be replaced anyway in the future. 773 773 */ 774 774 775 776 775 namespace CyclicRefWorkaround 776 { 777 777 std::set<JSObject*> g_ProcessedObjects; 778 778 jsval g_LastKey; 779 779 jsval g_LastValue; 780 780 bool g_RecursionDetectedInPrevReplacer = false; 781 781 uint g_countSameKeys = 0; 782 782 783 783 struct Stringifier 784 784 { 785 785 static JSBool callback(const jschar* buf, uint32 len, void* data) … … 794 794 795 795 std::stringstream stream; 796 796 }; 797 797 798 798 JSBool replacer(JSContext* cx, uintN UNUSED(argc), jsval* vp) 799 799 { 800 800 jsval value = JS_ARGV(cx, vp)[1]; … … 830 830 JS_SET_RVAL(cx, vp, JS_ARGV(cx, vp)[1]); 831 831 return JS_TRUE; 832 832 } 833 834 833 } 834 835 835 std::string CThreadDebugger::StringifyCyclicJSON(jsval obj, bool indent) 836 836 { 837 837 CyclicRefWorkaround::Stringifier str; … … 861 861 862 862 } 863 863 JS_ClearPendingException(m->m_pScriptInterface->GetContext()); 864 return "";864 return std::string(); 865 865 } 866 866 867 867 return str.stream.str(); 868 868 } 869 869 870 870 871 bool CThreadDebugger::CompareScriptInterfacePtr(ScriptInterface* pScriptInterface) 871 bool CThreadDebugger::CompareScriptInterfacePtr(ScriptInterface* pScriptInterface) const 872 872 { 873 873 return (pScriptInterface == m->m_pScriptInterface); 874 874 } -
source/scriptinterface/ThreadDebugger.h
27 27 class CBreakPoint 28 28 { 29 29 public: 30 CBreakPoint() { m_UserLine = 0; m_Filename = ""; } 30 CBreakPoint() : m_UserLine(0) { } 31 31 32 uint m_UserLine; 32 33 std::string m_Filename; 33 34 }; … … 36 37 class CActiveBreakPoint : public CBreakPoint 37 38 { 38 39 public: 39 CActiveBreakPoint() : 40 CBreakPoint() 41 { 42 Initialize(); 43 } 40 CActiveBreakPoint() 41 : m_ActualLine(m_UserLine) 42 , m_Script(NULL) 43 , m_Pc(NULL) 44 , m_ToRemove(false) 45 { } 44 46 45 47 CActiveBreakPoint(CBreakPoint breakPoint) 46 { 47 m_Filename = breakPoint.m_Filename; 48 m_UserLine = breakPoint.m_UserLine; 49 Initialize(); 50 } 51 52 void Initialize() 53 { 54 m_ToRemove = false; 55 m_Script = NULL; 56 m_Pc = NULL; 57 m_ActualLine = m_UserLine; 58 } 48 : CBreakPoint(breakPoint) // using default copy constructor 49 , m_ActualLine(m_UserLine) 50 , m_Script(NULL) 51 , m_Pc(NULL) 52 , m_ToRemove(false) 53 { } 59 54 60 55 uint m_ActualLine; 61 56 JSScript* m_Script; … … 151 146 /** @brief Compares the object's associated scriptinterface with the pointer passed as parameter. 152 147 * @return true if equal 153 148 */ 154 bool CompareScriptInterfacePtr(ScriptInterface* pScriptInterface) ;149 bool CompareScriptInterfacePtr(ScriptInterface* pScriptInterface) const; 155 150 156 151 // Getter/Setters for members that need to be threadsafe 157 152 std::string GetBreakFileName();