Skip to content

Commit b0f30d4

Browse files
Jip J. Dekkeralbertnetymk
Jip J. Dekker
authored andcommitted
Add DTrace/SystemTap support to Encore (parapluu#655)
* DTrace for Pony and Encore works together <3 use make use=dtrace. This will create probes in both encore and pony. For systemtap you can try this feature with following: cd src/tests/encore/systemtap encorec ../basic/realfutures.enc -o realfutures sudo stap -L 'process("*").mark("*")' * Adds DTrace probes for specific future uses * Adds probe for closure creation * Fix DTrace compilation * Framework for inserting dtrace probes This commit provides a framework for inserting dtrace probes in Encore programs. Currently, only comments are generated, but in theory we should be able to replace them with actual dtrace calls. This at least works as a starting point for the dtrace-team. Also some boyscouting. * Adds the actual probes to the generated C code * Early exit on DTrace header generation * Fix the encore probes * Fix dtrace function without arguments * Enable DTrace for embedded statements * haskell changes should now be working * Fixes the Embedded probe mess * Add additional header to compile clean without DTrace This is a workaround that will make sure that Encore compiles cleanly when compiled without the flag. The extra header file is placed in
1 parent a66b193 commit b0f30d4

19 files changed

+400
-64
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,5 @@ src/tests/encore/traits/*
7474
.stack*
7575
coverage/
7676
encorec.tix
77+
src/runtime/common/dtrace_probes.h
78+
src/runtime/common/encore_probes.h

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ RANGE_INC=$(RUNTIME_DIR)/range/range.h
8181
RANGE_LIB=$(RUNTIME_DIR)/pony/bin/$(CONFIG)/librange.a
8282

8383
pony: dirs $(PONY_INC)
84-
make -C $(SRC_DIR) pony
84+
make -C $(SRC_DIR) pony use=$(use)
8585
cp -r $(COMMON_INC) $(INC_DIR)
8686
cp -r $(POOL_INC) $(INC_DIR)
8787
cp -r $(PONY_INC) $(INC_DIR)

src/Makefile

+10-4
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ PONY_DIR=runtime/pony
22

33
all: pony
44

5-
test:
5+
test:
66
make -C tests
77

8-
pony:
9-
cd $(PONY_DIR); premake4 gmake
8+
pony:
9+
cd $(PONY_DIR); premake4 gmake $(use)
1010
make -C $(PONY_DIR) config=debug
1111
make -C $(PONY_DIR) config=release
1212

13-
clean: clean_pony
13+
clean: clean_pony clean_dtrace
1414
@echo "cleaning test files..."
1515
make -C tests clean
1616
@echo "done"
@@ -20,4 +20,10 @@ clean_pony:
2020
[ -f $(PONY_DIR)/Makefile ] && make -C $(PONY_DIR) clean || true
2121
rm -rf $(PONY_DIR)/*.make $(PONY_DIR)/Makefile $(PONY_DIR)/bin $(PONY_DIR)/obj
2222

23+
clean_dtrace:
24+
rm -f $(PONY_DIR)/../common/dtrace_probes.h
25+
rm -f $(PONY_DIR)/../common/encore_probes.h
26+
rm -f $(PONY_DIR)/../common/dtrace_probes.o
27+
rm -f $(PONY_DIR)/../common/encore_probes.o
28+
2329
.PHONY: all test pony clean clean_pony

src/back/CodeGen/CCodeNames.hs

+9
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,15 @@ encoreAssert :: CCode Expr -> CCode Stat
141141
encoreAssert p =
142142
Statement $ Call (Nam "encore_assert") [Cast (Typ "intptr_t") p]
143143

144+
this :: String
145+
this = "_this"
146+
147+
thisName :: CCode Name
148+
thisName = Nam this
149+
150+
thisVar :: CCode Lval
151+
thisVar = Var this
152+
144153
encoreName :: String -> String -> String
145154
encoreName kind name =
146155
let

src/back/CodeGen/ClassDecl.hs

+16-16
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import CodeGen.ClassTable
1616
import CodeGen.Type
1717
import CodeGen.Trace
1818
import CodeGen.GC
19+
import CodeGen.DTrace
1920

2021
import CCode.Main
2122
import CCode.PrettyCCode ()
@@ -67,7 +68,7 @@ dispatchFunDecl cdecl@(A.Class{A.cname, A.cfields, A.cmethods}) =
6768
([(Ptr (Ptr encoreCtxT), encoreCtxVar),
6869
(Ptr ponyActorT, Var "_a"),
6970
(Ptr ponyMsgT, Var "_m")])
70-
(Seq [Assign (Decl (Ptr . AsType $ classTypeName cname, Var "_this"))
71+
(Seq [Assign (Decl (Ptr . AsType $ classTypeName cname, thisVar))
7172
(Cast (Ptr . AsType $ classTypeName cname) (Var "_a")),
7273
Seq $ map assignTypeVar classTypeVars,
7374
(Switch (Var "_m" `Arrow` Nam "id")
@@ -83,7 +84,7 @@ dispatchFunDecl cdecl@(A.Class{A.cname, A.cfields, A.cmethods}) =
8384
classTypeVars = Ty.getTypeParameters cname
8485
assignTypeVar t =
8586
Assign (Decl (Ptr ponyTypeT, AsLval $ typeVarRefName t))
86-
(Arrow (Nam "_this") (typeVarRefName t))
87+
(Arrow thisName (typeVarRefName t))
8788
ponyMainClause =
8889
(Nam "_ENC__MSG_MAIN",
8990
Seq $ [Assign (Decl (Ptr ponyMainMsgT, Var "msg")) (Cast (Ptr ponyMainMsgT) (Var "_m")),
@@ -167,7 +168,7 @@ dispatchFunDecl cdecl@(A.Class{A.cname, A.cfields, A.cmethods}) =
167168
streamMethodCall =
168169
Statement $ Call (methodImplName cname mName)
169170
(encoreCtxVar :
170-
Var "_this" :
171+
thisVar :
171172
nullVar :
172173
Var "_fut" :
173174
map (AsLval . argName . A.pname) mParams)
@@ -178,7 +179,7 @@ dispatchFunDecl cdecl@(A.Class{A.cname, A.cfields, A.cmethods}) =
178179
AsExpr $ Var "_fut",
179180
asEncoreArgT (translate mType)
180181
(Call (methodImplName cname mName)
181-
(encoreCtxVar : Var "_this" :
182+
(encoreCtxVar : thisVar :
182183
pMethodArrName :
183184
map (AsLval . argName . A.pname) mParams))]
184185
mName = A.methodName mdecl
@@ -199,7 +200,7 @@ dispatchFunDecl cdecl@(A.Class{A.cname, A.cfields, A.cmethods}) =
199200
methodCall =
200201
Statement $
201202
Call (methodImplName cname mName)
202-
(encoreCtxVar : Var "_this" : pMethodArrName :
203+
(encoreCtxVar : thisVar : pMethodArrName :
203204
map (AsLval . argName . A.pname) mParams)
204205
mName = A.methodName mdecl
205206
mParams = A.methodParams mdecl
@@ -237,15 +238,14 @@ constructorImpl act cname =
237238
fBody = Seq $
238239
assignThis :
239240
decorateThis act ++
240-
[ret this]
241+
[ret thisVar]
241242
in
242243
Function retType fName args fBody
243244
where
244245
classType = AsType $ classTypeName cname
245246
thisType = Ptr classType
246247
cast = Cast thisType
247-
this = Var "this"
248-
declThis = Decl (thisType, this)
248+
declThis = Decl (thisType, thisVar)
249249
runtimeType = Amp $ runtimeTypeName cname
250250
create = createCall act
251251
assignThis = Assign declThis $ cast create
@@ -260,7 +260,7 @@ constructorImpl act cname =
260260
Call encoreAllocName [AsExpr $ Deref encoreCtxVar, Sizeof classType]
261261

262262
decorateThis :: Activity -> [CCode Stat]
263-
decorateThis Passive = [Assign (this `Arrow` selfTypeField) runtimeType]
263+
decorateThis Passive = [Assign (thisVar `Arrow` selfTypeField) runtimeType]
264264
decorateThis _ = []
265265

266266
translateSharedClass cdecl@(A.Class{A.cname, A.cfields, A.cmethods}) table =
@@ -327,16 +327,16 @@ traitMethodSelector table A.Class{A.cname, A.ccomposition} =
327327
runtimeTypeInitFunDecl :: A.ClassDecl -> CCode Toplevel
328328
runtimeTypeInitFunDecl A.Class{A.cname, A.cfields, A.cmethods} =
329329
Function void (runtimeTypeInitFnName cname)
330-
[(Ptr . AsType $ classTypeName cname, Var "this"), (Embed "...", Embed "")]
330+
[(Ptr . AsType $ classTypeName cname, thisVar), (Embed "...", Embed "")]
331331
(Seq $
332332
(Statement $ Decl (Typ "va_list", Var "params")) :
333-
(Statement $ Call (Nam "va_start") [Var "params", Var "this"]) :
333+
(Statement $ Call (Nam "va_start") [Var "params", thisVar]) :
334334
map initRuntimeType typeParams ++
335335
[Statement $ Call (Nam "va_end") [Var "params"]])
336336
where
337337
typeParams = Ty.getTypeParameters cname
338338
initRuntimeType ty =
339-
Assign (Var "this" `Arrow` typeVarRefName ty)
339+
Assign (thisVar `Arrow` typeVarRefName ty)
340340
(Call (Nam "va_arg") [Var "params", Var "pony_type_t *"])
341341

342342
tracefunDecl :: A.ClassDecl -> CCode Toplevel
@@ -353,7 +353,7 @@ tracefunDecl A.Class{A.cname, A.cfields, A.cmethods} =
353353
(Ptr void, Var "p")]
354354
(Seq $
355355
(Assign (Decl (Ptr (Ptr encoreCtxT), encoreCtxVar)) (Amp ctxArg)):
356-
(Assign (Decl (Ptr . AsType $ classTypeName cname, Var "_this"))
356+
(Assign (Decl (Ptr . AsType $ classTypeName cname, thisVar))
357357
(Var "p")) :
358358
runtimeTypeAssignment ++
359359
map traceField cfields)
@@ -363,12 +363,12 @@ tracefunDecl A.Class{A.cname, A.cfields, A.cmethods} =
363363
extractTypeVariable t =
364364
if Ty.isTypeVar t then
365365
Assign (Decl (Ptr ponyTypeT, AsLval $ typeVarRefName t))
366-
(Arrow (Nam "_this") (typeVarRefName t))
367-
else error $ "Expected type variable but found concrete type"
366+
(Arrow thisName (typeVarRefName t))
367+
else error "Expected type variable but found concrete type"
368368
typeParams = Ty.getTypeParameters cname
369369
traceField A.Field {A.ftype, A.fname} =
370370
let var = Var . show $ fieldName fname
371-
field = Var "_this" `Arrow` fieldName fname
371+
field = thisVar `Arrow` fieldName fname
372372
fieldAssign = Assign (Decl (translate ftype, var)) field
373373
in Seq [fieldAssign, traceVariable ftype var]
374374

src/back/CodeGen/Closure.hs

+7-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import CodeGen.Trace (traceVariable)
1111
import CodeGen.CCodeNames
1212
import CodeGen.ClassTable
1313
import qualified CodeGen.Context as Ctx
14+
import CodeGen.DTrace
1415
import CCode.Main
1516
import qualified Identifiers as ID
1617

@@ -69,9 +70,12 @@ translateClosure closure typeVars table
6970
(Typ "value_t", Var "_args[]"),
7071
(Ptr void, Var "_env")]
7172
(Seq $
73+
dtraceClosureEntry argNames :
7274
extractArguments params ++
7375
extractEnvironment envName freeVars fTypeVars ++
74-
[bodyStat, returnStmnt bodyName resultType])]
76+
[bodyStat
77+
,dtraceClosureExit
78+
,returnStmnt bodyName resultType])]
7579
| otherwise =
7680
error
7781
"Tried to translate a closure from something that was not a closure"
@@ -118,8 +122,7 @@ translateClosure closure typeVars table
118122
ctxArg = Var "_ctx_arg"
119123
body = Seq $
120124
Assign (Decl (Ptr (Ptr encoreCtxT), encoreCtxVar)) (Amp ctxArg) :
121-
Assign (Decl (Ptr $ Struct envName, Var "_this")) (Var "p") :
125+
Assign (Decl (Ptr $ Struct envName, thisVar)) (Var "p") :
122126
map traceMember members
123127
traceMember (name, ty) = traceVariable ty $ getVar name
124-
getVar name =
125-
(Var "_this") `Arrow` fieldName name
128+
getVar name = thisVar `Arrow` fieldName name

src/back/CodeGen/DTrace.hs

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
module CodeGen.DTrace where
2+
3+
import CCode.Main
4+
import CCode.PrettyCCode
5+
import Identifiers as ID
6+
import Data.List
7+
import Text.Printf
8+
9+
dtrace :: String -> [String] -> CCode Stat
10+
dtrace probe [] =
11+
Embed $ printf "ENC_DTRACE0(%s)" probe
12+
dtrace probe args =
13+
let n = length args
14+
in
15+
Embed $ printf "ENC_DTRACE%d(%s, %s)"
16+
n probe (intercalate ", " args)
17+
18+
-- TODO: Args not used; can't use variable size of arguments
19+
20+
dtraceFieldAccess :: CCode Lval -> ID.Name -> CCode Stat
21+
dtraceFieldAccess target name =
22+
dtrace "FIELD_ACCESS" ["(uintptr_t)*_ctx", "(uintptr_t)" ++ pp target, show $ show name]
23+
24+
dtraceFieldWrite :: CCode Lval -> ID.Name -> CCode Stat
25+
dtraceFieldWrite target name =
26+
dtrace "FIELD_WRITE" ["(uintptr_t)*_ctx", "(uintptr_t)" ++ pp target, show $ show name]
27+
28+
dtraceMethodCall :: CCode Lval -> ID.Name -> [CCode Lval] -> CCode Stat
29+
dtraceMethodCall target name args =
30+
dtrace "METHOD_CALL" $ ["(uintptr_t)*_ctx", "(uintptr_t)" ++ pp target, show $ show name] -- ++ map pp args
31+
32+
dtraceMethodEntry :: CCode Lval -> ID.Name -> [CCode Lval] -> CCode Stat
33+
dtraceMethodEntry this name args =
34+
dtrace "METHOD_ENTRY" $ ["(uintptr_t)*_ctx", "(uintptr_t)" ++ pp this, show $ show name] -- ++ map pp args
35+
36+
dtraceMethodExit :: CCode Lval -> ID.Name -> CCode Stat
37+
dtraceMethodExit this name =
38+
dtrace "METHOD_EXIT" ["(uintptr_t)*_ctx", "(uintptr_t)" ++ pp this, show $ show name]
39+
40+
dtraceFunctionCall :: ID.QualifiedName -> [CCode Lval] -> CCode Stat
41+
dtraceFunctionCall name args =
42+
dtrace "FUNCTION_CALL" $ ["(uintptr_t)*_ctx", show $ show name ] -- : map pp args
43+
44+
dtraceFunctionEntry :: ID.Name -> [CCode Lval] -> CCode Stat
45+
dtraceFunctionEntry name args =
46+
dtrace "FUNCTION_ENTRY" ["(uintptr_t)*_ctx", show $ show name] -- : map pp args
47+
48+
dtraceFunctionExit :: ID.Name -> CCode Stat
49+
dtraceFunctionExit name =
50+
dtrace "FUNCTION_EXIT" ["(uintptr_t)*_ctx", show $ show name]
51+
52+
dtraceClosureCall :: ID.QualifiedName -> [CCode Lval] -> CCode Stat
53+
dtraceClosureCall name args =
54+
dtrace "CLOSURE_CALL" ["(uintptr_t)*_ctx", show $ show name] -- : map pp args
55+
56+
dtraceClosureEntry :: [CCode Lval] -> CCode Stat
57+
dtraceClosureEntry args =
58+
dtrace "CLOSURE_ENTRY" ["(uintptr_t)*_ctx"] -- $ map pp args
59+
60+
dtraceClosureExit :: CCode Stat
61+
dtraceClosureExit = dtrace "CLOSURE_EXIT" ["(uintptr_t)*_ctx"]

0 commit comments

Comments
 (0)