VLDB 2026 Research / reviewers in the wild / expert
Yannis Smaragdakis
dblp:s/YSmaragdakis
· DBLP profile ↗
101ranked-venue papers
23as first author
4since 2021 · last 2025
0000-0002-0499-0182ORCID · verified
Domains — the database's venue-derived domains; a paper can count in several
Software engineering, systems software and programming languages · 93 · 21 first-author · 4 since 2021Systems, architecture and hardware · 10 · 3 first-authorArtificial intelligence and machine learning · 1Theory of computation · 1 · 1 first-authorApplied, interdisciplinary, general and emerging computing · 1
| Year | Publication | Venue | Position |
|---|---|---|---|
| 2025 | Universal Scalability in Declarative Program Analysis (with Choice-Based Combination Pruning)abstractDatalog engines for fixpoint evaluation have brought great benefits to static program analysis over the past decades. A Datalog specification of an analysis allows a declarative, easy-to-maintain specification, without sacrificing performance, and indeed often achieving significant speedups compared to hand-coded algorithms. However, these benefits come with a certain loss of control. Datalog evaluation is bottom-up, meaning that all inferences (from a set of initial facts) are performed and all their conclusions are outputs of the computation. In practice, virtually every program analysis expressed in Datalog becomes unscalable for some inputs, due to the worst-case blowup of computing all results, even when a partial answer would have been perfectly satisfactory. In this work, we present a simple, uniform, and elegant solution to the problem, with great practical effectiveness and application to virtually any Datalog-based analysis. The approach consists of leveraging the choice construct, supported natively in modern Datalog engines like Soufflé. The choice construct allows the definition of functional dependencies in a relation and has been used in the past for expressing worklist algorithms. We show a near-universal construction that allows the choice construct to flexibly limit evaluation of predicates. The technique is applicable to practically any analysis architecture imaginable, since it adaptively prunes evaluation results when a (programmer-controlled) projection of a relation exceeds a desired cardinality. We apply the technique to probably the largest, pre-existing Datalog analysis frameworks in existence: Doop (for Java bytecode) and the main client analyses from the Gigahorse framework (for Ethereum smart contracts). Without needing to understand the existing analysis logic and with minimal, local-only changes, the performance of each framework increases dramatically, by over 20x for the hardest inputs, with near-negligible sacrifice in completeness. Anastasios Antoniadis, Ilias Tsatiris, Neville Grech, Yannis Smaragdakis |
Proc. ACM Program. Lang. | 4 |
| 2022 | Elipmoc: advanced decompilation of Ethereum smart contractsabstractSmart contracts on the Ethereum blockchain greatly benefit from cutting-edge analysis techniques and pose significant challenges. A primary challenge is the extremely low-level representation of deployed contracts. We present Elipmoc, a decompiler for the next generation of smart contract analyses. Elipmoc is an evolution of Gigahorse, the top research decompiler, dramatically improving over it and over other state-of-the-art tools, by employing several high-precision techniques and making them scalable. Among these techniques are a new kind of context sensitivity (termed “transactional sensitivity”) that provides a more effective static abstraction of distinct dynamic executions; a path-sensitive (yet scalable, through path merging) algorithm for inference of function arguments and returns; and a fully context sensitive private function reconstruction process. As a result, smart contract security analyses and reverse-engineering tools built on top of Elipmoc achieve high scalability, precision and completeness. Elipmoc improves over all notable past decompilers, including its predecessor, Gigahorse, and the state-of-the-art industrial tool, Panoramix, integrated into the primary Ethereum blockchain explorer, Etherscan. Elipmoc produces decompiled contracts with fully resolved operands at a rate of 99.5% (compared to 62.8% for Gigahorse), and achieves much higher completeness in code decompilation than Panoramix—e.g., up to 67% more coverage of external call statements—while being over 5x faster. Elipmoc has been the enabler for recent (independent) discoveries of several exploitable vulnerabilities on popular protocols, over funds in the many millions of dollars. Neville Grech, Sifis Lagouvardos, Ilias Tsatiris, Yannis Smaragdakis |
Proc. ACM Program. Lang. | 4 |
| 2021 | Symbolic value-flow static analysis: deep, precise, complete modeling of Ethereum smart contractsabstractWe present a static analysis approach that combines concrete values and symbolic expressions. This symbolic value-flow (“symvalic”) analysis models program behavior with high precision, e.g., full path sensitivity. To achieve deep modeling of program semantics, the analysis relies on a symbiotic relationship between a traditional static analysis fixpoint computation and a symbolic solver: the solver does not merely receive a complex “path condition” to solve, but is instead invoked repeatedly (often tens or hundreds of thousands of times), in close cooperation with the flow computation of the analysis. The result of the symvalic analysis architecture is a static modeling of program behavior that is much more complete than symbolic execution, much more precise than conventional static analysis, and domain-agnostic: no special-purpose definition of anti-patterns is necessary in order to compute violations of safety conditions with high precision. We apply the analysis to the domain of Ethereum smart contracts. This domain represents a fundamental challenge for program analysis approaches: despite numerous publications, research work has not been effective at uncovering vulnerabilities of high real-world value. In systematic comparison of symvalic analysis with past tools, we find significantly increased completeness (shown as 83-96% statement coverage and more true error reports) combined with much higher precision, as measured by rate of true positive reports. In terms of real-world impact, since the beginning of 2021, the analysis has resulted in the discovery and disclosure of several critical vulnerabilities, over funds in the many millions of dollars. Six separate bug bounties totaling over $350K have been awarded for these disclosures. Yannis Smaragdakis, Neville Grech, Sifis Lagouvardos, Konstantinos Triantafyllou, Ilias Tsatiris |
Proc. ACM Program. Lang. | 1 |
| 2021 | Making pointer analysis more precise by unleashing the power of selective context sensitivityabstractTraditional context-sensitive pointer analysis is hard to scale for large and complex Java programs. To address this issue, a series of selective context-sensitivity approaches have been proposed and exhibit promising results. In this work, we move one step further towards producing highly-precise pointer analyses for hard-to-analyze Java programs by presenting the Unity-Relay framework, which takes selective context sensitivity to the next level. Briefly, Unity-Relay is a one-two punch: given a set of different selective context-sensitivity approaches, say S = S1, . . . , Sn, Unity-Relay first provides a mechanism (called Unity)to combine and maximize the precision of all components of S. When Unity fails to scale, Unity-Relay offers a scheme (called Relay) to pass and accumulate the precision from one approach Si in S to the next, Si+1, leading to an analysis that is more precise than all approaches in S. As a proof-of-concept, we instantiate Unity-Relay into a tool called Baton and extensively evaluate it on a set of hard-to-analyze Java programs, using general precision metrics and popular clients. Compared with the state of the art, Baton achieves the best precision for all metrics and clients for all evaluated programs. The difference in precision is often dramatic — up to 71% of alias pairs reported by previously-best algorithms are found to be spurious and eliminated. Tian Tan 0001, Yue Li 0006, Xiaoxing Ma, Chang Xu 0001, Yannis Smaragdakis |
Proc. ACM Program. Lang. | 5 |
| 2020 | Static Analysis of Shape in TensorFlow ProgramsabstractMachine learning has been widely adopted in diverse science and engineering domains, aided by reusable libraries and quick development patterns. The TensorFlow library is probably the best-known representative of this trend and most users employ the Python API to its powerful back-end. TensorFlow programs are susceptible to several systematic errors, especially in the dynamic typing setting of Python. We present Pythia, a static analysis that tracks the shapes of tensors across Python library calls and warns of several possible mismatches. The key technical aspects are a close modeling of library semantics with respect to tensor shape, and an identification of violations and error-prone patterns. Pythia is powerful enough to statically detect (with 84.62% precision) 11 of the 14 shape-related TensorFlow bugs in the recent Zhang et al. empirical study - an independent slice of real-world bugs. Sifis Lagouvardos, Julian Dolby, Neville Grech, Anastasios Antoniadis, Yannis Smaragdakis |
ECOOP | 5 |
| 2020 | Identifying Java calls in native code via binary scanningabstractCurrent Java static analyzers, operating either on the source or bytecode level, exhibit unsoundness for programs that contain native code. We show that the Java Native Interface (JNI) specification, which is used by Java programs to interoperate with Java code, is principled enough to permit static reasoning about the effects of native code on program execution when it comes to call-backs. Our approach consists of disassembling native binaries, recovering static symbol information that corresponds to Java method signatures, and producing a model for statically exercising these native call-backs with appropriate mock objects. The approach manages to recover virtually all Java calls in native code, for both Android and Java desktop applications—(a) achieving 100% native-to-application call-graph recall on large Android applications (Chrome, Instagram) and (b) capturing the full native call-back behavior of the XCorpus suite programs. Georgios Fourtounis 0001, Leonidas Triantafyllou, Yannis Smaragdakis |
ISSTA | 3 |
| 2020 | Static analysis of Java enterprise applications: frameworks and caches, the elephants in the roomabstractEnterprise applications are a major success domain of Java, and Java is the default setting for much modern static analysis research. It would stand to reason that high-quality static analysis of Java enterprise applications would be commonplace, but this is far from true. Major analysis frameworks feature virtually no support for enterprise applications and offer analyses that are woefully incomplete and vastly imprecise, when at all scalable. Anastasios Antoniadis, Nikos Filippakis, Paddy Krishnan, Raghavendra Ramesh, Nicholas Allen, Yannis Smaragdakis |
PLDI | 6 |
| 2020 | Ethainter: a smart contract security analyzer for composite vulnerabilitiesabstractSmart contracts on permissionless blockchains are exposed to inherent security risks due to interactions with untrusted entities. Static analyzers are essential for identifying security risks and avoiding millions of dollars worth of damage. Lexi Brent, Neville Grech, Sifis Lagouvardos, Bernhard Scholz, Yannis Smaragdakis |
PLDI | 5 |
| 2020 | Precise static modeling of Ethereum "memory"abstractStatic analysis of smart contracts as-deployed on the Ethereum blockchain has received much recent attention. However, high-precision analyses currently face significant challenges when dealing with the Ethereum VM (EVM) execution model. A major such challenge is the modeling of low-level, transient “memory” (as opposed to persistent, on-blockchain “storage”) that smart contracts employ. Statically understanding the usage patterns of memory is non-trivial, due to the dynamic allocation nature of in-memory buffers. We offer an analysis that models EVM memory, recovering high-level concepts (e.g., arrays, buffers, call arguments) via deep modeling of the flow of values. Our analysis opens the door to Ethereum static analyses with drastically increased precision. One such analysis detects the extraction of ERC20 tokens by unauthorized users. For another practical vulnerability (redundant calls, possibly used as an attack vector), our memory modeling yields analysis precision of 89%, compared to 16% for a state-of-the-art tool without precise memory modeling. Additionally, precise memory modeling enables the static computation of a contract’s gas cost. This gas-cost analysis has recently been instrumental in the evaluation of the impact of the EIP-1884 repricing (in terms of gas costs) of EVM operations, leading to a reward and significant publicity from the Ethereum Foundation. Sifis Lagouvardos, Neville Grech, Ilias Tsatiris, Yannis Smaragdakis |
Proc. ACM Program. Lang. | 4 |
| 2020 | A Principled Approach to Selective Context Sensitivity for Pointer AnalysisabstractContext sensitivity is an essential technique for ensuring high precision in static analyses. It has been observed that applying context sensitivity partially, only on a select subset of the methods, can improve the balance between analysis precision and speed. However, existing techniques are based on heuristics that do not provide much insight into what characterizes this method subset. In this work, we present a more principled approach for identifying precision-critical methods, based on general patterns of value flows that explain where most of the imprecision arises in context-insensitive pointer analysis. Using this theoretical foundation, we present an efficient algorithm, Z IPPER , to recognize these flow patterns in a given program and employ context sensitivity accordingly. We also present a variant, Z IPPER e , that additionally takes into account which methods are disproportionally costly to analyze with context sensitivity. Our experimental results on standard benchmark and real-world Java programs show that Z IPPER preserves effectively all of the precision (98.8%) of a highly precise conventional context-sensitive pointer analysis (2-object-sensitive with a context-sensitive heap, 2obj for short), with a substantial speedup (on average, 3.4× and up to 9.4×), and that Z IPPER e preserves 94.7% of the precision of 2obj, with an order-of-magnitude speedup (on average, 25.5× and up to 88×). In addition, for 10 programs that cannot be analyzed by 2obj within a three-hour time limit, on average Z IPPER e can guide 2obj to finish analyzing them in less than 11 minutes with high precision compared to context-insensitive and introspective context-sensitive analyses. Yue Li 0006, Tian Tan 0001, Anders Møller, Yannis Smaragdakis |
ACM Trans. Program. Lang. Syst. | 4 |
| 2019 | Deep Static Modeling of invokedynamicabstractJava 7 introduced programmable dynamic linking in the form of the invokedynamic framework. Static analysis of code containing programmable dynamic linking has often been cited as a significant source of unsoundness in the analysis of Java programs. For example, Java lambdas, introduced in Java 8, are a very popular feature, which is, however, resistant to static analysis, since it mixes invokedynamic with dynamic code generation. These techniques invalidate static analysis assumptions: programmable linking breaks reasoning about method resolution while dynamically generated code is, by definition, not available statically. In this paper, we show that a static analysis can predictively model uses of invokedynamic while also cooperating with extra rules to handle the runtime code generation of lambdas. Our approach plugs into an existing static analysis and helps eliminate all unsoundness in the handling of lambdas (including associated features such as method references) and generic invokedynamic uses. We evaluate our technique on a benchmark suite of our own and on third-party benchmarks, uncovering all code previously unreachable due to unsoundness, highly efficiently. Georgios Fourtounis 0001, Yannis Smaragdakis |
ECOOP | 2 |
| 2019 | Gigahorse: thorough, declarative decompilation of smart contractsabstractThe rise of smart contracts - autonomous applications running on blockchains - has led to a growing number of threats, necessitating sophisticated program analysis. However, smart contracts, which transact valuable tokens and cryptocurrencies, are compiled to very low-level bytecode. This bytecode is the ultimate semantics and means of enforcement of the contract. We present the Gigahorse toolchain. At its core is a reverse compiler (i.e., a decompiler) that decompiles smart contracts from Ethereum Virtual Machine (EVM) bytecode into a highlevel 3-address code representation. The new intermediate representation of smart contracts makes implicit data- and control-flow dependencies of the EVM bytecode explicit. Decompilation obviates the need for a contract's source and allows the analysis of both new and deployed contracts. Gigahorse advances the state of the art on several fronts. It gives the highest analysis precision and completeness among decompilers for Ethereum smart contracts - e.g., Gigahorse can decompile over 99.98% of deployed contracts, compared to 88% for the recently-published Vandal decompiler and under 50% for the state-of-the-practice Porosity decompiler. Importantly, Gigahorse offers a full-featured toolchain for further analyses (and a “batteries included” approach, with multiple clients already implemented), together with the highest performance and scalability. Key to these improvements is Gigahorse's use of a declarative, logic-based specification, which allows high-level insights to inform low-level decompilation. Neville Grech, Lexi Brent, Bernhard Scholz, Yannis Smaragdakis |
ICSE | 4 |
| 2018 | An efficient data structure for must-alias analysisabstractA must-alias (or “definite-alias”) analysis computes sets of expressions that are guaranteed to be aliased at a given pro- gram point. The analysis has been shown to have significant practical impact, and it is actively used in popular research frameworks and commercial tools. We present a custom data structure that speeds up must-alias analysis by nearly two orders of magnitude (while computing identical results). The data structure achieves efficiency by encoding multiple alias sets in a single linked structure, and compactly representing the aliasing relations of arbitrarily long expressions. We ex- plore the data structure’s performance in both an imperative and a declarative setting and contrast it extensively with prior techniques. With our approach, must-alias analysis can be performed efficiently, over large Java benchmarks, in under half a minute, making the analysis cost acceptable for most practical uses. George Kastrinis, George Balatsouras, Kostas Ferles, Nefeli Prokopaki-Kostopoulou, Yannis Smaragdakis |
CC | 5 |
| 2018 | Efficient Reflection String Analysis via Graph ColoringabstractStatic analyses for reflection and other dynamic language features have recently increased in number and advanced in sophistication. Most such analyses rely on a whole-program model of the flow of strings, through the stack and heap. We show that this global modeling of strings remains a major bottleneck of static analyses and propose a compact encoding, in order to battle unnecessary complexity. In our encoding, strings are maximally merged if they can never serve to differentiate class members in reflection operations. We formulate the problem as an instance of graph coloring and propose a fast polynomial-time algorithm that exploits the unique features of the setting (esp. large cliques, leading to hundreds of colors for realistic programs). The encoding is applied to two different frameworks for string-guided Java reflection analysis from past literature and leads to significant optimization (e.g., a ~2x reduction in the number of string-flow inferences), for a whole-program points-to analysis that uses strings. Neville Grech, George Kastrinis, Yannis Smaragdakis |
ECOOP | 3 |
| 2018 | Defensive Points-To Analysis: Effective Soundness via LazinessabstractWe present a defensive may-point-to analysis approach, which offers soundness even in the presence of arbitrary opaque code: all non-empty points-to sets computed are guaranteed to be over-approximations of the sets of values arising at run time. A key design tenet of the analysis is laziness: the analysis computes points-to relationships only for variables or objects that are guaranteed to never escape into opaque code. This means that the analysis misses some valid inferences, yet it also never wastes work to compute sets of values that are not "complete", i.e., that may be missing elements due to opaque code. Laziness enables great efficiency, allowing a highly precise points-to analysis (such as a 5-call-site-sensitive, flow-sensitive analysis). Despite its conservative nature, our analysis yields sound, actionable results for a large subset of the program code, achieving (under worst-case assumptions) 34-74% of the program coverage of an unsound state-of-the-art analysis for real-world programs. Yannis Smaragdakis, George Kastrinis |
ECOOP | 1 |
| 2018 | Static analysis of Java dynamic proxiesabstractThe dynamic proxy API is one of Java’s most widely-used dynamic features, permitting principled run-time code generation and link- ing. Dynamic proxies can implement any set of interfaces and for- ward method calls to a special object that handles them reflectively. The flexibility of dynamic proxies, however, comes at the cost of having a dynamically generated layer of bytecode that cannot be penetrated by current static analyses. In this paper, we observe that the dynamic proxy API is stylized enough to permit static analysis. We show how the semantics of dynamic proxies can be modeled in a straightforward manner as logical rules in the Doop static analysis framework. This concise set of rules enables Doop’s standard analyses to process code behind dynamic proxies. We evaluate our approach by analyzing XCorpus, a corpus of real-world Java programs: we fully handle 95% of its reported proxy creation sites. Our handling results in the analysis of significant portions of previously unreachable or incompletely- modeled code. Georgios Fourtounis 0001, George Kastrinis, Yannis Smaragdakis |
ISSTA | 3 |
| 2018 | Shooting from the heap: ultra-scalable static analysis with heap snapshotsabstractTraditional whole-program static analysis (e.g., a points-to analysis that models the heap) encounters scalability problems for realistic applications. We propose a ``featherweight'' analysis that combines a dynamic snapshot of the heap with otherwise full static analysis of program behavior. Neville Grech, Georgios Fourtounis 0001, Adrian Francalanza, Yannis Smaragdakis |
ISSTA | 4 |
| 2018 | Symbolic reasoning for automatic signal placementabstractExplicit signaling between threads is a perennial cause of bugs in concurrent programs. While there are several run-time techniques to automatically notify threads upon the availability of some shared resource, such techniques are not widely-adopted due to their run-time overhead. This paper proposes a new solution based on static analysis for automatically generating a performant explicit-signal program from its corresponding implicit-signal implementation. The key idea is to generate verification conditions that allow us to minimize the number of required signals and unnecessary context switches, while guaranteeing semantic equivalence between the source and target programs. We have implemented our method in a tool called Expresso and evaluate it on challenging benchmarks from prior papers and open-source software. Expresso-generated code significantly outperforms past automatic signaling mechanisms (avg. 1.56x speedup) and closely matches the performance of hand-optimized explicit-signal code. Kostas Ferles, Jacob Van Geffen, Isil Dillig, Yannis Smaragdakis |
PLDI | 4 |
| 2018 | Scalability-first pointer analysis with self-tuning context-sensitivityabstractContext-sensitivity is important in pointer analysis to ensure high precision, but existing techniques suffer from unpredictable scalability. Many variants of context-sensitivity exist, and it is difficult to choose one that leads to reasonable analysis time and obtains high precision, without running the analysis multiple times. Yue Li 0006, Tian Tan 0001, Anders Møller, Yannis Smaragdakis |
ESEC/SIGSOFT FSE | 4 |
| 2018 | MadMax: surviving out-of-gas conditions in Ethereum smart contractsabstractEthereum is a distributed blockchain platform, serving as an ecosystem for smart contracts: full-fledged inter-communicating programs that capture the transaction logic of an account. Unlike programs in mainstream languages, a gas limit restricts the execution of an Ethereum smart contract: execution proceeds as long as gas is available. Thus, gas is a valuable resource that can be manipulated by an attacker to provoke unwanted behavior in a victim's smart contract (e.g., wasting or blocking funds of said victim). Gas-focused vulnerabilities exploit undesired behavior when a contract (directly or through other interacting contracts) runs out of gas. Such vulnerabilities are among the hardest for programmers to protect against, as out-of-gas behavior may be uncommon in non-attack scenarios and reasoning about it is far from trivial. In this paper, we classify and identify gas-focused vulnerabilities, and present MadMax: a static program analysis technique to automatically detect gas-focused vulnerabilities with very high confidence. Our approach combines a control-flow-analysis-based decompiler and declarative program-structure queries. The combined analysis captures high-level domain-specific concepts (such as "dynamic data structure storage" and "safely resumable loops") and achieves high precision and scalability. MadMax analyzes the entirety of smart contracts in the Ethereum blockchain in just 10 hours (with decompilation timeouts in 8% of the cases) and flags contracts with a (highly volatile) monetary value of over $2.8B as vulnerable. Manual inspection of a sample of flagged contracts shows that 81% of the sampled warnings do indeed lead to vulnerabilities, which we report on in our experiment. Neville Grech, Michael Kong, Anton Jurisevic, Lexi Brent, Bernhard Scholz, Yannis Smaragdakis |
Proc. ACM Program. Lang. | 6 |
| 2018 | Precision-guided context sensitivity for pointer analysisabstractContext sensitivity is an essential technique for ensuring high precision in Java pointer analyses. It has been observed that applying context sensitivity partially, only on a select subset of the methods, can improve the balance between analysis precision and speed. However, existing techniques are based on heuristics that do not provide much insight into what characterizes this method subset. In this work, we present a more principled approach for identifying precision-critical methods, based on general patterns of value flows that explain where most of the imprecision arises in context-insensitive pointer analysis. Accordingly, we provide an efficient algorithm to recognize these flow patterns in a given program and exploit them to yield good tradeoffs between analysis precision and speed. Our experimental results on standard benchmark and real-world programs show that a pointer analysis that applies context sensitivity partially, only on the identified precision-critical methods, preserves effectively all (98.8%) of the precision of a highly-precise conventional context-sensitive pointer analysis (2-object-sensitive with a context-sensitive heap), with a substantial speedup (on average 3.4X, and up to 9.2X). Yue Li 0006, Tian Tan 0001, Anders Møller, Yannis Smaragdakis |
Proc. ACM Program. Lang. | 4 |
| 2017 | Stream fusion, to completenessabstractStream processing is mainstream (again): Widely-used stream libraries are now available for virtually all modern OO and functional languages, from Java to C# to Scala to OCaml to Haskell. Yet expressivity and performance are still lacking. For instance, the popular, well-optimized Java 8 streams do not support the zip operator and are still an order of magnitude slower than hand-written loops. Oleg Kiselyov, Aggelos Biboudis, Nick Palladinos, Yannis Smaragdakis |
POPL | 4 |
| 2017 | Heaps don't lie: countering unsoundness with heap snapshotsabstractStatic analyses aspire to explore all possible executions in order to achieve soundness. Yet, in practice, they fail to capture common dynamic behavior. Enhancing static analyses with dynamic information is a common pattern, with tools such as Tamiflex. Past approaches, however, miss significant portions of dynamic behavior, due to native code, unsupported features (e.g., invokedynamic or lambdas in Java), and more. We present techniques that substantially counteract the unsoundness of a static analysis, with virtually no intrusion to the analysis logic. Our approach is reified in the HeapDL toolchain and consists in taking whole-heap snapshots during program execution, that are further enriched to capture significant aspects of dynamic behavior, regardless of the causes of such behavior. The snapshots are then used as extra inputs to the static analysis. The approach exhibits both portability and significantly increased coverage. Heap information under one set of dynamic inputs allows a static analysis to cover many more behaviors under other inputs. A HeapDL-enhanced static analysis of the DaCapo benchmarks computes 99.5% (median) of the call-graph edges of unseen dynamic executions (vs. 76.9% for the Tamiflex tool). Neville Grech, Georgios Fourtounis 0001, Adrian Francalanza, Yannis Smaragdakis |
Proc. ACM Program. Lang. | 4 |
| 2017 | P/Taint: unified points-to and taint analysisabstractStatic information-flow analysis (especially taint-analysis) is a key technique in software security, computing where sensitive or untrusted data can propagate in a program. Points-to analysis is a fundamental static program analysis, computing what abstract objects a program expression may point to. In this work, we propose a deep unification of information-flow and points-to analysis. We observe that information-flow analysis is not a mere high-level client of points-to information, but it is indeed identical to points-to analysis on artificial abstract objects that represent different information sources. The very same algorithm can compute, simultaneously, two interlinked but separate results (points-to and information-flow values) with changes only to its initial conditions. The benefits of such a unification are manifold. We can use existing points-to analysis implementations, with virtually no modification (only minor additions of extra logic for sanitization) to compute information flow concepts, such as value tainting. The algorithmic enhancements of points-to analysis (e.g., different flavors of context sensitivity) can be applied transparently to information-flow analysis. Heavy engineering work on points-to analysis (e.g., handling of the reflection API for Java) applies to information-flow analysis without extra effort. We demonstrate the benefits in a realistic implementation that leverages the Doop points-to analysis framework (including its context-sensitivity and reflection analysis features) to provide an information-flow analysis with excellent precision (over 91%) and recall (over 99%) for standard Java information-flow benchmarks. The analysis comfortably scales to large, real-world Android applications, analyzing the Facebook Messenger app with more than 55 K classes in under 7 hours. Neville Grech, Yannis Smaragdakis |
Proc. ACM Program. Lang. | 2 |
| 2016 | Structure-Sensitive Points-To Analysis for C and C++
George Balatsouras, Yannis Smaragdakis |
SAS | 2 |
| 2015 | More Sound Static Handling of Java Reflection
Yannis Smaragdakis, George Balatsouras, George Kastrinis, Martin Bravenboer |
APLAS | 1 |
| 2015 | A Backend Extension Mechanism for PQL/Java with Free Run-Time Optimisation
Hilmar Ackermann, Christoph Reichenbach, Yannis Smaragdakis |
CC | 4 |
| 2015 | Streams a la carte: Extensible Pipelines with Object AlgebrasabstractStreaming libraries have become ubiquitous in object-oriented languages, with recent offerings in Java, C#, and Scala. All such libraries, however, suffer in terms of extensibility: there is no way to change the semantics of a streaming pipeline (e.g., to fuse filter operators, to perform computations lazily, to log operations) without changes to the library code. Furthermore, in some languages it is not even possible to add new operators (e.g., a zip operator, in addition to the standard map, filter, etc.) without changing the library. We address such extensibility shortcomings with a new design for streaming libraries. The architecture underlying this design borrows heavily from Oliveira and Cook's object algebra solution to the expression problem, extended with a design that exposes the push/pull character of the iteration, and an encoding of higher-kinded polymorphism. We apply our design to Java and show that the addition of full extensibility is accompanied by high performance, matching or exceeding that of the original, highly-optimized Java streams library. Aggelos Biboudis, Nick Palladinos, Georgios Fourtounis 0001, Yannis Smaragdakis |
ECOOP | 4 |
| 2015 | Foo: a minimal modern OO calculusabstractWe present the Flyweight Object-Oriented (Fᴏᴏ) calculus for the modeling of object-oriented languages. Fᴏᴏ is a simple, minimal class-based calculus, modeling only essential computational aspects and emphasizing larger-scale features (e.g., inheritance and generics). Fᴏᴏ is motivated by the observation that recent language design work focuses on elements not well-captured either by traditional object calculi or by language-specific modeling efforts, such as Featherweight Java. Fᴏᴏ integrates seamlessly both nominal and structural subtyping ideas, leveraging the latter to eliminate the need for modeling object fields and constructors. Comparing to recent formalization efforts in the literature, Fᴏᴏ is more compact, yet versatile enough to be usable in multiple settings modeling Java, C#, or Scala extensions. Prodromos Gerakios, Georgios Fourtounis 0001, Yannis Smaragdakis |
FTfJP@ECOOP | 3 |
| 2015 | Automating ad hoc data representation transformationsabstractTo maximize run-time performance, programmers often specialize their code by hand, replacing library collections and containers by custom objects in which data is restructured for efficient access. However, changing the data representation is a tedious and error-prone process that makes it hard to test, maintain and evolve the source code. We present an automated and composable mechanism that allows programmers to safely change the data representation in delimited scopes containing anything from expressions to entire class definitions. To achieve this, programmers define a transformation and our mechanism automatically and transparently applies it during compilation, eliminating the need to manually change the source code. Our technique leverages the type system in order to offer correctness guarantees on the transformation and its interaction with object-oriented language features, such as dynamic dispatch, inheritance and generics. We have embedded this technique in a Scala compiler plugin and used it in four very different transformations, ranging from improving the data layout and encoding, to retrofitting specialization and value class status, and all the way to collection deforestation. On our benchmarks, the technique obtained speedups between 1.8x and 24.5x. Vlad Ureche, Aggelos Biboudis, Yannis Smaragdakis, Martin Odersky |
OOPSLA | 3 |
| 2014 | Refactoring Java generics by inferring wildcards, in practiceabstractWildcard annotations can improve the generality of Java generic libraries, but require heavy manual effort. We present an algorithm for refactoring and inferring more general type instantiations of Java generics using wildcards. Compared to past approaches, our work is practical and immediately applicable: we assume no changes to the Java type system, while taking into account all its intricacies. Our system allows users to select declarations (variables, method parameters, return types, etc.) to generalize and considers declarations not declared in available source code. It then performs an inter-procedural flow analysis and a method body analysis, in order to generalize type signatures. We evaluate our technique on six Java generic libraries. We find that 34% of available declarations of variant type signatures can be generalized - i.e., relaxed with more general wildcard types. On average, 146 other declarations need to be updated when a declaration is generalized, showing that this refactoring would be too tedious and error-prone to perform manually. John Altidor, Yannis Smaragdakis |
OOPSLA | 2 |
| 2014 | Introspective analysis: context-sensitivity, across the boardabstractContext-sensitivity is the primary approach for adding more precision to a points-to analysis, while hopefully also maintaining scalability. An oft-reported problem with context-sensitive analyses, however, is that they are bi-modal: either the analysis is precise enough that it manipulates only manageable sets of data, and thus scales impressively well, or the analysis gets quickly derailed at the first sign of imprecision and becomes orders-of-magnitude more expensive than would be expected given the program's size. There is currently no approach that makes precise context-sensitive analyses (of any flavor: call-site-, object-, or type-sensitive) scale across the board at a level comparable to that of a context-insensitive analysis. To address this issue, we propose introspective analysis: a technique for uniformly scaling context-sensitive analysis by eliminating its performance-detrimental behavior, at a small precision expense. Introspective analysis consists of a common adaptivity pattern: first perform a context-insensitive analysis, then use the results to selectively refine (i.e., analyze context-sensitively) program elements that will not cause explosion in the running time or space. The technical challenge is to appropriately identify such program elements. We show that a simple but principled approach can be remarkably effective, achieving scalability (often with dramatic speedup) for benchmarks previously completely out-of-reach for deep context-sensitive analyses. Yannis Smaragdakis, George Kastrinis, George Balatsouras |
PLDI | 1 |
| 2014 | Residual Investigation: Predictive and Precise Bug DetectionabstractWe introduce the concept of residual investigation for program analysis. A residual investigation is a dynamic check installed as a result of running a static analysis that reports a possible program error. The purpose is to observe conditions that indicate whether the statically predicted program fault is likely to be realizable and relevant. The key feature of a residual investigation is that it has to be much more precise (i.e., with fewer false warnings) than the static analysis alone, yet significantly more general (i.e., reporting more errors) than the dynamic tests in the program's test suite that are pertinent to the statically reported error. That is, good residual investigations encode dynamic conditions that, when considered in conjunction with the static error report, increase confidence in the existence or severity of an error without needing to directly observe a fault resulting from the error. We enhance the static analyzer FindBugs with several residual investigations appropriately tuned to the static error patterns in FindBugs, and apply it to nine large open-source systems and their native test suites. The result is an analysis with a low occurrence of false warnings (false positives) while reporting several actual errors that would not have been detected by mere execution of a program's test suite. Kaituo Li, Christoph Reichenbach, Christoph Csallner, Yannis Smaragdakis |
ACM Trans. Softw. Eng. Methodol. | 4 |
| 2013 | Efficient and Effective Handling of Exceptions in Java Points-to Analysis
George Kastrinis, Yannis Smaragdakis |
CC | 2 |
| 2013 | Reified type parameters using Java annotationsabstractJava generics are compiled by-erasure: all clients reuse the same bytecode, with uses of the unknown type erased. C++ templates are compiled by-expansion: each type-instantiation of a template produces a different code definition. The two approaches offer trade-offs on multiple axes. We propose an extension of Java generics that allows by-expansion translation relative to selected type parameters only. This language design allows sophisticated users to get the best of both worlds at a fine granularity. Furthermore, our proposal is based on Java 8 Type Annotations (JSR 308) and the Checker Framework as an abstraction layer for controlling compilation without changes to the internals of a Java compiler. Prodromos Gerakios, Aggelos Biboudis, Yannis Smaragdakis |
GPCE | 3 |
| 2013 | SEDGE: Symbolic example data generation for dataflow programsabstractExhaustive, automatic testing of dataflow (esp. mapreduce) programs has emerged as an important challenge. Past work demonstrated effective ways to generate small example data sets that exercise operators in the Pig platform, used to generate Hadoop map-reduce programs. Although such prior techniques attempt to cover all cases of operator use, in practice they often fail. Our SEDGE system addresses these completeness problems: for every dataflow operator, we produce data aiming to cover all cases that arise in the dataflow program (e.g., both passing and failing a filter). SEDGE relies on transforming the program into symbolic constraints, and solving the constraints using a symbolic reasoning engine (a powerful SMT solver), while using input data as concrete aids in the solution process. The approach resembles dynamic-symbolic (a.k.a. “concolic”) execution in a conventional programming language, adapted to the unique features of the dataflow domain. In third-party benchmarks, SEDGE achieves higher coverage than past techniques for 5 out of 20 PigMix benchmarks and 7 out of 11 SDSS benchmarks and (with equal coverage for the rest of the benchmarks). We also show that our targeting of the high-level dataflow language pays off: for complex programs, state-of-the-art dynamic-symbolic execution at the level of the generated map-reduce code (instead of the original dataflow program) requires many more test cases or achieves much lower coverage than our approach. Kaituo Li, Christoph Reichenbach, Yannis Smaragdakis, Yanlei Diao, Christoph Csallner |
ASE | 3 |
| 2013 | Class hierarchy complementation: soundly completing a partial type graphabstractWe present the problem of class hierarchy complementation: given a partially known hierarchy of classes together with subtyping constraints ("A has to be a transitive subtype of B") complete the hierarchy so that it satisfies all constraints. The problem has immediate practical application to the analysis of partial programs--e.g., it arises in the process of providing a sound handling of "phantom classes" in the Soot program analysis framework. We provide algorithms to solve the hierarchy complementation problem in the single inheritance and multiple inheritance settings. We also show that the problem in a language such as Java, with single inheritance but multiple subtyping and distinguished class vs. interface types, can be decomposed into separate single- and multiple-subtyping instances. We implement our algorithms in a tool, JPhantom, which complements partial Java bytecode programs so that the result is guaranteed to satisfy the Java verifier requirements. JPhantom is highly scalable and runs in mere seconds even for large input applications and complex constraints (with a maximum of 14s for a 19MB binary). George Balatsouras, Yannis Smaragdakis |
OOPSLA | 2 |
| 2013 | Forsaking inheritance: supercharged delegation in DelphJabstractWe propose DelphJ: a Java-based OO language that eschews inheritance completely, in favor of a combination of class morphing and (deep) delegation. Compared to past delegation approaches, the novel aspect of our design is the ability to emulate the best aspects of inheritance while retaining maximum flexibility: using morphing, a class can select any of the methods of its delegatee and export them (if desired) or transform them (e.g., to add extra arguments or modify type signatures), yet without needing to name these methods explicitly and handle them one-by-one. Compared to past work on morphing, our approach adopts and adapts advanced delegation mechanisms, in order to add late binding capabilities and, thus, provide a full substitute of inheritance. Additionally, we explore complex semantic issues in the interaction of delegation with late binding. We present our language design both informally, with numerous examples, and formally in a core calculus. Prodromos Gerakios, Aggelos Biboudis, Yannis Smaragdakis |
OOPSLA | 3 |
| 2013 | Set-based pre-processing for points-to analysisabstractWe present set-based pre-analysis: a virtually universal optimization technique for flow-insensitive points-to analysis. Points-to analysis computes a static abstraction of how object values flow through a program's variables. Set-based pre-analysis relies on the observation that much of this reasoning can take place at the set level rather than the value level. Computing constraints at the set level results in significant optimization opportunities: we can rewrite the input program into a simplified form with the same essential points-to properties. This rewrite results in removing both local variables and instructions, thus simplifying the subsequent value-based points-to computation. Effectively, set-based pre-analysis puts the program in a normal form optimized for points-to analysis. Yannis Smaragdakis, George Balatsouras, George Kastrinis |
OOPSLA | 1 |
| 2013 | Hybrid context-sensitivity for points-to analysisabstractContext-sensitive points-to analysis is valuable for achieving high precision with good performance. The standard flavors of context-sensitivity are call-site-sensitivity (kCFA) and object-sensitivity. Combining both flavors of context-sensitivity increases precision but at an infeasibly high cost. We show that a selective combination of call-site- and object-sensitivity for Java points-to analysis is highly profitable. Namely, by keeping a combined context only when analyzing selected language features, we can closely approximate the precision of an analysis that keeps both contexts at all times. In terms of speed, the selective combination of both kinds of context not only vastly outperforms non-selective combinations but is also faster than a mere object-sensitive analysis. This result holds for a large array of analyses (e.g., 1-object-sensitive, 2-object-sensitive with a context-sensitive heap, type-sensitive) establishing a new set of performance/precision sweet spots. George Kastrinis, Yannis Smaragdakis |
PLDI | 2 |
| 2013 | Second-order constraints in dynamic invariant inferenceabstractThe current generation of dynamic invariant detectors often produce invariants that are inconsistent with program semantics or programmer knowledge. We improve the consistency of dynamically discovered invariants by taking into account higher-level constraints. These constraints encode knowledge about invariants, even when the invariants themselves are unknown. For instance, even though the invariants describing the behavior of two functions f1 and f2 may be unknown, we may know that any valid input for f1 is also valid for f2, i.e., the precondition of f1 implies that of f2. We explore techniques for expressing and employing such consistency constraints to improve the quality of produced invariants. We further introduce techniques for dynamically discovering potential second-order constraints that the programmer can subsequently approve or reject. Kaituo Li, Christoph Reichenbach, Yannis Smaragdakis, Michal Young |
ESEC/SIGSOFT FSE | 3 |
| 2012 | Java Wildcards Meet Definition-Site Variance
John Altidor, Christoph Reichenbach, Yannis Smaragdakis |
ECOOP | 3 |
| 2012 | PQL: A Purely-Declarative Java Extension for Parallel Programming
Christoph Reichenbach, Yannis Smaragdakis, Neil Immerman |
ECOOP | 2 |
| 2012 | Residual investigation: predictive and precise bug detectionabstractWe introduce the concept of “residual investigation” for program analysis. A residual investigation is a dynamic check installed as a result of running a static analysis that reports a possible program error. The purpose is to observe conditions that indicate whether the statically predicted program fault is likely to be realizable and relevant. The key feature of a residual investigation is that it has to be much more precise (i.e., with fewer false warnings) than the static analysis alone, yet significantly more general (i.e., reporting more errors) than the dynamic tests in the program's test suite pertinent to the statically reported error. That is, good residual investigations encode dynamic conditions that, when taken in conjunction with the static error report, increase confidence in the existence of an error, as well as its severity, without needing to directly observe a fault resulting from the error. Kaituo Li, Christoph Reichenbach, Christoph Csallner, Yannis Smaragdakis |
ISSTA | 4 |
| 2012 | Sound predictive race detection in polynomial timeabstractData races are among the most reliable indicators of programming errors in concurrent software. For at least two decades, Lamport's happens-before (HB) relation has served as the standard test for detecting races--other techniques, such as lockset-based approaches, fail to be sound, as they may falsely warn of races. This work introduces a new relation, causally-precedes (CP), which generalizes happens-before to observe more races without sacrificing soundness. Intuitively, CP tries to capture the concept of happens-before ordered events that must occur in the observed order for the program to observe the same values. What distinguishes CP from past predictive race detection approaches (which also generalize an observed execution to detect races in other plausible executions) is that CP-based race detection is both sound and of polynomial complexity. We demonstrate that the unique aspects of CP result in practical benefit. Applying CP to real-world programs, we successfully analyze server-level applications (e.g., Apache FtpServer) and show that traces longer than in past predictive race analyses can be analyzed in mere seconds to a few minutes. For these programs, CP race detection uncovers races that are hard to detect by repeated execution and HB race detection: a single run of CP race detection produces several races not discovered by 10 separate rounds of happens-before race detection. Yannis Smaragdakis, Jacob Evans, Caitlin Sadowski, Jaeheon Yi, Cormac Flanagan |
POPL | 1 |
| 2011 | Taming the wildcards: combining definition- and use-site varianceabstractVariance allows the safe integration of parametric and subtype polymorphism. Two flavors of variance, definition-site versus use-site variance, have been studied and have had their merits hotly debated. Definition-site variance (as in Scala and C#) offers simple type-instantiation rules, but causes fractured definitions of naturally invariant classes; Use-site variance (as in Java) offers simplicity in class definitions, yet complex type-instantiation rules that elude most programmers. John Altidor, Shan Shan Huang, Yannis Smaragdakis |
PLDI | 3 |
| 2011 | Pick your contexts well: understanding object-sensitivityabstractObject-sensitivity has emerged as an excellent context abstraction for points-to analysis in object-oriented languages. Despite its practical success, however, object-sensitivity is poorly understood. For instance, for a context depth of 2 or higher, past scalable implementations deviate significantly from the original definition of an object-sensitive analysis. The reason is that the analysis has many degrees of freedom, relating to which context elements are picked at every method call and object creation. We offer a clean model for the analysis design space, and discuss a formal and informal understanding of object-sensitivity and of how to create good object-sensitive analyses. The results are surprising in their extent. We find that past implementations have made a sub-optimal choice of contexts, to the severe detriment of precision and performance. We define a "full-object-sensitive" analysis that results in significantly higher precision, and often performance, for the exact same context depth. We also introduce "type-sensitivity" as an explicit approximation of object-sensitivity that preserves high context quality at substantially reduced cost. A type-sensitive points-to analysis makes an unconventional use of types as context: the context types are not dynamic types of objects involved in the analysis, but instead upper bounds on the dynamic types of their allocator objects. Our results expose the influence of context choice on the quality of points-to analysis and demonstrate type-sensitivity to be an idea with major impact: It decisively advances the state-of-the-art with a spectrum of analyses that simultaneously enjoy speed (several times faster than an analogous object-sensitive analysis), scalability (comparable to analyses with much less context-sensitivity), and precision (comparable to the best object-sensitive analysis with the same context depth). Yannis Smaragdakis, Martin Bravenboer, Ondrej Lhoták |
POPL | 1 |
| 2011 | Statically safe program generation with SafeGen
Shan Shan Huang, David Zook, Yannis Smaragdakis |
Sci. Comput. Program. | 3 |
| 2011 | DOLAR: virtualizing heterogeneous information spaces to support their expansionabstractAbstract Users expect applications to successfully cope with the expansion of information as necessitated by the continuous inclusion of novel types of content. Given that such content may originate from ‘not‐seen thus far’ data collections and/or data sources, the challenging issue is to achieve the return of investment on existing services, adapting to new information without changing existing business‐logic implementation. To address this need, we introduce DOLAR (Data Object Language And Runtime), a service‐neutral framework which virtualizes the information space to avoid invasive, time‐consuming, and expensive source‐code extensions that frequently break applications. Specifically, DOLAR automates the introduction of new business‐logic objects in terms of the proposed virtual ‘content objects’. Such user‐specified virtual objects align to storage artifacts and help realize uniform ‘store‐to‐user’ data flows atop heterogeneous sources, while offering the reverse ‘user‐to‐store’ flows with identical effectiveness and ease of use. In addition, the suggested virtual object composition schemes help decouple business logic from any content origin, storage and/or structural details, allowing applications to support novel types of items without modifying their service provisions. We expect that content‐rich applications will benefit from our approach and demonstrate how DOLAR has assisted in the cost‐effective development and gradual expansion of a production‐quality digital library. Experimentation shows that our approach imposes minimal overheads and DOLAR‐based applications scale as well as any underlying datastore(s). Copyright © 2011 John Wiley & Sons, Ltd. Kostas Saidis, Yannis Smaragdakis, Alex Delis |
Softw. Pract. Exp. | 2 |
| 2011 | Morphing: Structurally shaping a class by reflecting on othersabstractWe present MorphJ: a language for specifying general classes whose members are produced by iterating over members of other classes. We call this technique “class morphing” or just “morphing.” Morphing extends the notion of genericity so that not only types of methods and fields, but also the structure of a class can vary according to type variables. This adds a disciplined form of metaprogramming to mainstream languages and allows expressing common programming patterns in a highly generic way that is otherwise not supported by conventional techniques. For instance, morphing lets us write generic proxies (i.e., classes that can be parameterized with another class and export the same public methods as that class); default implementations (e.g., a generic do-nothing type, configurable for any interface); semantic extensions (e.g., specialized behavior for methods that declare a certain annotation); and more. MorphJ's hallmark feature is that, despite its emphasis on generality, it allows modular type-checking: a MorphJ class can be checked independently of its uses. Thus, the possibility of supplying a type parameter that will lead to invalid code is detected early, an invaluable feature for highly general components that will be statically instantiated by other programmers. We demonstrate the benefits of morphing with several examples, including a MorphJ reimplementation of DSTM2, a software transactional memory library which reduces 1,484 lines of Java reflection and bytecode engineering library calls to just 586 lines of MorphJ code. Shan Shan Huang, Yannis Smaragdakis |
ACM Trans. Program. Lang. Syst. | 2 |
| 2010 | What can the GC compute efficiently?: a language for heap assertions at GC timeabstractWe present the DeAL language for heap assertions that are efficiently evaluated during garbage collection time. DeAL is a rich, declarative, logic-based language whose programs are guaranteed to be executable with good whole-heap locality, i.e., within a single traversal over every live object on the heap and a finite neighborhood around each object. As a result, evaluating DeAL programs incurs negligible cost: for simple assertion checking at each garbage collection, the end-to-end execution slowdown is below 2%. DeAL is integrated into Java as a VM extension and we demonstrate its efficiency and expressiveness with several applications and properties from the past literature. Christoph Reichenbach, Neil Immerman, Yannis Smaragdakis, Edward Aftandilian, Samuel Z. Guyer |
OOPSLA | 3 |
| 2010 | Resolving and exploiting the k-CFA paradox: illuminating functional vs. object-oriented program analysisabstractLow-level program analysis is a fundamental problem, taking the shape of "flow analysis" in functional languages and "points-to" analysis in imperative and object-oriented languages. Despite the similarities, the vocabulary and results in the two communities remain largely distinct, with limited cross-understanding. One of the few links is Shivers's k-CFA work, which has advanced the concept of "context-sensitive analysis" and is widely known in both communities. Matthew Might, Yannis Smaragdakis, David Van Horn |
PLDI | 2 |
| 2010 | Adaptive locks: Combining transactions and locks for efficient concurrency
Takayuki Usui, Reimer Behrends, Jacob Evans, Yannis Smaragdakis |
J. Parallel Distributed Comput. | 4 |
| 2009 | Adaptive Locks: Combining Transactions and Locks for Efficient ConcurrencyabstractTransactional memory is being advanced as an alternative to traditional lock-based synchronization for concurrent programming. Transactional memory simplifies the programming model and maximizes concurrency. At the same time, transactions can suffer from interference that causes them to often abort, from heavy overheads for memory accesses, and from expressiveness limitations (e.g., for I/O operations). In this paper we propose an adaptive locking technique that dynamically observes whether a critical section would be best executed transactionally or while holding a mutex lock. The critical new elements of our approach include the adaptivity logic and cost-benefit analysis, a low overhead implementation of statistics collection and adaptive locking in a full C compiler, and an exposition of the effects on the programming model. In experiments with both micro and macro-benchmarks we found adaptive locks to consistently match or out perform the better of the two component mechanisms (mutexes or transactions). Compared to either mechanism alone, adaptive locks often provide 3-to-10x speedups. Additionally, adaptive locks simplify the programming model by reducing the need for fine-grained locking: with adaptive locks, the programmer can specify coarse-grained locking annotations and often achieve fine-grained locking performance due to the transactional memory mechanisms. Takayuki Usui, Reimer Behrends, Jacob Evans, Yannis Smaragdakis |
PACT | 4 |
| 2009 | Exception analysis and points-to analysis: better togetherabstractException analysis and points-to analysis are typically done in complete separation. Past algorithms for precise exception analysis (e.g., pairing throw clauses with catch statements) use pre-computed points-to information. Past points-to analyses either unsoundly ignore exceptions, or conservatively compute a crude approximation of exception throwing (e.g., considering an exception throw as an assignment to a global variable, accessible from any catch clause). We show that this separation results in significant slowdowns or vast imprecision. The two kinds of analyses are interdependent: neither can be performed accurately without the other. The interdependency leads us to propose a joint handling for performance and precision. We show that our exception analysis is expressible highly elegantly in a declarative form, and can apply to points-to analyses of varying precision. In fact, our specification of exception analysis is "fully precise", as it models closely the Java exception handling semantics. The necessary approximation is provided only through whichever abstractions are used for contexts and objects in the base points-to analysis. Our combined approach achieves similar precision relative to exceptions (exception-catch links) as the best past precise exception analysis, with a runtime of seconds instead of tens of minutes. At the same time, our analysis achieves much higher precision of points-to information (an average of half as many values for each reachable variable for most of the DaCapo benchmarks) than points-to analyses that treat exceptions conservatively, all at a fraction of the execution time. Martin Bravenboer, Yannis Smaragdakis |
ISSTA | 2 |
| 2009 | Strictly declarative specification of sophisticated points-to analysesabstractWe present the DOOP framework for points-to analysis of Java programs. DOOP builds on the idea of specifying pointer analysis algorithms declaratively, using Datalog: a logic-based language for defining (recursive) relations. We carry the declarative approach further than past work by describing the full end-to-end analysis in Datalog and optimizing aggressively using a novel technique specifically targeting highly recursive Datalog programs. Martin Bravenboer, Yannis Smaragdakis |
OOPSLA | 2 |
| 2009 | Scalable satisfiability checking and test data generation from modeling diagrams
Yannis Smaragdakis, Christoph Csallner, Ranjith Subramanian |
Autom. Softw. Eng. | 1 |
| 2009 | J-Orchestra: Enhancing Java programs with distribution capabilitiesabstractJ-Orchestra is a system that enhances centralized Java programs with distribution capabilities. Operating at the bytecode level, J-Orchestra transforms a centralized Java program (i.e., running on a single Java Virtual Machine (JVM)) into a distributed one (i.e., running across multiple JVMs). This transformation effectively separates distribution concerns from the core functionality of a program. J-Orchestra follows a semiautomatic transformation process. Through a GUI, the user selects program elements (at class granularity) and assigns them to network locations. Based on the user's input, the J-Orchestra backend automatically partitions the program through compiler-level techniques, without changes to the JVM or to the Java Runtime Environment (JRE) classes. By means of bytecode engineering and code generation, J-Orchestra substitutes method calls with remote method calls, direct object references with proxy references, etc. It also translates Java language features (e.g., static methods and fields, inheritance, inner classes, new object construction, etc.) for efficient distributed execution. We detail the main technical issues that J-Orchestra addresses, including its mechanism for program transformation in the presence of unmodifiable code (e.g., in JRE classes) and the translation of concurrency and synchronization constructs to work correctly over the network. We further discuss a case study of transforming a large, commercial, third-party application for efficient execution in a client server environment and outline the architectural characteristics of centralized programs that are amenable to automated distribution with J-Orchestra. Eli Tilevich, Yannis Smaragdakis |
ACM Trans. Softw. Eng. Methodol. | 2 |
| 2008 | DySy: dynamic symbolic execution for invariant inferenceabstractDynamically discovering likely program invariants from concrete test executions has emerged as a highly promising software engineering technique. Dynamic invariant inference has the advantage of succinctly summarizing both "expected" program inputs and the subset of program behaviors that is normal under those inputs. In this paper, we introduce a technique that can drastically increase the relevance of inferred invariants, or reduce the size of the test suite required to obtain good invariants. Instead of falsifying invariants produced by pre-set patterns, we determine likely program invariants by combining the concrete execution of actual test cases with a simultaneous symbolic execution of the same tests. The symbolic execution produces abstract conditions over program variables that the concrete tests satisfy during their execution. In this way, we obtain the benefits of dynamic inference tools like Daikon: the inferred invariants correspond to the observed program behaviors. At the same time, however, our inferred invariants are much more suited to the program at hand than Daikon's hard-coded invariant patterns. The symbolic invariants are literally derived from the program text itself, with appropriate value substitutions as dictated by symbolic execution. Christoph Csallner, Nikolai Tillmann, Yannis Smaragdakis |
ICSE | 3 |
| 2008 | Expressive and safe static reflection with MorphJabstractRecently, language extensions have been proposed for Java and C# to support pattern-based reflective declaration. These extensions introduce a disciplined form of meta-programming and aspect-oriented programming to mainstream languages: They allow members of a class (i.e., fields and methods) to be declared by statically iterating over and pattern-matching on members of other classes. Such techniques, however, have been unable to safely express simple, but common, idioms such as declaring getter and setter methods for fields. Shan Shan Huang, Yannis Smaragdakis |
PLDI | 2 |
| 2008 | DSD-Crasher: A hybrid analysis tool for bug findingabstractDSD-Crasher is a bug finding tool that follows a three-step approach to program analysis: D. Capture the program's intended execution behavior with dynamic invariant detection. The derived invariants exclude many unwanted values from the program's input domain. S. Statically analyze the program within the restricted input domain to explore many paths. D. Automatically generate test cases that focus on reproducing the predictions of the static analysis. Thereby confirmed results are feasible. This three-step approach yields benefits compared to past two-step combinations in the literature. In our evaluation with third-party applications, we demonstrate higher precision over tools that lack a dynamic step and higher efficiency over tools that lack a static step. Christoph Csallner, Yannis Smaragdakis, Tao Xie 0001 |
ACM Trans. Softw. Eng. Methodol. | 2 |
| 2008 | Domain-specific languages and program generation with meta-AspectJabstractMeta-AspectJ (MAJ) is a language for generating AspectJ programs using code templates. MAJ itself is an extension of Java, so users can interleave arbitrary Java code with AspectJ code templates. MAJ is a structured metaprogramming tool: a well-typed generator implies a syntactically correct generated program. MAJ promotes a methodology that combines aspect-oriented and generative programming. A valuable application is in implementing small domain-specific language extensions as generators using unobtrusive annotations for syntax extension and AspectJ as a back-end. The advantages of this approach are twofold. First, the generator integrates into an existing software application much as a regular API or library, instead of as a language extension. Second, a mature language implementation is easy to achieve with little effort since AspectJ takes care of the low-level issues of interfacing with the base Java language. In addition to its practical value, MAJ offers valuable insights to metaprogramming tool designers. It is a mature metaprogramming tool for AspectJ (and, by extension, Java): a lot of emphasis has been placed on context-sensitive parsing and error reporting. As a result, MAJ minimizes the number of metaprogramming (quote/unquote) operators and uses type inference to reduce the need to remember type names for syntactic entities. Shan Shan Huang, David Zook, Yannis Smaragdakis |
ACM Trans. Softw. Eng. Methodol. | 3 |
| 2008 | NRMI: Natural and Efficient MiddlewareabstractWe present natural remote method invocation (NRMI): a middleware mechanism that provides a fully general implementation of call-by-copy-restore semantics for arbitrary linked data structures, used as parameters in remote procedure calls. Call-by-copy-restore offers a more natural programming model for distributed systems than traditional call-by-copy middleware, enabling remote calls to behave much like local calls. We discuss in depth the effects of calling semantics for middleware, describe when and why NRMI is more convenient to use than standard middleware, and present three implementations of NRMI in distinct settings, showing the generality of the approach. Eli Tilevich, Yannis Smaragdakis |
IEEE Trans. Parallel Distributed Syst. | 2 |
| 2007 | Morphing: Safely Shaping a Class in the Image of Others
Shan Shan Huang, David Zook, Yannis Smaragdakis |
ECOOP | 3 |
| 2007 | Scalable automatic test data generation from modeling diagramsabstractWe explore the automatic generation of test data that respect constraints expressed in the Object-Role Modeling(ORM) language. ORM is a popular conceptual modelinglanguage, primarily targeting database applications, withsignificant uses in practice. The general problem of evenchecking whether an ORM diagram is satisfiable is quitehard: restricted forms are easily NP-hard and the problemis undecidable for some expressive formulations of ORM.Brute-force mapping to input for constraint and SAT solversdoes not scale: state-of-the-art solvers fail to find data to satisfy uniqueness and mandatory constraints in realistic time even for small examples. We instead define a restricted subset of ORM that allows efficient reasoning yet contains most constraints overwhelmingly used in practice. We show that the problem of deciding whether these constraints are consistent (i.e., whether we can generate appropriate test data) is solvable in polynomial time, and we produce a highly efficient (interactive speed) checker. Additionally, we analyze over 160 ORM diagrams that capture data models from industrial practice and demonstrate that our subset of ORM is expressive enough to handle their vast majority Yannis Smaragdakis, Christoph Csallner, Ranjith Subramanian |
ASE | 1 |
| 2007 | Transactions with isolation and cooperationabstractWe present the TIC (Transactions with Isolation and Cooperation) model for concurrent programming. TIC adds to standard transactional memory the ability for a transaction to observe the effects of other threads at selected points. This allows transactions to cooperate, as well as to invoke nonrepeatable or irreversible operations, such as I/O. Cooperating transactions run the danger of exposing intermediate state and of having other threads change the transaction's state. The TIC model protects against unanticipated interference by having the type system keep track of all operations that may (transitively) violate the atomicity of a transaction and require the programmer to establish consistency at appropriate points. The result is a programming model that is both general and simple. We have used the TIC model to re-engineer existing lock-based applications including a substantial multi-threaded web mail server and a memory allocator with coarse-grained locking. Our experience confirms the features of the TIC model: It is convenient for the programmer, while maintaining the benefits of transactional memory. Yannis Smaragdakis, Anthony Kay, Reimer Behrends, Michal Young |
OOPSLA | 1 |
| 2007 | Combining Static and Dynamic Reasoning for Bug Detection
Yannis Smaragdakis, Christoph Csallner |
TAP | 1 |
| 2006 | Transparent program transformationsin the presence of opaque codeabstractUser-level indirection is the automatic rewriting of an application to interpose code that gets executed upon program actions such as object field access, method call, object construction, etc. The approach is constrained by the presence of opaque (native) code that cannot be indirected and can invalidate the assumptions of any indirection transformation. In this paper, we demonstrate the problem of employing user-level indirection in the presence of native code. We then suggest reasonable assumptions on the behavior of native code and a simple analysis to compute the constraints they entail. We show that the type information at the native code interface is often a surprisingly sufficient approximation of native behavior for heuristically estimating when user-level indirection can be applied safely. Furthermore, we introduce a new user-level indirection approach that minimizes the constraints imposed by interactions with native code. Eli Tilevich, Yannis Smaragdakis |
GPCE | 2 |
| 2006 | Dynamically discovering likely interface invariantsabstractDynamic invariant detection is an approach that has received considerable attention in the recent research literature. A natural question arises in languages that separate the interface of a code module from its implementation: does an inferred invariant describe the interface or the implementation? Furthermore, if an implementation is allowed to refine another, as, for instance, in object-oriented method overriding, what is the relation between the inferred invariants of the overriding and the overridden method? The problem is of great practical interest. Invariants derived by real tools, like Daikon, often suffer from internal inconsistencies when overriding is taken into account, becoming unsuitable for some automated uses. We discuss the interactions between overriding and inferred invariants, and describe the implementation of an invariant inference tool that produces consistent invariants for interfaces and overridden methods. Christoph Csallner, Yannis Smaragdakis |
ICSE | 2 |
| 2006 | Easy language extension with meta-aspectJabstractDomain-specific languages hold the potential of automating the software development process. Nevertheless, the adoption of a domain-specific language is hindered by the difficulty of transitioning to different language syntax and employing a separate translator in the software build process. We present a methodology that simplifies the development and deployment of small language extensions, in the context of Java. The main language design principle is that of language extension through unobtrusive annotations. The main language implementation idea is to express the language as a generator of customized AspectJ aspects, using our Meta-AspectJ tool. The advantages of the approach are twofold. First, the tool integrates into an existing software application much as a regular API or library, instead of as a language extension. This means that the programmer can remove the language extension at any point and choose to implement the required functionality by hand without needing to rewrite the client code. Second, a mature language implementation is easy to achieve with little effort since AspectJ takes care of the low-level issues of interfacing with the base Java language. Shan Shan Huang, Yannis Smaragdakis |
ICSE | 2 |
| 2006 | DSD-Crasher: a hybrid analysis tool for bug findingabstractDSD-Crasher is a bug finding tool that follows a three-step approach to program analysis: Christoph Csallner, Yannis Smaragdakis |
ISSTA | 2 |
| 2006 | Adaptive Caches: Effective Shaping of Cache Behavior to WorkloadsabstractWe present and evaluate the idea of adaptive processor cache management. Specifically, we describe a novel and general scheme by which we can combine any two cache management algorithms (e.g., LRU, LFU, FIFO, Random) and adaptively switch between them, closely tracking the locality characteristics of a given program. The scheme is inspired by recent work in virtual memory management at the operating system level, which has shown that it is possible to adapt over two replacement policies to provide an aggregate policy that always performs within a constant factor of the better component policy. A hardware implementation of adaptivity requires very simple logic but duplicate tag structures. To reduce the overhead, we use partial tags, which achieve good performance with a small hardware cost. In particular, adapting between LRU and LFU replacement policies on an 8-way 512KB L2 cache yields a 12.7% improvement in average CPI on applications that exhibit a non-negligible L2 miss ratio. Our approach increases total cache storage by 4.0%, but it still provides slightly better performance than a conventional 10-way set-associative 640KB cache which requires 25% more storage Ranjith Subramanian, Yannis Smaragdakis, Gabriel H. Loh |
MICRO | 2 |
| 2005 | Statically Safe Program Generation with SafeGen
Shan Shan Huang, David Zook, Yannis Smaragdakis |
GPCE | 3 |
| 2005 | Check 'n' crash: combining static checking and testingabstractWe present an automatic error-detection approach that combines static checking and concrete test-case generation. Our approach consists of taking the abstract error conditions inferred using theorem proving techniques by a static checker (ESC/Java), deriving specific error conditions using a constraint solver, and producing concrete test cases (with the JCrasher tool) that are executed to determine whether an error truly exists. The combined technique has advantages over both static checking and automatic testing individually. Compared to ESC/Java, we eliminate spurious warnings and improve the ease-of-comprehension of error reports through the production of Java counterexamples. Compared to JCrasher, we eliminate the blind search of the input space, thus reducing the testing time and increasing the test quality. Christoph Csallner, Yannis Smaragdakis |
ICSE | 2 |
| 2005 | Binary refactoring: improving code behind the scenesabstractWe present Binary Refactoring: a software engineering technique for improving the implementation of programs without modifying their source code. While related to regular refactoring in preserving a program's functionality, binary refactoring aims to capture modifications that are often applied to source code, although they only improve the performance of the software application and not the code structure. We motivate binary refactoring, present a binary refactoring catalogue, describe the design and implementation of BARBER---our binary refactoring browser for Java, and demonstrate the usefulness of binary refactoring through a series of benchmarks. Eli Tilevich, Yannis Smaragdakis |
ICSE | 2 |
| 2005 | Appletizing: Running Legacy Java Code Remotely from a Web BrowserabstractAdding distributed capabilities to existing programs has come to the forefront of software evolution. As a standard Java distributed technology, applets offer the advantages of being easily deploy able over Web browsers and requiring little to no explicit distributed programming. Yet applets are inflexible: they download remote code and run it only on the client machine. We present appletizing: a semi-automatic approach to transforming a Java GUI application into a client-server application, in which the client runs as a Java applet that communicates with the server through RMI. To enable appletizing, we have expanded the capabilities of J-Orchestra, our automatic partitioning system that takes as input a Java application in bytecode format and transforms it into a distributed application, running across multiple standard JVMs. We discuss the motivation, benefits, and J-Orchestra support for appletizing, and validate our approach via a set of case studies and associated benchmarks. Eli Tilevich, Yannis Smaragdakis, Marcus Handte |
ICSM | 2 |
| 2004 | Generating AspectJ Programs with Meta-AspectJ
David Zook, Shan Shan Huang, Yannis Smaragdakis |
GPCE | 3 |
| 2004 | General adaptive replacement policiesabstractWe propose a general scheme for creating adaptive replacement policies with good performance and strong theoretical guarantees. Specifically, we show how to combine any two existing replacement policies so that the resulting policy provably can never perform worse than either of the original policies by more than a small factor. To show that our scheme performs very well with real application data, we derive a virtual memory replacement policy that adapts between LRU, loop detection, LFU, and MRU-like replacement. The resulting policy often performs better than all of the policies it adapts over, as well as two other hand-tuned adaptive policies from the recent literature. Yannis Smaragdakis |
ISMM | 1 |
| 2004 | Portable and Efficient Distributed Threads for Java
Eli Tilevich, Yannis Smaragdakis |
Middleware | 2 |
| 2004 | Program generators and the tools to make themabstractProgram generation is among the most promising techniques in the effort to increase the automation of programming tasks. In this paper, we discuss the potential impact and research value of program generation, we give examples of our research in the area, and we outline a future work direction that we consider most interesting. Specifically, we first discuss why program generators have significant applied potential. At the same time we argue that, as a research topic, meta-programming tools (i.e., language tools for writing program generators) may be of greater value. We then illustrate our views on generators and meta-programming tools with our latest work on the Meta-AspectJ meta-programming language and the GOTECH generator. Finally, we examine the problem of statically determining the safety of a generator and present its intricacies. We limit our focus to one particular kind of guarantee for generated code---ensuring that the generated program is free of compile-time errors. We believe that this research direction will see significant attention and will make a difference in the mainstream adoption of meta-programming technology. Yannis Smaragdakis, Shan Shan Huang, David Zook |
PEPM | 1 |
| 2004 | Invited talk: program generators and the tools to make themabstractProgram generation is among the most promising techniques in the effort to increase the automation of programming tasks. In this talk, we discuss the potential impact and research value of program generation, we give examples of our research in the area, and we outline a future work direction that we consider most interesting.Specifically, we first discuss why program generators have significant applied potential. We believe that program generators can be made easy-to-implement so that they are competitive with traditional software libraries in many software domains. Compared to a common library, a generator implementing a domain-specific language can offer more concise syntax, better static error checking, and better performance through cross-operation optimizations.Despite the significant applied value of generators, however, we argue that meta-programming tools (i.e., language tools for writing program generators) may be of greater value as a research topic. The reason has to do with the domain-specificity of generators. The value of a program generator is often tied so closely to a software domain that there is little general and reusable knowledge to transmit to other generator researchers. We discuss meta-programming tools as an area with both interesting conceptual problems and great value. A good meta-programming infrastructure can simplify the creation of generators to make them an effective solution for many more domains.We illustrate our views on generators and meta-programming tools with two artifacts from our latest work: the Meta-AspectJ meta-programming language [6] and the GOTECH generator [5]. Meta-AspectJ enables generating Java and AspectJ programs using code templates, i.e., quote and unquote operators. Meta-AspectJ has two interesting elements. First, we believe that using the AspectJ language as a back-end simplies the task of writing a generator. The GOTECH generator uses this technique to adapt a Java program for server side execution in a J2EE application server. Second, Meta-AspectJ is a technically mature meta-programming tool|in many respects the most advanced meta-programming tool for Java. For instance, Meta-AspectJ reduces the need to deal with low level syntactic types for quoted entities (e.g., "expression", "statement", "identifier", etc.) through type inference and a context-sensitive parsing algorithm.Finally, we examine the problem of statically determining the safety of a generator and present its intricacies. We limit our focus to one particular kind of guarantee for generated code: ensuring that the generated program is free of compile-time errors, such as type errors, references to undened variables, etc. We argue that it is the responsibility of a good meta-programming tool to ensure that the generators written in it will always produce legal programs. Nevertheless, if we do not severely limit the generator, the problem becomes one of arbitrary control- and data flow analysis. We discuss why the limitations of current meta-programming tools [1, 4] that offer safety guarantees are too strict and present possible avenues for future research.For further reading, a full paper accompanying the current talk can be found in the PEPM'04 proceedings. The reader may also want to consult one of the good surveys on program generation, examining the topic either from an applied perspective [3] or from a partial evaluation perspective [2]. Yannis Smaragdakis |
PPDP | 1 |
| 2004 | Program Generators and the Tools to Make Them
Yannis Smaragdakis |
SAS | 1 |
| 2004 | Functional programming with the FC++ libraryabstractWe describe the FC++ library, a rich library supporting functional programming in C++. Prior approaches to encoding higher order functions in C++ have suffered with respect to polymorphic functions from either lack of expressiveness or high complexity. In contrast, FC++ offers full and concise support for higher-order polymorphic functions through a novel use of C++ type inference. The FC++ library has a number of useful features, including a generalized mechanism to implement currying in C++, a “lazy list” class which enables the creation of “infinite data structures”, a subtype polymorphism facility, and an extensive library of useful functions, including a large part of the Haskell Standard Prelude. The FC++ library has an efficient implementation. We show the results of a number of experiments which demonstrate the value of optimizations we have implemented. These optimizations have improved the run-time performance by about an order of magnitude for some benchmark programs that make heavy use of FC++ lazy lists. We also make an informal performance comparison with similar programs written in Haskell. Brian McNamara, Yannis Smaragdakis |
J. Funct. Program. | 2 |
| 2004 | JCrasher: an automatic robustness tester for JavaabstractAbstract JCrasher is an automatic robustness testing tool for Java code. JCrasher examines the type information of a set of Java classes and constructs code fragments that will create instances of different types to test the behavior of public methods under random data. JCrasher attempts to detect bugs by causing the program under test to ‘crash’, that is, to throw an undeclared runtime exception. Although in general the random testing approach has many limitations, it also has the advantage of being completely automatic: o supervision is required except for off‐line inspection of the test ases that have caused a crash. Compared to other similar commercial and research tools, JCrasher offers several novelties: it transitively analyzes methods, determines the size of each tested method's parameter‐space and selects parameter combinations and therefore test cases at random, taking into account the time allocated for testing; it defines heuristics for determining whether a Java exception should be considered as a program bug or whether the JCrasher supplied inputs have violated the code's preconditions; it includes support for efficiently undoing all the state changes introduced by previous tests; it produces test files for JUnit, a popular Java testing tool; and it can be integrated in the Eclipse IDE. Copyright © 2004 John Wiley & Sons, Ltd. Christoph Csallner, Yannis Smaragdakis |
Softw. Pract. Exp. | 2 |
| 2003 | NRMI: Natural and Efficient MiddlewareabstractWe present NRMI: a drop-in replacement of Java RMI that offers call-by-copy-restore semantics for arbitrary linked data structures, in addition to regular call-by-copy semantics. Call-by-copy-restore middleware is more natural to use than traditional call-by-copy RPC mechanisms, enabling distributed calls to behave much like local calls. We discuss in depth the effect of calling semantics for middleware, describe how call-by-copy-restore can be implemented efficiently, and show examples of Java programs where NRMI is more convenient than regular Java RMI. Eli Tilevich, Yannis Smaragdakis |
ICDCS | 2 |
| 2003 | Aspectizing Server-Side DistributionabstractWe discuss how a collection of domain-specific and domain-independent tools can be combined to "aspectize" the distributed character of server-side applications, to a much greater extent than with prior efforts. Specifically, we present a framework that can be used with a large class of unaware applications to turn their objects into distributed objects with minimal programming effort. Our framework is developed on top of three main components: AspectJ (a high-level aspect language), XDoclet (a low-level aspect language), and NRMI (a middleware facility that makes remote calls behave more like local calls). We discuss why each of the three components offers unique advantages and is necessary for an elegant solution, why our approach is general, and how it constitutes a significant improvement over past efforts to isolate distribution concerns. Eli Tilevich, Stephan Urbanski, Yannis Smaragdakis, Marc J. Fleury |
ASE | 3 |
| 2003 | The EELRU adaptive replacement algorithm
Yannis Smaragdakis, Scott F. Kaplan, Paul R. Wilson 0001 |
Perform. Evaluation | 1 |
| 2002 | J-Orchestra: Automatic Java Application Partitioning
Eli Tilevich, Yannis Smaragdakis |
ECOOP | 2 |
| 2002 | Layered Development with (Unix) Dynamic Libraries
Yannis Smaragdakis |
ICSR | 1 |
| 2002 | FC++: Functional tools for object-oriented tasksabstractAbstract FC++ is a library for programming functionally in C++. Compared to other C++ functional programming libraries, FC++ is distinguished by its powerful type system which allows the manipulation of parametrically polymorphic functions (e.g., passing them as arguments to other functions and returning them as results). In this paper, we show how FC++ can be used in common object‐oriented programming tasks. We demonstrate FC++ implementations of several common design patterns (Adapter, Builder, Command, and more). Compared to conventional C++ implementations of these patterns, our implementations are either simpler (in that fewer classes/dependencies are needed), more efficient, or more type‐safe (thanks to parametric polymorphism and type inference). Copyright © 2002 John Wiley & Sons, Ltd. Yannis Smaragdakis, Brian McNamara |
Softw. Pract. Exp. | 1 |
| 2002 | Mixin layers: an object-oriented implementation technique for refinements and collaboration-based designsabstractA "refinement" is a functionality addition to a software project that can affect multiple dispersed implementation entities (functions, classes, etc.). In this paper, we examine large-scale refinements in terms of a fundamental object-oriented technique called collaboration-based design. We explain how collaborations can be expressed in existing programming languages or can be supported with new language constructs (which we have implemented as extensions to the Java language). We present a specific expression of large-scale refinements called mixin layers , and demonstrate how it overcomes the scalability difficulties that plagued prior work. We also show how we used mixin layers as the primary implementation technique for building an extensible Java compiler, JTS. Yannis Smaragdakis, Don S. Batory |
ACM Trans. Softw. Eng. Methodol. | 1 |
| 2000 | Functional programming in C++abstractThis paper describes FC++: a rich library supporting functional programming in C++. Prior approaches to encoding higher order functions in C++ have suffered with respect to polymorphic functions from either lack of expressiveness or high complexity. In contrast, FC++ offers full and concise support for higher-order polymorphic functions through a novel use of C++ type inference.Another new element in FC++ is that it implements a subtype polymorphism policy for functions, in addition to the more common parametric polymorphism facilities. Subtype polymorphism is common in object oriented languages and ensures that functions in FC++ fit well within the C++ object model.Apart from these conceptual differences, FC++ is also an improvement in technical terms over previous efforts in the literature. Our function objects are reference-counted and can be aliased without needing to be copied, resulting in an efficient implementation. The reference-counting mechanism is also exported to the user as a general-purpose replacement of native C++ pointers. Finally, we supply a number of useful functional operators (a large part of the Haskell Standard Prelude) to facilitate programming with FC++. The end result is a library that is usable and efficient, while requiring no extensions to the base C++ language. Brian McNamara, Yannis Smaragdakis |
ICFP | 2 |
| 2000 | Object-oriented frameworks and product lines
Don S. Batory, Richard Cardone, Yannis Smaragdakis |
SPLC | 3 |
| 2000 | Performing Replacement in Modem Pools
Yannis Smaragdakis, Paul R. Wilson 0001 |
USENIX ATC, General Track | 1 |
| 1999 | Trace Reduction for Virtual Memory SimulationsabstractThe unmanageably large size of reference traces has spurred the development of sophisticated trace reduction techniques. In this paper we presenttwonew algorithms for trace reduction --- Safely Allowed Drop (SAD) and Optimal LRU Reduction (OLR). Both achieve high reduction factors and guarantee exact simulations for common replacement policies and for memories larger than a user-defined threshold. In particular, simulation on OLR-reduced traces is accurate for the LRU replacement algorithm, while simulation on SAD-reduced traces is accurate for the LRU and OPT algorithms. OLR also satisfies an optimality property: for a given trace and memory size it produces the shortest possible trace that has the same LRU behavior as the original for a memory of at least this size. Our approach has multiple applications, especially in simulating virtual memory systems Scott F. Kaplan, Yannis Smaragdakis, Paul R. Wilson 0001 |
SIGMETRICS | 2 |
| 1999 | EELRU: Simple and Effective Adaptive Page ReplacementabstractDespite the many replacement algorithms proposed throughout the years, approximations of Least Recently Used (LRU) replacement are predominant in actual virtual memory management systems because of their simplicity and efficiency.LRU, however, exhibits well-known performance problems for regular access patterns over more pages than the main memory can hold (e.g., large loops).In this paper we present Early Eviction LRU (EELRU).EELRU is a simple adaptive replacement algorithm, which uses only the kind of information needed by LRU-how recently each page has been touched relative to the others.It exploits this information more effectively than LRU, using a simple on-line cost/benefit analysis to guide its replacement decisions.In the very common situations where LRU is good, EELRU is good because it behaves like LRU.In common worst cases for LRU, EELRU is significantly better, and in fact close to optimal as it opts to sacrifice some pages to allow others to stay in memory longer.Overall, in its worst case, EELRU cannot be more than a constant factor worse than LRU, while LRU can be worse than EELRU by a factor almost equal to the number of pages in memory.In simulation experiments with a variety of programs and wide ranges of memory sizes, we show that EELRU does in fact outperform LRU, typically reducing misses by ten to thirty percent, and occasionally by much more-sometimes by a factor of two to ten.It rarely performs worse than LRU, and then only by a small amount.Overall, EELRU demonstrates several principles which could be widely useful for adaptive page replacement algorithms:(1) it adapts to changes in program behavior, distinguishing important behavior characteristics for each workload.In particular, EELRU is not affected by highfrequency behavior (e.g., loops much smaller than the memory size) as such behavior may obscure important largescale regularities;(2) EELRU chooses pages to evict in a way that respects both the memory size and the aggregate memory-referencing behavior of the program; (3) depending Yannis Smaragdakis, Scott F. Kaplan, Paul R. Wilson 0001 |
SIGMETRICS | 1 |
| 1999 | The Case for Compressed Caching in Virtual Memory Systems
Paul R. Wilson 0001, Scott F. Kaplan, Yannis Smaragdakis |
USENIX ATC, General Track | 3 |
| 1999 | Architectural Styles as Adaptors
Don S. Batory, Yannis Smaragdakis, Lou Coglianese |
WICSA | 2 |
| 1998 | Implementing Layered Designs with Mixin Layers
Yannis Smaragdakis, Don S. Batory |
ECOOP | 1 |
| 1998 | JTS: tools for implementing domain-specific languagesabstractThe Jakarta Tool Suite (JTS) aims to reduce substantially the cost of generator development by providing domain-independent tools for creating domain-specific languages and component-based generators called GenVoca generators. JTS is a set of precompiler-compiler tools for extending industrial programming languages (e.g., Java) with domain-specific constructs. JTS is itself a GenVoca generator where precompilers for JTS-extended languages are constructed from components. Don S. Batory, Bernie J. Lofaso, Yannis Smaragdakis |
ICSR | 3 |
| 1998 | Implementing reusable object-oriented componentsabstractObject oriented (OO) classes are generally not reusable because they are not meaningful in isolation; most classes only have meaning as members of cooperating suites of classes (e.g., design patterns). These suites usually arise in designs, but rarely exist as encapsulated entities in OO implementations. We present a method for directly mapping cooperating suites of classes into encapsulated C++ implementations. Our method is an improvement over the VanHilst and Notkin approach (M. VanHilst and D. Notkin, 1996) for implementing collaboration based designs and constitutes a step towards more reusable (object oriented) components. Yannis Smaragdakis, Don S. Batory |
ICSR | 1 |