| 101 | } |
| 102 | |
| 103 | bool Profiler::Write(CpuProfile* cpuProfile) { |
| 104 | struct timespec nowt; |
| 105 | clock_gettime(CLOCK_MONOTONIC, &nowt); |
| 106 | uint64_t now = (int64_t) nowt.tv_sec * 1000000000LL + nowt.tv_nsec; |
| 107 | |
| 108 | auto sec = static_cast<unsigned long>(now / 1000000); |
| 109 | auto usec = static_cast<unsigned long>(now % 1000000); |
| 110 | |
| 111 | char filename[256]; |
| 112 | auto profileName = ArgConverter::ConvertToString(cpuProfile->GetTitle()); |
| 113 | snprintf(filename, sizeof(filename), "%s/%s-%s-%lu.%lu.cpuprofile", m_outputDir.c_str(), m_appName.c_str(), profileName.c_str(), sec, usec); |
| 114 | |
| 115 | auto fp = fopen(filename, "w"); |
| 116 | if (nullptr == fp) { |
| 117 | return false; |
| 118 | } |
| 119 | |
| 120 | fwrite("{\"head\":", sizeof(char), 8, fp); |
| 121 | |
| 122 | stack<const CpuProfileNode*> s; |
| 123 | s.push(cpuProfile->GetTopDownRoot()); |
| 124 | |
| 125 | char buff[1024]; |
| 126 | auto COMMA_NODE = reinterpret_cast<const CpuProfileNode*>(1); |
| 127 | auto CLOSE_NODE = reinterpret_cast<const CpuProfileNode*>(2); |
| 128 | auto PREFIX = string("RegExp:"); |
| 129 | |
| 130 | while (!s.empty()) { |
| 131 | const CpuProfileNode* node = s.top(); |
| 132 | s.pop(); |
| 133 | if (node == CLOSE_NODE) { |
| 134 | fwrite("]}", sizeof(char), 2, fp); |
| 135 | } else if (node == COMMA_NODE) { |
| 136 | fwrite(",", sizeof(char), 1, fp); |
| 137 | } else { |
| 138 | auto funcName = ArgConverter::ConvertToString(node->GetFunctionName()); |
| 139 | auto scriptName = ArgConverter::ConvertToString(node->GetScriptResourceName()); |
| 140 | auto lineNumber = node->GetLineNumber(); |
| 141 | auto columnNumber = node->GetColumnNumber(); |
| 142 | if (funcName.compare(0, PREFIX.size(), PREFIX) == 0) { |
| 143 | stringstream ss; |
| 144 | ss << "RegExp_" << scriptName << "_" << lineNumber << "_" << columnNumber; |
| 145 | funcName = ss.str(); |
| 146 | } |
| 147 | snprintf(buff, sizeof(buff), "{\"functionName\":\"%s\",\"scriptId\":%d,\"url\":\"%s\",\"lineNumber\":%d,\"columnNumber\":%d,\"hitCount\":%u,\"deoptReason\":\"%s\",\"id\":%u,\"children\":[", |
| 148 | funcName.c_str(), |
| 149 | node->GetScriptId(), |
| 150 | scriptName.c_str(), |
| 151 | lineNumber, |
| 152 | columnNumber, |
| 153 | node->GetHitCount(), |
| 154 | node->GetBailoutReason(), |
| 155 | node->GetNodeId()); |
| 156 | fwrite(buff, sizeof(char), strlen(buff), fp); |
| 157 | |
| 158 | s.push(CLOSE_NODE); |
| 159 | |
| 160 | int count = node->GetChildrenCount(); |