SUMMARYReaching the best level of runtime performance from a high‐level, object‐oriented language is often considered challenging if not unattainable. The closed‐world assumption involves considering all of the source code of an application together at compile time. That assumption makes it possible to produce an efficient code. For instance, multiple inheritance can be implemented as efficiently as single inheritance. Our compilation strategy is the result of a prolonged project, tying together several compilation techniques: call graph analysis, dead code elimination, type flow analysis, code customization, implementation of dynamic dispatch, inlining, pointer optimization, switch optimization, objects layout, and so on. Merging all of these techniques into a global strategy appears to be quite problematic. Throughout the paper, two real‐world compilers are used as benchmarks to provide measurements for compiler writers to evaluate the applicability of our approach. Type flow analysis is a fundamental aspect of our strategy to resolve method calls. We have extended type flow analysis to deal with the content of arrays, enabling us to process additional expressions and thus making it possible to obtain a true global analysis. Typically, more than 90% of method call sites are statically resolved. Our experience indicates that the closed‐world assumption is suitable for numerous applications. Surprisingly, even library‐defined control statements from dynamic languages are perfectly processed with our strategy. The Smalltalk ifTrue:ifFalse:, whileTrue:, to:do:, and so on are, for the very first time, perfectly translated. Copyright © 2012 John Wiley & Sons, Ltd.
A widespread practice to implement a flexible array is to consider the storage area into two parts: the used area, which is already available for read/write operations, and the supply area, which is used in case of enlargement of the array. The main purpose of the supply area is to avoid as much as possible the reallocation of the whole storage area in case of enlargement. As the supply area is not used by the application, the main idea of the paper is to convey the information to the garbage collector, making it possible to avoid completely the marking of the supply area. We also present a simple method to analyze the types of objects, which are stored in an array as well as the possible presence of NULL values within the array. This allows us to better specialize the work of the garbage collector when marking the used area, and also, by transitivity, to improve overall results for type analysis of all expressions of the source code. After introducing several abstract data types, which represent the main arrays concerned by our technique (i.e., zero or variable indexing, circular arrays and hash maps), we measure its impact during the bootstrap of two compilers whose libraries are equipped with these abstract data types. We then measure, on various software products we have not written, the frequency of certain habits of manipulation of arrays, to assess the validity of our approach. Copyright EXPLOITING ARRAY MANIPULATION HABITS 1641 Create(cap) The creation operation to be used in order to prepare a new empty array with a given capacity cap: assert (cap >= 0); capacity = cap; size = 0; storage = malloc(cap); Extend(obj) To extend by one the array on its right, writing obj in the new slot. In case of reallocation (i.e. when the supply area is empty), the capacity is increased twofold:if ( size >= capacity ) { capacity = capacity * 2; storage = realloc(storage, capacity); } storage[size] = obj; size = size + 1; Read(ind)This function returns the object stored at index ind assuming that the index is correct, that is, a valid index in the used area:Write(ind, obj) Change the value at index ind using obj for the replacement, assuming that the ind is a valid index in the used area: assert ((0 <= ind) && (ind < size)); storage[ind] = obj; order of statements. For instance, using all the reachable assignments in a variable, we compute all the possible types for that variable. The analysis is flow insensitive, that is, the order of reachable assignments does not matter. We consider on the whole the set of reachable assignments.Concerning instance variables, we do not discriminate between the different instances from the same class (Figure 2); the type information is identical for all instances of a given class. For a formal method argument, we use the set of reachable effective arguments, that is, all reachable calls. Classically, to obtain the set of dynamic types of a given method call, we consider all the methods EXPLOITING ARRAY MANIPULATION HABITS 1645 Note that it is not necessary to reset with NULL the cell that...
scite is a Brooklyn-based organization that helps researchers better discover and understand research articles through Smart Citations–citations that display the context of the citation and describe whether the article provides supporting or contrasting evidence. scite is used by students and researchers from around the world and is funded in part by the National Science Foundation and the National Institute on Drug Abuse of the National Institutes of Health.
hi@scite.ai
10624 S. Eastern Ave., Ste. A-614
Henderson, NV 89052, USA
Copyright © 2024 scite LLC. All rights reserved.
Made with 💙 for researchers
Part of the Research Solutions Family.