Title: Minding the Gap Between Slicing and Refactoring (or
1Minding the GapBetween Slicing and
Refactoring(or Fine Slicing A new slicing
technique to yield slices whose complements are
slices too)
- Ran Ettinger, IBM Haifa Research Lab
- CREST Open Workshop, Kings College, London
- 28 April 2010
- Joint work with Aharon Abadi and Yishai Feldman
2The gap is in the complement
- Both techniques care for syntax and semantics
preservation, but - Syntactically
- Slicing is about program decomposition
- Refactoring is about program recomposition
- Semantically
- Slicing preserves a subset of the original
behavior - Refactoring is expected to preserve the full
behavior (or functionality) - Is the meaning of extract the same?
3Slice-Extraction Refactoring
- Make a slice of code reusable
- Not merely copying and pasting it
- Update the original code too, like in the
Extract Method refactoring - Turn a non-contiguous slice into a contiguous
fragment of code, before applying Extract
Method - Rearrange the rest of the code
- Prepare parameters
- Use slice results
- Hide unwanted side-effects
- Compute further results
- A kind of defragmentation
4TCP Example
- Taken from recent work on automatic recovery of
state diagrams from procedural code Moria Abadi
and Yishai Feldman, PLDE10 - Recovery algorithm requires all state changes
from a given state to occur in a single procedure - Precede recovery with refactoring when this is
not the case - Isolate state-changing code in called procedures
and move it all to a single procedure - Code example from Comer et al. 2004
5Is this a correct isolation step?
- int tcpclosing(Tcb ptcb, Ep pep)
- ...
- result tcbdealloc(ptcb) ...
-
- int tcbdealloc(Tcb ptcb)
- if (ptcb.tcb_state TCPS_FREE)
- return OK
- switch (ptcb.tcb_type)
- case TCPT_CONNECTION
- tcpkilltimers(ptcb)
- sdelete(ptcb.tcb_ocsem)
- sdelete(ptcb.tcb_ssema)
- sdelete(ptcb.tcb_rsema)
- freemem(ptcb.tcb_sndbuf, ptcb.tcb_sbsize)
- freemem(ptcb.tcb_rcvbuf, ptcb.tcb_rbsize)
- if (ptcb.tcb_rsegq gt 0)
int tcpclosing(Tcb ptcb, Ep pep) ... if
(ptcb.tcb_type TCPT_CONNECTION
ptcb.tcb_type TCPT_SERVER)) ptcb.tcb_state
TCPS_FREE result tcbdealloc(ptcb)
... int tcbdealloc(Tcb ptcb) if
(ptcb.tcb_state TCPS_FREE) return OK
switch (ptcb.tcb_type) case TCPT_CONNECTION
tcpkilltimers(ptcb) sdelete(ptcb.tcb_ocsem
) sdelete(ptcb.tcb_ssema)
sdelete(ptcb.tcb_rsema) freemem(ptcb.tcb_sndb
uf, ptcb.tcb_sbsize) freemem(ptcb.tcb_rcvbuf,
ptcb.tcb_rbsize) if (ptcb.tcb_rsegq gt 0)
freeq(ptcb.tcb_rsegq) break case
TCPT_SERVER pdelete(ptcb.tcb_listenq, 0)
break default signal(ptcb.tcb_mutex)
return SYSERR sdelete(ptcb.tcb_mutex)
return OK
6A new slicing technique to assist in automated
extraction
- Informally, a traditional (backward) slice of a
given program with respect to selected
interesting variables is a subprogram that
computes the same values as the original program
for the selected variables - Accordingly, a (backward) fine slice of a given
program with respect to selected interesting
variables and other oracle variables is a
subprogram that computes the same values as the
original program for the selected variables,
given values for the oracle variables
7Fine Slicing
- A generalization of traditional program slicing
- Fine slices can be precisely bounded
- Slicing criteria include set of data and control
dependences to ignore - Fine slices are executable and extractable
- Oracle-based semantics for fine slices
- Algorithm for computing data-structure
representing the oracle - Forward fine slices are executable
- Might be larger than traditional forward slices
8Extract Computation
- A new refactoring
- Extracts a fine slice into contiguous code
- Computes the co-slice
- Computation can then be extracted into a separate
method using Extract Method - Passes necessary oracle variables between slice
and co-slice - Generates new containers if series of values need
to be passed
9A Case Study inEnterprise Refactoring WRT08-09
- Converted a Java Servlet to use the MVC pattern,
using a series of small refactoring steps - Inadequate automation for most steps
- Most significant deficit in Extract Method
- Extract multiple fragments
- Extract a partial fragment
- Extract loop with partial body
- Extract code with conditional exits
- All 4 cases involve the extraction of fine slices
- Based on Alex Chaffee, Refactoring to
Model-View-Controller (http//www.purpletech.com/
articles/mvc/refactoring-to-mvc.html)
10(a) Extract multiple fragments
User user getCurrentUser(request) if (user
null) response.sendRedirect(LOGIN_PAGE_URL)
return response.setContentType("text/html")
disableCache(response) String albumName
request.getParameter("album") PrintWriter out
response.getWriter()
11(b) Extract a partial fragment
out.println(DOCTYPE_HTML) out.println("lthtmlgt")
out.println("ltheadgt") out.println("lttitlegtErrorlt/
titlegt") out.println("lt/headgt") out.print("ltbody
gtltp class'error'gt") out.print("Could not load
album '" albumName
"'") out.println("lt/pgtlt/bodygt") out.println("lt/h
tmlgt")
12(c) Extract loop with partial body
1 2 3 4 5 6 7 8 9 10
out.println("lttable border0gt") int start page
20 int end start 20 end Math.min(end,
album.getPictures().size()) for
(int i start i lt end i) Picture picture
album.getPicture(i) printPicture(out,
picture) out.println("lt/tablegt")
132 3 4 5 6 7 9 1 6 8 10
int start page 20 int end start 20 end
Math.min(end, album.getPictures()
.size()) QueueltPicturegt pictures
new LinkedListltPicturegt() for (int i start i
lt end i) Picture picture
album.getPicture(i) pictures.add(picture) ou
t.println("lttable border0gt") for (int i
start i lt end i) printPicture(out,
pictures.remove()) out.println("lt/tablegt")
14(d) Extract code with conditional exits
if (album null) new ErrorPage("Could not
load album '" album.getName()
"'").printMessage(out) return //...
15 if (invalidAlbum(album, out)) return
//... boolean invalidAlbum(Album album,
PrintWriter out) boolean invalid
album null if (invalid) new
ErrorPage("Could not load album '"
album.getName() "'").printMessage(out)
return invalid
16Token Semantics
"lttable border0gt"
out
out.println("lttable border0gt") int start page
20 int end start 20 end Math.min(end,
album.getPictures().size()) for
(int i start i lt end i) Picture picture
album.getPicture(i) printPicture(out,
picture) out.println("lt/tablegt")
println
page
20
start
out
album
out
getPictures
i
size
end
min
getPicture
p1
p2
end
"lt/tablegt"
i
out
out
p1
p2
lt
println
printPicture
T
F
exit
17Fine Slicing
"lttable border0gt"
out
out.println("lttable border0gt") int start page
20 int end start 20 end Math.min(end,
album.getPictures().size()) for
(int i start i lt end i) Picture picture
album.getPicture(i) printPicture(out,
picture) out.println("lt/tablegt")
println
page
20
start
out
album
out
getPictures
i
size
end
min
getPicture
end
"lt/tablegt"
i
out
out
lt
println
printPicture
T
F
exit
18The Fine Slice
entry
"lttable border0gt"
out.println("lttable border0gt") for (int i
start i lt end i) printPicture(out,
picture) out.println("lt/tablegt")
out
println
out
end
start
picture
out
i
"lt/tablegt"
i
out
out
lt
println
printPicture
T
F
exit
19Co-Slicing
entry
"lttable border0gt"
out
out.println("lttable border0gt") int start page
20 int end start 20 end Math.min(end,
album.getPictures().size()) for
(int i start i lt end i) Picture picture
album.getPicture(i) printPicture(out,
picture) out.println("lt/tablegt")
println
page
20
start
out
album
out
getPictures
i
size
end
min
getPicture
end
"lt/tablegt"
i
out
out
lt
println
printPicture
T
F
exit
20The Co-Slice
entry
out.println("lttable border0gt") int start page
20 int end start 20 end Math.min(end,
album.getPictures().size()) for
(int i start i lt end i) Picture picture
album.getPicture(i)
page
20
start
album
getPictures
i
size
end
min
getPicture
i
start
picture
lt
out
end
T
F
exit
21Co-slice
entry
Fine slice
page
entry
20
"lttable border0gt"
out
start
println
album
end
start
picture
getPictures
i
end
size
min
getPicture
start
picture
i
i
out
lt
"lt/tablegt"
lt
end
out
T
F
println
T
F
out
exit
exit
22Adding a Container
out.println("lttable border0gt") int start page
20 int end start 20 end Math.min(end,
album.getPictures().size()) QueueltPi
cturegt pictures new LinkedListltPicturegt() for
(int i start i lt end i) Picture picture
album.getPicture(i) pictures.add(picture)
printPicture(out,pictures.remove()) out.pri
ntln("lt/tablegt")
"lttable border0gt"
out
println
println
page
20
start
out
album
out
getPictures
i
pictures
size
end
min
getPicture
new
pictures
picture
add
pictures
end
pictures
"lt/tablegt"
i
out
out
remove
remove
picture
lt
lt
println
println
printPicture
printPicture
T
F
exit
23The Fine Slice
void display(PrintStream out, int start, int
end, QueueltPicturegt pictures)
out.println("lttable border0gt") for (int i
start i lt end i) printPicture(out,
pictures.remove()) out.println("lt/tablegt")
entry
entry
"lttable border0gt"
out
println
println
end
start
pictures
out
out
i
pictures
pictures
"lt/tablegt"
i
out
out
remove
remove
picture
lt
lt
println
println
printPicture
printPicture
T
F
exit
24Program with Container
out.println("lttable border0gt") int start page
20 int end start 20 end Math.min(end,
album.getPictures().size()) QueueltPi
cturegt pictures new LinkedListltPicturegt() for
(int i start i lt end i) Picture picture
album.getPicture(i) pictures.add(picture)
printPicture(out,pictures.remove()) out.pri
ntln("lt/tablegt")
entry
"lttable border0gt"
out
println
println
page
20
start
out
album
out
getPictures
i
pictures
size
end
min
getPicture
new
pictures
picture
add
pictures
end
pictures
"lt/tablegt"
i
out
out
remove
remove
picture
lt
lt
println
println
printPicture
printPicture
T
F
exit
25The Co-Slice
int start page 20 int end start 20 end
Math.min(end, album.getPictures()
.size()) QueueltPicturegt pictures new
LinkedListltPicturegt() for (int i start i lt
end i) Picture picture
album.getPicture(i) pictures.add(picture)
display(out,start,end, pictures)
out
page
20
start
album
getPictures
start
i
pictures
size
end
min
getPicture
new
pictures
pictures
picture
end
add
pictures
pictures
i
i
lt
lt
display
out
T
F
exit
26Revisiting the TCP Example
- int tcbdealloc(Tcb ptcb)
- if (ptcb.tcb_state TCPS_FREE)
- return OK
- switch (ptcb.tcb_type)
- case TCPT_CONNECTION
- tcpkilltimers(ptcb)
- sdelete(ptcb.tcb_ocsem)
- sdelete(ptcb.tcb_ssema)
- sdelete(ptcb.tcb_rsema)
- freemem(ptcb.tcb_sndbuf, ptcb.tcb_sbsize)
- freemem(ptcb.tcb_rcvbuf, ptcb.tcb_rbsize)
- if (ptcb.tcb_rsegq gt 0)
- freeq(ptcb.tcb_rsegq)
- break
- case TCPT_SERVER
- pdelete(ptcb.tcb_listenq, 0)
- break
- default
- signal(ptcb.tcb_mutex)
27Slicing Unstructured Code FSE09
- A plan-based slicing algorithm in two main stages
- Compute initial slice by following all control
and data dependences - Complete the slice by identifying required
control structure - Lemma Let P be a surface plan, and let Q be a
slice computed from P. If (p,q) is a control edge
in Q, then every path from p to the exit in the
source program P passes through q without passing
through any other port of Q before it. - Theorem It is always possible to add to the
slice a control path consisting of branches from
the original program for every control edge in
the plan. Regardless of which paths are chosen,
two points in the resulting slice have a control
path between them iff they are connected by a
control path in the original program that does
not go through any other point in the slice. - Proof for flat languages, with conditional and
unconditional branch statements - Precisely identifies the possible sets of
branches (gotos, jumps) that may be added to the
slice - Any path in the original program can be chosen
- Optimizations can be performed
p
q
28Control Flow Graph of Initial Slice
Entry
- int tcbdealloc(Tcb ptcb)
- if (ptcb.tcb_state TCPS_FREE)
- return OK
- switch (ptcb.tcb_type)
- case TCPT_CONNECTION
- tcpkilltimers(ptcb)
- sdelete(ptcb.tcb_ocsem)
- sdelete(ptcb.tcb_ssema)
- sdelete(ptcb.tcb_rsema)
- freemem(ptcb.tcb_sndbuf, ptcb.tcb_sbsize)
- freemem(ptcb.tcb_rcvbuf, ptcb.tcb_rbsize)
- if (ptcb.tcb_rsegq gt 0)
- freeq(ptcb.tcb_rsegq)
- break
- case TCPT_SERVER
- pdelete(ptcb.tcb_listenq, 0)
- break
- default
- signal(ptcb.tcb_mutex)
Exit
29Adding relevant branches (a)
Entry
- int tcbdealloc(Tcb ptcb)
- if (ptcb.tcb_state TCPS_FREE)
- return OK
- switch (ptcb.tcb_type)
- case TCPT_CONNECTION
- tcpkilltimers(ptcb)
- sdelete(ptcb.tcb_ocsem)
- sdelete(ptcb.tcb_ssema)
- sdelete(ptcb.tcb_rsema)
- freemem(ptcb.tcb_sndbuf, ptcb.tcb_sbsize)
- freemem(ptcb.tcb_rcvbuf, ptcb.tcb_rbsize)
- if (ptcb.tcb_rsegq gt 0)
- freeq(ptcb.tcb_rsegq)
- break
- case TCPT_SERVER
- pdelete(ptcb.tcb_listenq, 0)
- break
- default
- signal(ptcb.tcb_mutex)
Exit
30Adding relevant branches (b)
Entry
- int tcbdealloc(Tcb ptcb)
- if (ptcb.tcb_state TCPS_FREE)
- return OK
- switch (ptcb.tcb_type)
- case TCPT_CONNECTION
- tcpkilltimers(ptcb)
- sdelete(ptcb.tcb_ocsem)
- sdelete(ptcb.tcb_ssema)
- sdelete(ptcb.tcb_rsema)
- freemem(ptcb.tcb_sndbuf, ptcb.tcb_sbsize)
- freemem(ptcb.tcb_rcvbuf, ptcb.tcb_rbsize)
- if (ptcb.tcb_rsegq gt 0)
- freeq(ptcb.tcb_rsegq)
- break
- case TCPT_SERVER
- pdelete(ptcb.tcb_listenq, 0)
- break
- default
- signal(ptcb.tcb_mutex)
Exit
31Adding relevant branches (c)
Entry
- int tcbdealloc(Tcb ptcb)
- if (ptcb.tcb_state TCPS_FREE)
- return OK
- switch (ptcb.tcb_type)
- case TCPT_CONNECTION
- tcpkilltimers(ptcb)
- sdelete(ptcb.tcb_ocsem)
- sdelete(ptcb.tcb_ssema)
- sdelete(ptcb.tcb_rsema)
- freemem(ptcb.tcb_sndbuf, ptcb.tcb_sbsize)
- freemem(ptcb.tcb_rcvbuf, ptcb.tcb_rbsize)
- if (ptcb.tcb_rsegq gt 0)
- freeq(ptcb.tcb_rsegq)
- break
- case TCPT_SERVER
- pdelete(ptcb.tcb_listenq, 0)
- break
- default
- signal(ptcb.tcb_mutex)
Exit
32Adding relevant branches (d)
Entry
- int tcbdealloc(Tcb ptcb)
- if (ptcb.tcb_state TCPS_FREE)
- return OK
- switch (ptcb.tcb_type)
- case TCPT_CONNECTION
- tcpkilltimers(ptcb)
- sdelete(ptcb.tcb_ocsem)
- sdelete(ptcb.tcb_ssema)
- sdelete(ptcb.tcb_rsema)
- freemem(ptcb.tcb_sndbuf, ptcb.tcb_sbsize)
- freemem(ptcb.tcb_rcvbuf, ptcb.tcb_rbsize)
- if (ptcb.tcb_rsegq gt 0)
- freeq(ptcb.tcb_rsegq)
- break
- case TCPT_SERVER
- pdelete(ptcb.tcb_listenq, 0)
- break
- default
- signal(ptcb.tcb_mutex)
Exit
33Adding relevant branches (e)
Entry
- int tcbdealloc(Tcb ptcb)
- if (ptcb.tcb_state TCPS_FREE)
- return OK
- switch (ptcb.tcb_type)
- case TCPT_CONNECTION
- tcpkilltimers(ptcb)
- sdelete(ptcb.tcb_ocsem)
- sdelete(ptcb.tcb_ssema)
- sdelete(ptcb.tcb_rsema)
- freemem(ptcb.tcb_sndbuf, ptcb.tcb_sbsize)
- freemem(ptcb.tcb_rcvbuf, ptcb.tcb_rbsize)
- if (ptcb.tcb_rsegq gt 0)
- freeq(ptcb.tcb_rsegq)
- break
- case TCPT_SERVER
- pdelete(ptcb.tcb_listenq, 0)
- break
- default
- signal(ptcb.tcb_mutex)
Exit
34Complete Slice
- int tcbdealloc(Tcb ptcb)
- if (ptcb.tcb_state TCPS_FREE)
- return OK
- switch (ptcb.tcb_type)
- case TCPT_CONNECTION
- tcpkilltimers(ptcb)
- sdelete(ptcb.tcb_ocsem)
- sdelete(ptcb.tcb_ssema)
- sdelete(ptcb.tcb_rsema)
- freemem(ptcb.tcb_sndbuf, ptcb.tcb_sbsize)
- freemem(ptcb.tcb_rcvbuf, ptcb.tcb_rbsize)
- if (ptcb.tcb_rsegq gt 0)
- freeq(ptcb.tcb_rsegq)
- break
- case TCPT_SERVER
- pdelete(ptcb.tcb_listenq, 0)
- break
- default
- signal(ptcb.tcb_mutex)
35Isolated State-Changing Code
- int tcbdealloc(Tcb ptcb)
- int old_tcb_state ptcb.tcb_state
- if (ptcb.tcb_state TCPS_FREE)
- goto L1
- switch (ptcb.tcb_type)
- case TCPT_CONNECTION
- break
- case TCPT_SERVER
- break
- default
- goto L1
-
- ptcb.tcb_state TCPS_FREE
- L1
- int new_tcb_state ptcb.tcb_state
- int result
- ptcb.tcb_state old_tcb_state
- if (ptcb.tcb_state TCPS_FREE)
- result OK
switch (ptcb.tcb_type) case
TCPT_CONNECTION tcpkilltimers(ptcb)
sdelete(ptcb.tcb_ocsem) sdelete(ptcb.tcb_ssem
a) sdelete(ptcb.tcb_rsema)
freemem(ptcb.tcb_sndbuf, ptcb.tcb_sbsize)
freemem(ptcb.tcb_rcvbuf, ptcb.tcb_rbsize) if
(ptcb.tcb_rsegq gt 0) freeq(ptcb.tcb_rsegq)
break case TCPT_SERVER
pdelete(ptcb.tcb_listenq, 0) break
default signal(ptcb.tcb_mutex) result
SYSERR goto L2 sdelete(ptcb.tcb_mutex)
result OK L2 ptcb.tcb_state
new_tcb_state return result
36Related Work (I) (Non-)Executable Slices
- A wide range of slicing techniques which yield a
non-executable collection of program statements - Traditional backward slicing (e.g., Weiser,
ICSE81 or OttensteinOttenstein, PSDE84), when
applied to unstructured code - Solved by a designated stage in plan-based
slicing (Abadi, Ettinger Feldman, FSE09) - Forward slicing (Horwitz, Reps Binkley,
TOPLAS90) - Barrier slicing (Krinke, SCAM03)
- Chopping (Jackson Rollins, FSE94) and Barrier
Chopping (Krinke, SCAM03) - Thin slicing (Sridharan, Fink Bodik, PLDI07)
- Hypothesis All the above can be made executable
with an appropriate oracle, by adding the
required control structure - An executable slice is a program in itself, one
that preserves the original program's behavior
with respect to a given slicing criterion
37Related Work (II) Executable Slices with Reduced
Scope or Size
- Other techniques for limiting the scope of
slicing, for getting smaller and more focused
slices - Block-based slicing (Maruyama, SSR01) structured
code only, no correctness proof - Co-slicing (my thesis, 2006) limited to slicing
from the end and oracle of final values only
proof on toy language - Parametric slicing (Field, Ramalingam Tip,
POPL95) their constrained slices are an
executable generalization of static and dynamic
slices like oracle semantics, they formalize
programs with holes however, their hole stand
for an expression whose value is irrelevant,
while our hole stand for a significant (oracle)
value to be sent as a parameter - Some forms of dynamic and forward slicing are
executable (Venkatesh, PLDI91 Binkley et al,.
SCAM04) forward slices made excessively large
through the addition of backward slices
38Related Work (III) Behavior Preserving Procedure
Extraction
- Contiguous code
- Bill Opdyke's thesis (UIUC, 92) for C
- GriswoldNotkin (ToSE93) for Scheme
- Arbitrary selections of (not necessarily
contiguous) statements - Tucking (LakhotiaDeprez, IST98) the complement
is a slice too (from all non-extracted points no
dataflow from the extracted slice to its
complement yields over-duplication strong
preconditions (e.g., no global variables involved
and no live-on-exit variable defined on both the
slice and complement - Semantics-Preserving Procedure Extraction
(KomondoorHorwitz, POPL00) considers all
permutations of selected and surrounding
statements no duplication allowed not practical
(exponential time complexity) - Effective Automatic Procedure Extraction
(KomondoorHorwitz, IWPC03) improves on their
POPL00 algorithm by being more practical (cubic
time and space), allowing some duplication (of
conditionals and jumps) might miss some correct
permutations though no duplication of
assignments or loops allows dataflow from
complementary to extracted code and from
extracted code to (a second portion of)
complementary code supports exiting jumps - Extraction of block-based slices (Maruyama,
SSR01) extracts a slice of one variable only
restricted to structured code no proof given - My thesis (Sliding, 2006) sliding
transformation, sequentially composes a slice and
its complement, allowing dataflow from the former
to the latter supports loop untangling and
duplication of assignments but restricted to
slicing from the end, and only final values from
the extracted slice can be reused in the
complement proof for toy language
39Conclusion
- Fine slicing is a generalization of program
slicing - It can be used to compute meaningful sub-programs
- For extraction, in automated refactoring tools
- For program understanding too
- Can be used to compute the complementary code
required for correct refactoring - This work is part of a long-term research project
focusing on advanced enterprise refactoring
tools, aiming to assist in daily software
development on the one hand and in legacy
modernization on the other - The new Extract Computation refactoring for
isolating fine slices is a crucial building block
in this endeavor - It will be used to enhance the automation for
complex code-motion refactorings in order to
support enterprise transformations such as the
move to MVC WRT08-09 - As our prototype matures, it will be possible to
evaluate to what extent such enterprise
transformations can be automated - Present and future work
- Interprocedural fine slicing
- Support for aliasing
- Support interprocedural transformations
- Automate a wide range of known refactorings,
based on fine slicing and Extract Computation
40References
- Abadi, Ettinger, and Feldman, WRT08
Re-approaching the refactoring rubicon. Workshop
on Refactoring Tools _at_ OOPSLA08. - Abadi, Ettinger, and Feldman, WRT09 Fine slicing
for advanced method extraction. Workshop on
Refactoring Tools _at_ OOPSLA09. - Abadi, Ettinger, and Feldman, FSE09 Improving
slice accuracy by compression of data and control
flow paths. - M. AbadiFeldman, PLDE10 Refactoring in multiple
representations code and statecharts. - Field, Ramalingam Tip, POPL95 Parametric
program slicing. - GriswoldNotkin, ToSE93 Automated assistance for
program restructuring. - Horwitz, Reps Binkley, TOPLAS90
Interprocedural slicing using dependence gaphs. - JacksonRollins, FSE94 A new model of program
dependences for reverse engineering. - KomondoorHorwitz, POPL00 Semantics-preserving
procedure extraction. - Komondoor and Horwitz, IWPC03 Effective
automatic procedure extraction. - Krinke, SCAM03 Barrier slicing and chopping.
- Krinke et al., SCAM04 Formalizing executable
dynamic and forward slicing. - LakhotiaDeprez, IST98 Restructuring programs by
tucking statements into functions. - Maruyama, SSR01 Automated method-extraction
refactoring by using block-based slicing - My thesis, 2006 Refactoring via program slicing
and sliding. - Opdykes PhD thesis, UIUC92 Refactoring
Object-Oriented Frameworks. - Sridharan, Fink Bodik, PLDI07 Thin slicing.
- Venkatesh, PLDI91 The semantic approach to
program slicing.