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 +----------------------------------------------------------------------+
16 #ifndef incl_HPHP_RUNTIME_VM_SERVICE_REQUESTS_INLINE_H_
17 #define incl_HPHP_RUNTIME_VM_SERVICE_REQUESTS_INLINE_H_
19 #include "hphp/runtime/vm/jit/service-requests.h"
20 #include "hphp/runtime/vm/jit/mc-generator.h"
22 namespace HPHP
{ namespace JIT
{
24 inline ServiceReqArgInfo
ccServiceReqArgInfo(JIT::ConditionCode cc
) {
25 return ServiceReqArgInfo
{ServiceReqArgInfo::CondCode
, { uint64_t(cc
) }};
29 typename
std::enable_if
<
30 // Only allow for things with a sensible cast to uint64_t.
31 std::is_integral
<T
>::value
|| std::is_pointer
<T
>::value
||
32 std::is_enum
<T
>::value
33 >::type
packServiceReqArg(ServiceReqArgVec
& args
, T arg
) {
34 // By default, assume we meant to pass an immediate arg.
35 args
.push_back({ ServiceReqArgInfo::Immediate
, { uint64_t(arg
) } });
38 inline void packServiceReqArg(ServiceReqArgVec
& args
,
39 const ServiceReqArgInfo
& argInfo
) {
40 args
.push_back(argInfo
);
43 template<typename T
, typename
... Arg
>
44 void packServiceReqArgs(ServiceReqArgVec
& argv
, T arg
, Arg
... args
) {
45 packServiceReqArg(argv
, arg
);
46 packServiceReqArgs(argv
, args
...);
49 inline void packServiceReqArgs(ServiceReqArgVec
& argv
) {
50 // Recursive base case.
53 //////////////////////////////////////////////////////////////////////
55 template<typename
... Arg
>
56 TCA
emitServiceReq(CodeBlock
& cb
, SRFlags flags
, ServiceRequest sr
, Arg
... a
) {
57 // These should reuse stubs. Use emitEphemeralServiceReq.
58 assert(sr
!= REQ_BIND_JMPCC_FIRST
&&
59 sr
!= REQ_BIND_JMPCC_SECOND
&&
62 ServiceReqArgVec argv
;
63 packServiceReqArgs(argv
, a
...);
64 return mcg
->backEnd().emitServiceReqWork(cb
, cb
.frontier(), true, flags
, sr
,
68 template<typename
... Arg
>
69 TCA
emitServiceReq(CodeBlock
& cb
, ServiceRequest sr
, Arg
... a
) {
70 return emitServiceReq(cb
, SRFlags::None
, sr
, a
...);
73 template<typename
... Arg
>
74 TCA
emitEphemeralServiceReq(CodeBlock
& cb
, TCA start
, ServiceRequest sr
,
76 assert(sr
== REQ_BIND_JMPCC_FIRST
||
77 sr
== REQ_BIND_JMPCC_SECOND
||
79 assert(cb
.contains(start
));
81 ServiceReqArgVec argv
;
82 packServiceReqArgs(argv
, a
...);
83 return mcg
->backEnd().emitServiceReqWork(cb
, start
, false, SRFlags::None
, sr
,
87 //////////////////////////////////////////////////////////////////////
93 template<> struct hash
<HPHP::JIT::ServiceRequest
> {
94 size_t operator()(const HPHP::JIT::ServiceRequest
& sr
) const {