2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present 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/type-profile.h"
19 #include "hphp/runtime/base/execution-context.h"
20 #include "hphp/runtime/base/request-info.h"
21 #include "hphp/runtime/base/runtime-option.h"
22 #include "hphp/runtime/vm/jit/mcgen-translate.h"
23 #include "hphp/runtime/vm/jit/relocation.h"
24 #include "hphp/runtime/vm/jit/tc.h"
25 #include "hphp/runtime/vm/jit/write-lease.h"
32 //////////////////////////////////////////////////////////////////////
37 * In cli mode, we only record samples if we're in recording to replay later.
39 * In server mode, we exclude warmup document requests from profiling.
42 RDS_LOCAL_NO_CHECK(TypeProfileLocals
, rl_typeProfileLocals
)
43 {TypeProfileLocals
{}};
48 std::atomic
<uint64_t> numRequests
;
52 ProfileNonVMThread::ProfileNonVMThread() {
53 always_assert(!rl_typeProfileLocals
->nonVMThread
);
54 rl_typeProfileLocals
->nonVMThread
= true;
57 ProfileNonVMThread::~ProfileNonVMThread() {
58 rl_typeProfileLocals
->nonVMThread
= false;
61 void profileWarmupStart() {
65 void profileWarmupEnd() {
69 uint64_t requestCount() {
70 return numRequests
.load(std::memory_order_relaxed
);
73 static inline RequestKind
getRequestKind() {
74 if (rl_typeProfileLocals
->nonVMThread
) return RequestKind::NonVM
;
75 if (warmingUp
) return RequestKind::Warmup
;
76 return RequestKind::Standard
;
79 void profileRequestStart() {
80 rl_typeProfileLocals
->requestKind
= getRequestKind();
82 auto const codeCoverageForceInterp
= []{
83 if (RuntimeOption::EvalEnableCodeCoverage
> 1) return true;
84 if (RuntimeOption::EvalEnableCodeCoverage
== 1) {
85 if (RuntimeOption::RepoAuthoritative
) return false;
86 auto const tport
= g_context
->getTransport();
88 tport
->getParam("enable_code_coverage").compare("true") == 0;
93 // Force the request to use interpreter (not even running jitted code) during
94 // retranslateAll when we need to dump out precise profile data.
95 auto const forceInterp
= (jit::mcgen::pendingRetranslateAllScheduled() &&
96 RuntimeOption::DumpPreciseProfData
) ||
97 codeCoverageForceInterp
;
98 bool okToJit
= !forceInterp
&& isStandardRequest();
99 if (!RequestInfo::s_requestInfo
.isNull()) {
100 if (RID().isJittingDisabled()) {
102 } else if (!okToJit
) {
103 RID().setJittingDisabled(true);
106 jit::setMayAcquireLease(okToJit
);
108 // Force interpretation if needed.
109 if (rl_typeProfileLocals
->forceInterpret
!= forceInterp
) {
110 rl_typeProfileLocals
->forceInterpret
= forceInterp
;
111 if (!RequestInfo::s_requestInfo
.isNull()) {
117 void profileRequestEnd() {
118 if (!isStandardRequest()) return;
119 numRequests
.fetch_add(1, std::memory_order_relaxed
);
120 static auto const requestSeries
= ServiceData::createTimeSeries(
122 {ServiceData::StatsType::RATE
, ServiceData::StatsType::SUM
},
123 {std::chrono::seconds(60), std::chrono::seconds(0)}
125 requestSeries
->addValue(1);