63 #include <unordered_map> 66 #include "vtune-jit.h" 78 void SetPosition(intptr_t pc,
int pos) {
84 : pc_(pc), pos_(pos) { }
90 std::list<LineNumInfo>* GetLineNumInfo() {
91 return &line_num_info_;
95 void AddCodeLineInfo(
const LineNumInfo& line_info) {
96 line_num_info_.push_back(line_info);
98 std::list<LineNumInfo> line_num_info_;
102 bool operator () (
void* key1,
void* key2)
const {
108 uint32_t operator () (
void* code)
const {
109 static const uintptr_t kGoldenRatio = 2654435761u;
111 return static_cast<uint32_t>(hash * kGoldenRatio);
115 typedef std::unordered_map<void*, void*, HashForCodeObject, SameCodeObjects>
118 static JitInfoMap* GetEntries() {
119 static JitInfoMap* entries;
120 if (entries == NULL) {
121 entries =
new JitInfoMap();
126 static bool IsLineInfoTagged(
void* ptr) {
127 return 0 != (
reinterpret_cast<intptr_t
>(ptr));
130 static JITCodeLineInfo* UntagLineInfo(
void* ptr) {
131 return reinterpret_cast<JITCodeLineInfo*
>(
132 reinterpret_cast<intptr_t
>(ptr));
139 static char* GetFunctionNameFromMixedName(
const char* str,
int length) {
142 char* start_ptr = NULL;
144 while (str[index++] !=
':' && (index < length)) {}
146 if (str[index] ==
'*' || str[index] ==
'~' ) index++;
147 if (index >= length)
return NULL;
149 start_ptr =
const_cast<char*
>(str + index);
151 while (index < length && str[index++] !=
' ') {
155 char* result =
new char[count + 1];
156 memcpy(result, start_ptr, count);
157 result[count] =
'\0';
163 void VTUNEJITInterface::event_handler(
const v8::JitCodeEvent* event) {
164 if (VTUNERUNNING && event != NULL) {
165 switch (event->type) {
166 case v8::JitCodeEvent::CODE_ADDED: {
167 char* temp_file_name = NULL;
168 char* temp_method_name =
169 GetFunctionNameFromMixedName(event->name.str,
170 static_cast<int>(event->name.len));
172 memset(&jmethod, 0,
sizeof jmethod);
173 jmethod.method_id = iJIT_GetNewMethodID();
174 jmethod.method_load_address =
event->code_start;
175 jmethod.method_size =
static_cast<unsigned int>(
event->code_len);
176 jmethod.method_name = temp_method_name;
178 Local<UnboundScript> script =
event->script;
180 if (*script != NULL) {
182 if ((*script->GetScriptName())->IsString()) {
183 Local<String> script_name =
186 new char[script_name->Utf8Length(event->isolate) + 1];
187 script_name->WriteUtf8(event->isolate, temp_file_name);
188 jmethod.source_file_name = temp_file_name;
191 JitInfoMap::iterator entry =
192 GetEntries()->find(event->code_start);
193 if (entry != GetEntries()->end() && IsLineInfoTagged(entry->first)) {
194 JITCodeLineInfo* line_info = UntagLineInfo(entry->second);
196 std::list<JITCodeLineInfo::LineNumInfo>* vtunelineinfo =
197 line_info->GetLineNumInfo();
199 jmethod.line_number_size = (
unsigned int)vtunelineinfo->size();
200 jmethod.line_number_table =
204 std::list<JITCodeLineInfo::LineNumInfo>::iterator Iter;
206 for (Iter = vtunelineinfo->begin();
207 Iter != vtunelineinfo->end();
209 jmethod.line_number_table[index].Offset =
210 static_cast<unsigned int>(Iter->pc_);
211 jmethod.line_number_table[index++].LineNumber =
212 script->GetLineNumber(Iter->pos_) + 1;
214 GetEntries()->erase(event->code_start);
218 iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED,
219 reinterpret_cast<void*>(&jmethod));
220 if (temp_method_name)
221 delete []temp_method_name;
223 delete []temp_file_name;
227 case v8::JitCodeEvent::CODE_MOVED:
230 case v8::JitCodeEvent::CODE_REMOVED:
232 case v8::JitCodeEvent::CODE_ADD_LINE_POS_INFO: {
233 JITCodeLineInfo* line_info =
234 reinterpret_cast<JITCodeLineInfo*
>(
event->user_data);
235 if (line_info != NULL) {
236 line_info->SetPosition(static_cast<intptr_t>(event->line_info.offset),
237 static_cast<int>(event->line_info.pos));
241 case v8::JitCodeEvent::CODE_START_LINE_INFO_RECORDING: {
242 v8::JitCodeEvent* temp_event =
const_cast<v8::JitCodeEvent*
>(event);
243 temp_event->user_data =
new JITCodeLineInfo();
246 case v8::JitCodeEvent::CODE_END_LINE_INFO_RECORDING: {
247 GetEntries()->insert(std::pair <void*, void*>(event->code_start, event->user_data));
259 v8::JitCodeEventHandler GetVtuneCodeEventHandler() {
260 v8::V8::SetFlagsFromString(
"--nocompact_code_space",
261 (
int)strlen(
"--nocompact_code_space"));
262 return vTune::internal::VTUNEJITInterface::event_handler;
static V8_INLINE Local< T > Cast(Local< S > that)