blob: a1e2efbc223cfe3fb84c64c27e037fae1e1219af [file] [log] [blame]
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_COMPILER_MAP_INFERENCE_H_
#define V8_COMPILER_MAP_INFERENCE_H_
#include "include/v8config.h"
#include "src/compiler/graph-reducer.h"
#include "src/objects/instance-type.h"
#include "src/objects/map.h"
namespace v8 {
namespace internal {
namespace compiler {
class CompilationDependencies;
struct FeedbackSource;
class JSGraph;
class JSHeapBroker;
class Node;
// The MapInference class provides access to the "inferred" maps of an
// {object}. This information can be either "reliable", meaning that the object
// is guaranteed to have one of these maps at runtime, or "unreliable", meaning
// that the object is guaranteed to have HAD one of these maps.
//
// The MapInference class does not expose whether or not the information is
// reliable. A client is expected to eventually make the information reliable by
// calling one of several methods that will either insert map checks, or record
// stability dependencies (or do nothing if the information was already
// reliable).
class MapInference {
public:
MapInference(JSHeapBroker* broker, Node* object, Node* effect);
// The destructor checks that the information has been made reliable (if
// necessary) and force-crashes if not.
~MapInference();
// Is there any information at all?
V8_WARN_UNUSED_RESULT bool HaveMaps() const;
// These queries don't require a guard.
//
V8_WARN_UNUSED_RESULT bool AllOfInstanceTypesAreJSReceiver() const;
// Here, {type} must not be a String type.
V8_WARN_UNUSED_RESULT bool AllOfInstanceTypesAre(InstanceType type) const;
V8_WARN_UNUSED_RESULT bool AnyOfInstanceTypesAre(InstanceType type) const;
// These queries require a guard. (Even instance types are generally not
// reliable because of how the representation of a string can change.)
V8_WARN_UNUSED_RESULT MapHandles const& GetMaps();
V8_WARN_UNUSED_RESULT bool AllOfInstanceTypes(
std::function<bool(InstanceType)> f);
V8_WARN_UNUSED_RESULT bool Is(Handle<Map> expected_map);
// These methods provide a guard.
//
// Returns true iff maps were already reliable or stability dependencies were
// successfully recorded.
V8_WARN_UNUSED_RESULT bool RelyOnMapsViaStability(
CompilationDependencies* dependencies);
// Records stability dependencies if possible, otherwise it inserts map
// checks. Does nothing if maps were already reliable. Returns true iff
// dependencies were taken.
bool RelyOnMapsPreferStability(CompilationDependencies* dependencies,
JSGraph* jsgraph, Effect* effect,
Control control,
const FeedbackSource& feedback);
// Inserts map checks even if maps were already reliable.
void InsertMapChecks(JSGraph* jsgraph, Effect* effect, Control control,
const FeedbackSource& feedback);
// Internally marks the maps as reliable (thus bypassing the safety check) and
// returns the NoChange reduction. USE THIS ONLY WHEN RETURNING, e.g.:
// if (foo) return inference.NoChange();
V8_WARN_UNUSED_RESULT Reduction NoChange();
private:
JSHeapBroker* const broker_;
Node* const object_;
MapHandles maps_;
enum {
kReliableOrGuarded,
kUnreliableDontNeedGuard,
kUnreliableNeedGuard
} maps_state_;
bool Safe() const;
void SetNeedGuardIfUnreliable();
void SetGuarded();
V8_WARN_UNUSED_RESULT bool AllOfInstanceTypesUnsafe(
std::function<bool(InstanceType)> f) const;
V8_WARN_UNUSED_RESULT bool AnyOfInstanceTypesUnsafe(
std::function<bool(InstanceType)> f) const;
V8_WARN_UNUSED_RESULT bool RelyOnMapsHelper(
CompilationDependencies* dependencies, JSGraph* jsgraph, Effect* effect,
Control control, const FeedbackSource& feedback);
};
} // namespace compiler
} // namespace internal
} // namespace v8
#endif // V8_COMPILER_MAP_INFERENCE_H_