2 +----------------------------------------------------------------------+
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"
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
,
33 iJIT_Method_Load methodInfo
;
34 memset(&methodInfo
, 0, sizeof(methodInfo
));
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());
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
++) {
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
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
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
);
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
);
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
);