use AtomicLowPtr<Class> in NamedEntity>
[hiphop-php.git] / hphp / hhbbc / index.h
blob717a5948046d6dc701649e471ea40b8259cb263d
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2015 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
16 #ifndef incl_HHBBC_INDEX_H_
17 #define incl_HHBBC_INDEX_H_
19 #include <memory>
20 #include <mutex>
21 #include <tuple>
22 #include <vector>
23 #include <map>
25 #include <boost/variant.hpp>
26 #include <tbb/concurrent_hash_map.h>
28 #include <folly/Optional.h>
29 #include <folly/Hash.h>
31 #include "hphp/util/either.h"
32 #include "hphp/runtime/base/repo-auth-type-array.h"
33 #include "hphp/runtime/vm/type-constraint.h"
35 #include "hphp/hhbbc/hhbbc.h"
36 #include "hphp/hhbbc/misc.h"
38 namespace HPHP { namespace HHBBC {
40 //////////////////////////////////////////////////////////////////////
42 struct Type;
43 struct Index;
44 struct PublicSPropIndexer;
46 namespace php {
47 struct Class;
48 struct Func;
49 struct Unit;
50 struct Program;
53 //////////////////////////////////////////////////////////////////////
56 * This module contains functions for building and querying an Index
57 * of data relating to "resolved" versions of the names in of a
58 * php::Program. It also records dependencies so it is possible to
59 * tell which parts of the program may be interested in new inferred
60 * information about other parts of the program.
62 * The main entry point here is the Index class. The Index is built
63 * after parse time, and then analysis can query it for information.
66 //////////////////////////////////////////////////////////////////////
69 * A Context is a (unit, func, class) triple, where cls and func
70 * fields may be null in some situations. Most queries to the Index
71 * need a "context", to allow recording dependencies.
73 struct Context { borrowed_ptr<php::Unit> unit;
74 borrowed_ptr<php::Func> func;
75 borrowed_ptr<php::Class> cls; };
77 inline bool operator==(Context a, Context b) {
78 return a.unit == b.unit && a.func == b.func && a.cls == b.cls;
81 inline bool operator<(Context a, Context b) {
82 return std::make_tuple(a.unit, a.func, a.cls) <
83 std::make_tuple(b.unit, b.func, b.cls);
86 std::string show(Context);
89 * Context for a call to a function. This means the types and number
90 * of arguments, and where it is being called from.
92 * TODO(#3788877): add type of $this if it is going to be an object
93 * method, and the LSB class type if static.
95 struct CallContext {
96 Context caller;
97 std::vector<Type> args;
100 inline bool operator==(const CallContext& a, const CallContext& b) {
101 return a.caller == b.caller &&
102 a.args == b.args;
106 * State of properties on a class. Map from property name to its
107 * Type.
109 using PropState = std::map<SString,Type>;
111 //////////////////////////////////////////////////////////////////////
113 // private types
114 struct IndexData;
115 struct FuncFamily;
116 struct FuncInfo;
117 struct ClassInfo;
119 //////////////////////////////////////////////////////////////////////
122 * References to "resolved" entities with information in the index are
123 * in the res:: namespace.
125 * These represent handles to program entities that may have variable
126 * amounts of information. For example, we may know the name of a
127 * class in a res::Class, but do not know for sure which php::Class
128 * struct is actually associated with it.
130 namespace res {
133 * A resolved runtime Class, for a particular php::Class.
135 * Provides various lookup tables that allow querying the Class'
136 * information.
138 struct Class {
140 * Returns whether two classes are definitely same at runtime. If
141 * this function returns false, they still *may* be the same at
142 * runtime.
144 bool same(const Class&) const;
147 * Returns true if this class is definitely going to be a subtype
148 * of `o' at runtime. If this function returns false, this may
149 * still be a subtype of `o' at runtime, it just may not be known.
150 * A typical example is with "non unique" classes.
152 bool subtypeOf(const Class& o) const;
155 * If this function return false, it is known that this class
156 * is in no subtype relationship with the argument Class 'o'.
157 * Returns true if this class could be a subtype of `o' at runtime.
158 * When true is returned the two classes may still be unrelated but it is
159 * not possible to tell. A typical example is with "non unique" classes.
161 bool couldBe(const Class& o) const;
164 * Returns the name of this class. Non-null guarantee.
166 SString name() const;
169 * Whether this class could possibly be an interface or a trait.
171 * When returning false, it is known that this class is not an interface
172 * or a trait. When returning true, it's possible that this class is not
173 * an interface or trait but the system cannot tell.
175 bool couldBeInterfaceOrTrait() const;
178 * Returns whether this type has the no override attribute, that is, if it
179 * is a final class (explicitly marked by the user or known by the static
180 * analysis).
182 * When returning false the class is guaranteed to be final. When returning
183 * true the system cannot tell though the class may still be final.
185 bool couldBeOverriden() const;
188 * Whether this class (or its subtypes) could possibly have have
189 * certain magic methods.
191 bool couldHaveMagicGet() const;
194 * Returns the Class that is the first common ancestor between 'this' and 'o'.
195 * If there is no common ancestor folly::none is returned
197 folly::Optional<Class> commonAncestor(const Class& o) const;
199 private:
200 Class(borrowed_ptr<const Index>, Either<SString,borrowed_ptr<ClassInfo>>);
202 private:
203 friend std::string show(const Class&);
204 friend struct ::HPHP::HHBBC::Index;
205 friend struct ::HPHP::HHBBC::PublicSPropIndexer;
206 borrowed_ptr<const Index> index;
207 Either<SString,borrowed_ptr<ClassInfo>> val;
211 * This is an abstraction layer to represent possible runtime function
212 * resolutions.
214 * Internally, this may only know the name of the function (or method), or we
215 * may know exactly which source-code-level function it refers to, or we may
216 * only have ruled it down to one of a few functions in a class hierarchy. The
217 * interpreter can treat all these cases the same way using this.
219 struct Func {
221 * Returns whether two res::Funcs definitely mean the func at
222 * runtime.
224 * Note: this is potentially pessimistic for its use in ActRec state
225 * merging right now, but not incorrect.
227 bool same(const Func&) const;
230 * Returns the name of this function. Non-null guarantee.
232 SString name() const;
235 * Returns whether this resolved function could possibly be going through a
236 * magic call, in the magic way.
238 * That is, if was resolved as part of a direct call to an __call method,
239 * this will say true. If it was resolved as part as some normal method
240 * call, and we haven't proven that there's no way an __call dispatch could
241 * be involved, this will say false.
243 bool cantBeMagicCall() const;
245 private:
246 friend struct ::HPHP::HHBBC::Index;
247 struct FuncName {
248 bool operator==(FuncName o) const { return name == o.name; }
249 SString name;
251 struct MethodName {
252 bool operator==(MethodName o) const { return name == o.name; }
253 SString name;
255 using Rep = boost::variant< FuncName
256 , MethodName
257 , borrowed_ptr<FuncInfo>
258 , borrowed_ptr<FuncFamily>
261 private:
262 Func(borrowed_ptr<const Index>, Rep);
263 friend std::string show(const Func&);
265 private:
266 borrowed_ptr<const Index> index;
267 Rep val;
271 * Produce a trace-able string for a res::Func or res::Class.
273 std::string show(const Func&);
274 std::string show(const Class&);
278 //////////////////////////////////////////////////////////////////////
281 * This class encapsulates the known facts about the program, with a
282 * whole-program view.
284 * This structure contains unowned pointers into the php::Program it
285 * was created for. It should not out-live the Program.
287 * The const member functions of this class are thread safe for
288 * concurrent reads and writes. The non-const functions should be
289 * called in a single threaded context only (they are used during the
290 * "update" step in between whole program analysis rounds).
292 struct Index {
294 * Create an Index for a php::Program. Performs some initial
295 * analysis of the program.
297 explicit Index(borrowed_ptr<php::Program>);
300 * This class must not be destructed after its associated
301 * php::Program.
303 ~Index();
306 * The index operates in two modes: frozen, and unfrozen.
308 * Conceptually, the index is mutable and may acquire new
309 * information until it has been frozen, and once frozen, it retains
310 * the information it had at the point it was frozen.
312 * The reason this exists is because certain functions on the index
313 * may cause it to need to consult information in the bodies of
314 * functions other than the Context passed in. Specifically, if the
315 * interpreter tries to look up the return type for a callee in a
316 * given CallContext, the index may choose to recursively invoke
317 * type inference on that callee's function body to see if more
318 * precise information can be determined, unless it is frozen.
320 * This is fine until the final pass, because all bytecode is
321 * read-only at that stage. However, in the final pass, other
322 * threads might be optimizing a callee's bytecode and changing it,
323 * so we should not be reading from it to perform type inference
324 * concurrently. Freezing the index tells it it can't do that
325 * anymore.
327 * These are the functions to query and transition to frozen state.
329 bool frozen() const;
330 void freeze();
333 * The Index contains a Builder for an ArrayTypeTable.
335 * If we're creating assert types with options.InsertAssertions, we
336 * need to keep track of which array types exist in the whole
337 * program in order to include it in the repo.
339 std::unique_ptr<ArrayTypeTable::Builder>& array_table_builder() const;
342 * Find all the closures created inside the context of a given
343 * php::Class.
345 std::vector<borrowed_ptr<php::Class>>
346 lookup_closures(borrowed_ptr<const php::Class>) const;
349 * Try to resolve which class will be the class named `name' from a
350 * given context, if we can resolve it to a single class.
352 * Note, the returned class may or may not be *defined* at the
353 * program point you care about (it could be non-hoistable, even
354 * though it's unique, for example).
356 * Returns folly::none if we can't prove the supplied name must be a
357 * object type. (E.g. if there are type aliases.)
359 folly::Optional<res::Class> resolve_class(Context, SString name) const;
362 * Resolve a closure class.
364 * Returns both a resolved Class, and the actual php::Class for the
365 * closure. This function should only be used with class names are
366 * guaranteed to be closures (for example, the name supplied to a
367 * CreateCl opcode).
369 std::pair<res::Class,borrowed_ptr<php::Class>>
370 resolve_closure_class(Context ctx, SString name) const;
373 * Return a resolved class for a builtin class.
375 * Pre: `name' must be the name of a class defined in a systemlib.
377 res::Class builtin_class(SString name) const;
380 * Try to resolve a function named `name' from a given context.
382 * Note, the returned function may or may not be defined at the
383 * program point (it could require a function autoload that might
384 * fail).
386 res::Func resolve_func(Context, SString name) const;
389 * Try to resolve a function using namespace-style fallback lookup.
391 * The name `name' is tried first, and `fallback' is used if this
392 * isn't found. Both names must already be namespace-normalized.
393 * Resolution can fail because there are possible situations where
394 * we don't know which will be called at runtime.
396 * Note: the returned function may or may not be defined at the
397 * program point (it could require a function autoload that might
398 * fail).
400 folly::Optional<res::Func> resolve_func_fallback(Context,
401 SString name,
402 SString fallback) const;
405 * Try to resolve a class method named `name' with a given Context
406 * and class type.
408 * Pre: clsType.subtypeOf(TCls)
410 res::Func resolve_method(Context, Type clsType, SString name) const;
413 * Try to resolve a class constructor for the supplied class.
415 * Returns: folly::none if we can't figure out which constructor
416 * this would call.
418 folly::Optional<res::Func> resolve_ctor(Context, res::Class) const;
421 * Give the Type in our type system that matches an hhvm
422 * TypeConstraint, subject to the information in this Index.
424 * This function returns a subtype of Cell, although TypeConstraints
425 * at runtime can match reference parameters. The caller should
426 * make sure to handle that case.
428 * For soft constraints (@), this function returns Cell.
430 * For some non-soft constraints (such as "Stringish"), this
431 * function may return a Type that is a strict supertype of the
432 * constraint's type.
434 Type lookup_constraint(Context, const TypeConstraint&) const;
437 * If this function returns true, it is safe to assume that Type t
438 * will always satisfy TypeConstraint tc at run time.
440 bool satisfies_constraint(Context, Type t, const TypeConstraint& tc) const;
443 * Lookup what the best known Type for a class constant would be,
444 * using a given Index and Context, if a class of that name were
445 * loaded.
447 Type lookup_class_constant(Context, res::Class, SString cns) const;
450 * Return the best known return type for a resolved function, in a
451 * context insensitive way. Returns TInitGen at worst.
453 Type lookup_return_type(Context, res::Func) const;
456 * Return the best known return type for a resolved function, given
457 * the supplied calling context. Returns TInitGen at worst.
459 * During analyze phases, this function may re-enter analyze in
460 * order to interpret the callee with these argument types.
462 Type lookup_return_type(CallContext, res::Func) const;
465 * Look up the return type for an unresolved function. The
466 * interpreter should not use this routine---it's for stats or debug
467 * dumps.
469 * Nothing may be writing to the index when this function is used,
470 * but concurrent readers are allowed.
472 Type lookup_return_type_raw(borrowed_ptr<const php::Func>) const;
475 * Return the best known types of a closure's used variables (on
476 * entry to the closure). The function is the closure body.
478 std::vector<Type>
479 lookup_closure_use_vars(borrowed_ptr<const php::Func>) const;
482 * Return the availability of $this on entry to the provided method.
483 * If the Func provided is not a method of a class false is
484 * returned.
486 bool lookup_this_available(borrowed_ptr<const php::Func>) const;
489 * Returns the parameter preparation kind (if known) for parameter
490 * `paramId' on the given resolved Func.
492 PrepKind lookup_param_prep(Context, res::Func, uint32_t paramId) const;
495 * Returns the control-flow insensitive inferred private instance
496 * property types for a Class. The Class doesn't need to be
497 * resolved, because private properties don't depend on the
498 * inheritance hierarchy.
500 * The Index tracks the largest types for private properties that
501 * are guaranteed to hold at any program point.
503 PropState lookup_private_props(borrowed_ptr<const php::Class>) const;
506 * Returns the control-flow insensitive inferred private static
507 * property types for a Class. The class doesn't need to be
508 * resolved for the same reasons as for instance properties.
510 * The Index tracks the largest types for private static properties
511 * that are guaranteed to hold at any program point.
513 PropState lookup_private_statics(borrowed_ptr<const php::Class>) const;
516 * Lookup the best known type for a public static property, with a given
517 * class and name.
519 * This function will always return TInitGen before refine_public_statics has
520 * been called, or if the AnalyzePublicStatics option is off.
522 Type lookup_public_static(Type cls, Type name) const;
523 Type lookup_public_static(borrowed_ptr<const php::Class>, SString name) const;
526 * Returns whether a public static property is known to be immutable. This
527 * is used to add AttrPersistent flags to static properties, and relies on
528 * AnalyzePublicStatics (without this flag it will always return false).
530 bool lookup_public_static_immutable(borrowed_ptr<const php::Class>,
531 SString name) const;
534 * Returns the computed vtable slot for the given class, if it's an interface
535 * that was given a vtable slot. No two interfaces implemented by the same
536 * class will share the same vtable slot. May return kInvalidSlot, if the
537 * given class isn't an interface or if it wasn't assigned a slot.
539 Slot lookup_iface_vtable_slot(borrowed_ptr<const php::Class>) const;
542 * Refine the return type for a function, based on a round of
543 * analysis.
545 * No other threads should be calling functions on this Index when
546 * this function is called.
548 * Returns: the set of Contexts that depended on the return type of
549 * this php::Func.
551 std::vector<Context> refine_return_type(borrowed_ptr<const php::Func>, Type);
554 * Refine the used var types for a closure, based on a round of
555 * analysis.
557 * No other threads should be calling functions on this Index when
558 * this function is called.
560 * Returns: true if the types have changed.
562 bool refine_closure_use_vars(borrowed_ptr<const php::Class>,
563 const std::vector<Type>&);
566 * Refine the private property types for a class, based on a round
567 * of analysis.
569 * No other threads should be calling functions on this Index when
570 * this function is called.
572 void refine_private_props(borrowed_ptr<const php::Class> cls,
573 const PropState&);
576 * Refine the static private property types for a class, based on a
577 * round of analysis.
579 * No other threads should be calling functions on this Index when
580 * this function is called.
582 void refine_private_statics(borrowed_ptr<const php::Class> cls,
583 const PropState&);
586 * After a whole program pass using PublicSPropIndexer, the types can be
587 * reflected into the index for use during another type inference pass.
589 * No other threads should be calling functions on this Index or on the
590 * provided PublicSPropIndexer when this function is called.
592 void refine_public_statics(const PublicSPropIndexer&);
594 private:
595 Index(const Index&) = delete;
596 Index& operator=(Index&&) = delete;
598 private:
599 template<class FuncRange>
600 res::Func resolve_func_helper(const FuncRange&, SString) const;
601 res::Func do_resolve(borrowed_ptr<const php::Func>) const;
602 bool must_be_derived_from(borrowed_ptr<const php::Class>,
603 borrowed_ptr<const php::Class>) const;
604 bool could_be_related(borrowed_ptr<const php::Class>,
605 borrowed_ptr<const php::Class>) const;
606 Type satisfies_constraint_helper(Context, const TypeConstraint&) const;
608 private:
609 std::unique_ptr<IndexData> const m_data;
612 //////////////////////////////////////////////////////////////////////
615 * Indexer object used for collecting information about public static property
616 * types. See analyze_public_statics in whole-program.cpp for details about
617 * how it is used.
619 struct PublicSPropIndexer {
620 explicit PublicSPropIndexer(borrowed_ptr<const Index> index)
621 : m_index(index)
625 * Called by the interpreter during analyze_func_collect when a
626 * PublicSPropIndexer is active. This function must be called anywhere the
627 * interpreter does something that could change the type of public static
628 * properties named `name' on classes of type `cls' to `val'.
630 * Note that if cls and name are both too generic this object will have to
631 * give up all information it knows about any public static properties.
633 * This routine may be safely called concurrently by multiple analysis
634 * threads.
636 void merge(Context ctx, Type cls, Type name, Type val);
638 private:
639 friend struct Index;
641 struct KnownKey {
642 bool operator==(KnownKey o) const {
643 return cinfo == o.cinfo && prop == o.prop;
646 friend size_t tbb_hasher(KnownKey k) {
647 return folly::hash::hash_combine(k.cinfo, k.prop);
650 borrowed_ptr<ClassInfo> cinfo;
651 SString prop;
654 using UnknownMap = tbb::concurrent_hash_map<SString,Type>;
655 using KnownMap = tbb::concurrent_hash_map<KnownKey,Type>;
657 private:
658 borrowed_ptr<const Index> m_index;
659 std::atomic<bool> m_everything_bad{false};
660 UnknownMap m_unknown;
661 KnownMap m_known;
664 //////////////////////////////////////////////////////////////////////
668 #endif