Switch-related cleanup
[hiphop-php.git] / hphp / runtime / vm / jit / vtune-jit.cpp
blob8e99084a9b94ad0b31372931eb5ebc3c5ee9d0ab
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/runtime/vm/jit/vtune-jit.h"
18 #include "hphp/runtime/vm/jit/vtune/jitprofiling.h"
20 #include <vector>
21 #include <algorithm>
23 namespace HPHP { namespace jit {
25 // Method ids reported to Vtune JIT API should not be less than 1000 (see
26 // the comment in iJIT_Method_Load structure definition.) We use 1000 for
27 // trampolines and larger values for normal functions.
28 static const int MIN_METHOD_ID = 1000;
30 void reportTraceletToVtune(const Unit* unit,
31 const Func* func,
32 const TransRec& tr) {
33 iJIT_Method_Load methodInfo;
34 memset(&methodInfo, 0, sizeof(methodInfo));
36 if (!unit) return;
38 methodInfo.method_id = tr.src.funcID() + MIN_METHOD_ID;
40 if (func && func->fullName()) {
41 methodInfo.method_name = const_cast<char *>(func->fullName()->data());
42 } else {
43 methodInfo.method_name = const_cast<char *>("unknown");
46 methodInfo.source_file_name = const_cast<char *>(unit->filepath()->data());
48 // aStart field of tr.bcmapping may point to cold range, so we need to
49 // explicitly form mappings for main code and cold
51 size_t bcSize = tr.bcMapping.size();
52 std::vector<LineNumberInfo> mainLineMap, coldLineMap;
54 for (size_t i = 0; i < bcSize; i++) {
55 LineNumberInfo info;
57 info.LineNumber = unit->getLineNumber(tr.bcMapping[i].bcStart);
59 // Note that main code may be generated in the cold code range (see
60 // emitBlock in code-gen-x64 genCodeImpl()) so we need to explicitly check
61 // the aStart value.
62 if (tr.bcMapping[i].aStart >= tr.aStart &&
63 tr.bcMapping[i].aStart < tr.aStart + tr.aLen) {
64 info.Offset = tr.bcMapping[i].aStart - tr.aStart;
65 mainLineMap.push_back(info);
66 } else if (tr.bcMapping[i].aStart >= tr.acoldStart &&
67 tr.bcMapping[i].aStart < tr.acoldStart + tr.acoldLen) {
68 info.Offset = tr.bcMapping[i].aStart - tr.acoldStart;
69 coldLineMap.push_back(info);
72 info.Offset = tr.bcMapping[i].acoldStart - tr.acoldStart;
73 coldLineMap.push_back(info);
76 auto infoComp = [&](const LineNumberInfo& a,
77 const LineNumberInfo& b) -> bool {
78 return a.Offset < b.Offset;
81 std::sort(mainLineMap.begin(), mainLineMap.end(), infoComp);
82 std::sort(coldLineMap.begin(), coldLineMap.end(), infoComp);
84 // Note that at this moment LineNumberInfo structures contain pairs of lines
85 // and code offset for the start of the corresponding code, while JIT API
86 // treats the offset as the end of this code (and the start offset is taken
87 // from the previous element or is 0); need to shift the elements. Also,
88 // attribute the prologue (code before the first byte in the mapping) to the
89 // first line.
91 auto shiftLineMap = [&](std::vector<LineNumberInfo>& lineMap,
92 unsigned regionSize) {
93 if (lineMap.size() > 0) {
94 LineNumberInfo tmpInfo;
95 tmpInfo.Offset = regionSize;
96 tmpInfo.LineNumber = lineMap.back().LineNumber;
97 lineMap.push_back(tmpInfo);
98 for (size_t i = lineMap.size() - 2; i > 0; i--) {
99 lineMap[i].LineNumber = lineMap[i - 1].LineNumber;
104 shiftLineMap(mainLineMap, tr.aLen);
105 shiftLineMap(coldLineMap, tr.acoldLen);
107 // Report main body
109 methodInfo.method_load_address = tr.aStart;
110 methodInfo.method_size = tr.aLen;
111 methodInfo.line_number_size = mainLineMap.size();
112 methodInfo.line_number_table = &mainLineMap[0];
114 iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void *)&methodInfo);
116 // Report cold
118 methodInfo.method_load_address = tr.acoldStart;
119 methodInfo.method_size = tr.acoldLen;
120 methodInfo.line_number_size = coldLineMap.size();
121 methodInfo.line_number_table = &coldLineMap[0];
123 iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void *)&methodInfo);