mirror of
https://github.com/golang/go
synced 2024-11-19 01:34:40 -07:00
3b5de067a1
Core: reflect.TypeOf reflect.ValueOf reflect.Zero reflect.Value.Interface Maps: (reflect.Value).MapIndex (reflect.Value).MapKeys (reflect.Value).SetMapIndex (*reflect.rtype).Elem (*reflect.rtype).Key + tests: pointer/testdata/mapreflect.go. oracle/testdata/src/main/reflection.go. Interface objects (T, V...) have been renamed "tagged objects". Abstraction: we model reflect.Value similar to interface{}---as a pointer that points only to tagged objects---but a reflect.Value may also point to an "indirect tagged object", one in which the payload V is of type *T not T. These are required because reflect.Values can hold lvalues, e.g. when derived via Field() or Elem(), though we won't use them till we get to structs and pointers. Solving: each reflection intrinsic defines a new constraint and resolution rule. Because of the nature of reflection, generalizing across types, the resolution rules dynamically create additional complex constraints during solving, where previously only simple (copy) constraints were created. This requires some solver changes: The work done before the main solver loop (to attach new constraints to the graph) is now done before each iteration, in processNewConstraints. Its loop over constraints is broken into two passes: the first handles base (addr-of) constraints, the second handles simple and complex constraints. constraint.init() has been inlined. The only behaviour that varies across constraints is ptr() Sadly this will pessimize presolver optimisations, when we get there; such is the price of reflection. Objects: reflection intrinsics create objects (i.e. cause memory allocations) with no SSA operation. We will represent them as the cgnode of the instrinsic (e.g. reflect.New), so we extend Labels and node.data to represent objects as a product (not sum) of ssa.Value and cgnode and pull this out into its own type, struct object. This simplifies a number of invariants and saves space. The ntObject flag is now represented by obj!=nil; the other flags are moved into object. cgnodes are now always recorded in objects/Labels for which it is appropriate (all but those for globals, constants and the shared contours for functions). Also: - Prepopulate the flattenMemo cache to consider reflect.Value a fake pointer, not a struct. - Improve accessors and documentation on type Label. - @conctypes assertions renamed @types (since dyn. types needn't be concrete). - add oracle 'describe' test on an interface (missing, an oversight). R=crawshaw CC=golang-dev https://golang.org/cl/13418048
50 lines
2.0 KiB
Plaintext
50 lines
2.0 KiB
Plaintext
-*- text -*-
|
|
|
|
Pointer analysis to-do list
|
|
===========================
|
|
|
|
CONSTRAINT GENERATION:
|
|
- support reflection
|
|
- implement native intrinsics. These vary by platform.
|
|
- unsafe.Pointer conversions. Three options:
|
|
1) unsoundly (but type-safely) treat p=unsafe.Pointer(x) conversions as
|
|
allocations, losing aliases. This is what's currently implemented.
|
|
2) unsoundly (but type-safely) treat p=unsafe.Pointer(x) and T(p)
|
|
conversions as interface boxing and unboxing operations.
|
|
This may preserve some aliasing relations at little cost.
|
|
3) soundly track physical field offsets. (Summarise dannyb's email here.)
|
|
A downside is that we can't keep the identity field of struct
|
|
allocations that identifies the object.
|
|
|
|
PRESOLVER OPTIMISATIONS
|
|
- use HVN, HRU, LE, PE, HCD, LCD.
|
|
But: LE would lose the precise detail we currently enjoy in each label.
|
|
|
|
SOLVER:
|
|
- use BDDs and/or sparse bitvectors for ptsets
|
|
- use sparse bitvectors for graph edges
|
|
- use BDD-based relational composition for e.g. offset computations.
|
|
- experiment with different worklist algorithms:
|
|
priority queue (solver visit-time order)
|
|
red-black tree (node id order)
|
|
double-ended queue (insertion order)
|
|
fast doubly-linked list (See Zhanh et al PLDI'13)
|
|
(insertion order with fast membership test)
|
|
dannyb recommends sparse bitmap.
|
|
|
|
API:
|
|
- Rely less on callbacks and more on a 'result' type
|
|
returned by Analyze().
|
|
- Abstract the callgraph into a pure interface so that
|
|
we can provide other implementations in future (e.g. RTA-based).
|
|
Also provide the option to eliminate context-sensitivity
|
|
in a callgraph to yield a smaller (less precise) callgraph.
|
|
- Some optimisations (e.g. LE, PE) may change the API.
|
|
Think about them sooner rather than later.
|
|
- Eliminate Print probe now that we can query specific ssa.Values.
|
|
|
|
Misc:
|
|
- os.Args should point to something; currently they don't.
|
|
- Test on all platforms.
|
|
Currently we assume these go/build tags: linux, amd64, !cgo.
|