Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2315)

Unified Diff: src/compiler/typer.cc

Issue 1410953006: [turbofan] Properly type field access to stable heap object maps. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Final workarounds. Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/typer.h ('k') | test/cctest/compiler/function-tester.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/typer.cc
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc
index 2430d40e00a5df787f9f1a0b4f737144af17e2ea..b3ea7ffa03fac4dc7ad1bfaa9568adab3bad11aa 100644
--- a/src/compiler/typer.cc
+++ b/src/compiler/typer.cc
@@ -7,6 +7,7 @@
#include "src/base/flags.h"
#include "src/base/lazy-instance.h"
#include "src/bootstrapper.h"
+#include "src/compilation-dependencies.h"
#include "src/compiler/common-operator.h"
#include "src/compiler/graph-reducer.h"
#include "src/compiler/js-operator.h"
@@ -37,9 +38,13 @@ class Typer::Decorator final : public GraphDecorator {
};
-Typer::Typer(Isolate* isolate, Graph* graph, Type::FunctionType* function_type)
+Typer::Typer(Isolate* isolate, Graph* graph, Flags flags,
+ CompilationDependencies* dependencies,
+ Type::FunctionType* function_type)
: isolate_(isolate),
graph_(graph),
+ flags_(flags),
+ dependencies_(dependencies),
function_type_(function_type),
decorator_(nullptr),
cache_(kCache.Get()) {
@@ -204,6 +209,10 @@ class Typer::Visitor : public Reducer {
Zone* zone() { return typer_->zone(); }
Isolate* isolate() { return typer_->isolate(); }
Graph* graph() { return typer_->graph(); }
+ Typer::Flags flags() const { return typer_->flags(); }
+ CompilationDependencies* dependencies() const {
+ return typer_->dependencies();
+ }
void SetWeakened(NodeId node_id) { weakened_nodes_.insert(node_id); }
bool IsWeakened(NodeId node_id) {
@@ -252,6 +261,8 @@ class Typer::Visitor : public Reducer {
static Type* JSLoadPropertyTyper(Type*, Type*, Typer*);
static Type* JSCallFunctionTyper(Type*, Typer*);
+ static Type* ReferenceEqualTyper(Type*, Type*, Typer*);
+
Reduction UpdateType(Node* node, Type* current) {
if (NodeProperties::IsTyped(node)) {
// Widen the type of a previously typed node.
@@ -1575,8 +1586,17 @@ Type* Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) {
}
+// static
+Type* Typer::Visitor::ReferenceEqualTyper(Type* lhs, Type* rhs, Typer* t) {
+ if (lhs->IsConstant() && rhs->Is(lhs)) {
+ return t->singleton_true_;
+ }
+ return Type::Boolean();
+}
+
+
Type* Typer::Visitor::TypeReferenceEqual(Node* node) {
- return Type::Boolean(zone());
+ return TypeBinaryOp(node, ReferenceEqualTyper);
}
@@ -1666,8 +1686,53 @@ Type* Typer::Visitor::TypeChangeBitToBool(Node* node) {
Type* Typer::Visitor::TypeAllocate(Node* node) { return Type::TaggedPointer(); }
+namespace {
+
+MaybeHandle<Map> GetStableMapFromObjectType(Type* object_type) {
+ if (object_type->IsConstant() &&
+ object_type->AsConstant()->Value()->IsHeapObject()) {
+ Handle<Map> object_map(
+ Handle<HeapObject>::cast(object_type->AsConstant()->Value())->map());
+ if (object_map->is_stable()) return object_map;
+ } else if (object_type->IsClass()) {
+ Handle<Map> object_map = object_type->AsClass()->Map();
+ if (object_map->is_stable()) return object_map;
+ }
+ return MaybeHandle<Map>();
+}
+
+} // namespace
+
+
Type* Typer::Visitor::TypeLoadField(Node* node) {
- return FieldAccessOf(node->op()).type;
+ FieldAccess const& access = FieldAccessOf(node->op());
+ if (access.base_is_tagged == kTaggedBase &&
+ access.offset == HeapObject::kMapOffset) {
+ // The type of LoadField[Map](o) is Constant(map) if map is stable and
+ // either
+ // (a) o has type Constant(object) and map == object->map, or
+ // (b) o has type Class(map),
+ // and either
+ // (1) map cannot transition further, or
+ // (2) deoptimization is enabled and we can add a code dependency on the
+ // stability of map (to guard the Constant type information).
+ Type* const object = Operand(node, 0);
+ if (object->Is(Type::None())) return Type::None();
+ Handle<Map> object_map;
+ if (GetStableMapFromObjectType(object).ToHandle(&object_map)) {
+ if (object_map->CanTransition()) {
+ if (flags() & kDeoptimizationEnabled) {
+ dependencies()->AssumeMapStable(object_map);
+ } else {
+ return access.type;
+ }
+ }
+ Type* object_map_type = Type::Constant(object_map, zone());
+ DCHECK(object_map_type->Is(access.type));
+ return object_map_type;
+ }
+ }
+ return access.type;
}
« no previous file with comments | « src/compiler/typer.h ('k') | test/cctest/compiler/function-tester.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698