-
Notifications
You must be signed in to change notification settings - Fork 424
Prepack Concepts
Add examples.
By default, Prepack only attempts to analyze and optimize the global code. All referenced functions, e.g. callbacks that get installed, are called "residual function". Prepack does not attempt to analyze and optimize them by default. Prepack simply carries them over into the prepacked code, only doing some simple replacements/renamings in their bodies to reflect changes in the optimized code.
If you want to avoid that Prepack analyzes and optimizes code in an otherwise analyzed and optimized code block, use __residual
or __residual_unsafe
.
Besides concrete values, Prepack can keep track of abstract values. An abstract value is a value that is not fully known at prepack time.
More information:
Create abstract values from interpreted code via __abstract
, __abstractOrNull
, __abstractOrNullOrUndefined
, __abstractOrUndefined
. Use __isAbstract
to check if a value is abstract.
__assumeDataProperty
A simple object has no property getters or setters. When unknown properties of a simple abstract object are accesses, Prepack returns fresh abstract values.
More information:
Use __makeSimple
to make an object simple.
Prepack raises an error when accessing absent properties on objects marked as partial.
More information:
Use __makePartial
to make an object partial.
Any attempt to perform mutations on a final object is an error.
This is similar to a frozen object, but doesn't generate an actual Object.freeze
call.
Use __makeFinal
to make an object final.
JavaScript is a very dynamic language, and it is generally difficult to statically predict what side effects some JavaScript code might have.
Prepack can evaluate code in a special mode, a "pure scope", where it makes some optimistic assumptions (see Compiler assumptions).
Code evaluated in a "pure scope" can have side effects, as long as Prepack can directly discover them by interpreting the known code.
Invoke via __evaluatePureFunction
; optimized functions are also evaluated in a pure scope.
When an abstract function is invoked, Prepack doesn't know what side effects that function might have.
In general, Prepack make one significant assumption: the abstract function may not mutate any built-ins (Objects provided by, or reachable only via, the global
object.)
Currently, Prepack does one of two things:
- In a "pure scope", Prepack considers all bindings and objects reachable from the immediate call arguments as "leaked", and Prepack "havocs" them. This means that Prepack allows the function to mutate bindings and reachable objects, and any subsequent reads will have unknown values, and Prepack will generate code that reads the latest value from memory. When generating code, Prepack will also ensure that all leaking bindings and objects have the values as they were at the time of the call.
- Otherwise, Prepack insists that the arguments of the function are frozen if they are objects. In any case, Prepack assumes that no objects known to Prepack are mutated by the function call.
By default, Prepack only optimizes the global code. You can instruct Prepack to optimize particular functions. Prepack evaluates those function in a "pure scope", making certain assumptions about the function's behavior, and assuming that the state of all built-ins at the time when the optimized function gets called is exactly the same state as it was at the end of global code evaluation.
More information:
Use __optimize
in analyzed code to instruct Prepack to optimize a function.
“Effects” is an internal data-structure that encodes anything a piece of JavaScript code (an AST node) could have done.
More information: