Commit 402c300c authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[turbofan] Eliminate handle dereference in JSGraph::Constant.

This adds an overload of JSGraph::Constant that takes an ObjectReference
rather than a Handle<Object>.

ObjectReference is a new superclass of HeapReference.

Also several refactorings and renaming, e.g.:
- Rename HeapReference to HeapObjectRef.
- Rename ContextHeapReference to ContextRef.
- ...
- Rename HeapReferenceType to HeapObjectType.

Bug: v8:7790
Change-Id: Id3e567cbaf7c326189b99b2fd4ced6bff02f9640
Reviewed-on: https://chromium-review.googlesource.com/1104337Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53797}
parent 90e464a2
...@@ -104,13 +104,12 @@ bool IsContextParameter(Node* node) { ...@@ -104,13 +104,12 @@ bool IsContextParameter(Node* node) {
// context (which we want to read from or store to), try to return a // context (which we want to read from or store to), try to return a
// specialization context. If successful, update {distance} to whatever // specialization context. If successful, update {distance} to whatever
// distance remains from the specialization context. // distance remains from the specialization context.
base::Optional<ContextHeapReference> GetSpecializationContext( base::Optional<ContextRef> GetSpecializationContext(
const JSHeapBroker* broker, Node* node, size_t* distance, const JSHeapBroker* broker, Node* node, size_t* distance,
Maybe<OuterContext> maybe_outer) { Maybe<OuterContext> maybe_outer) {
switch (node->opcode()) { switch (node->opcode()) {
case IrOpcode::kHeapConstant: { case IrOpcode::kHeapConstant: {
HeapReference object = HeapObjectRef object(HeapConstantOf(node->op()));
broker->HeapReferenceForObject(HeapConstantOf(node->op()));
if (object.IsContext()) return object.AsContext(); if (object.IsContext()) return object.AsContext();
break; break;
} }
...@@ -119,14 +118,14 @@ base::Optional<ContextHeapReference> GetSpecializationContext( ...@@ -119,14 +118,14 @@ base::Optional<ContextHeapReference> GetSpecializationContext(
if (maybe_outer.To(&outer) && IsContextParameter(node) && if (maybe_outer.To(&outer) && IsContextParameter(node) &&
*distance >= outer.distance) { *distance >= outer.distance) {
*distance -= outer.distance; *distance -= outer.distance;
return broker->HeapReferenceForObject(outer.context).AsContext(); return ContextRef(outer.context);
} }
break; break;
} }
default: default:
break; break;
} }
return base::Optional<ContextHeapReference>(); return base::Optional<ContextRef>();
} }
} // anonymous namespace } // anonymous namespace
...@@ -140,7 +139,7 @@ Reduction JSContextSpecialization::ReduceJSLoadContext(Node* node) { ...@@ -140,7 +139,7 @@ Reduction JSContextSpecialization::ReduceJSLoadContext(Node* node) {
// First walk up the context chain in the graph as far as possible. // First walk up the context chain in the graph as far as possible.
Node* context = NodeProperties::GetOuterContext(node, &depth); Node* context = NodeProperties::GetOuterContext(node, &depth);
base::Optional<ContextHeapReference> maybe_concrete = base::Optional<ContextRef> maybe_concrete =
GetSpecializationContext(js_heap_broker(), context, &depth, outer()); GetSpecializationContext(js_heap_broker(), context, &depth, outer());
if (!maybe_concrete.has_value()) { if (!maybe_concrete.has_value()) {
// We do not have a concrete context object, so we can only partially reduce // We do not have a concrete context object, so we can only partially reduce
...@@ -149,7 +148,7 @@ Reduction JSContextSpecialization::ReduceJSLoadContext(Node* node) { ...@@ -149,7 +148,7 @@ Reduction JSContextSpecialization::ReduceJSLoadContext(Node* node) {
} }
// Now walk up the concrete context chain for the remaining depth. // Now walk up the concrete context chain for the remaining depth.
ContextHeapReference concrete = maybe_concrete.value(); ContextRef concrete = maybe_concrete.value();
for (; depth > 0; --depth) { for (; depth > 0; --depth) {
concrete = concrete.previous(js_heap_broker()).value(); concrete = concrete.previous(js_heap_broker()).value();
} }
...@@ -157,12 +156,12 @@ Reduction JSContextSpecialization::ReduceJSLoadContext(Node* node) { ...@@ -157,12 +156,12 @@ Reduction JSContextSpecialization::ReduceJSLoadContext(Node* node) {
if (!access.immutable()) { if (!access.immutable()) {
// We found the requested context object but since the context slot is // We found the requested context object but since the context slot is
// mutable we can only partially reduce the load. // mutable we can only partially reduce the load.
return SimplifyJSLoadContext(node, jsgraph()->Constant(concrete.object()), return SimplifyJSLoadContext(
depth); node, jsgraph()->Constant(js_heap_broker(), concrete), depth);
} }
// This will hold the final value, if we can figure it out. // This will hold the final value, if we can figure it out.
base::Optional<ObjectReference> maybe_value; base::Optional<ObjectRef> maybe_value;
maybe_value = maybe_value =
concrete.get(js_heap_broker(), static_cast<int>(access.index())); concrete.get(js_heap_broker(), static_cast<int>(access.index()));
...@@ -172,25 +171,24 @@ Reduction JSContextSpecialization::ReduceJSLoadContext(Node* node) { ...@@ -172,25 +171,24 @@ Reduction JSContextSpecialization::ReduceJSLoadContext(Node* node) {
// We must be conservative and check if the value in the slot is currently // We must be conservative and check if the value in the slot is currently
// the hole or undefined. Only if it is neither of these, can we be sure // the hole or undefined. Only if it is neither of these, can we be sure
// that it won't change anymore. // that it won't change anymore.
HeapReferenceType type = HeapObjectType type = maybe_value->AsHeapObjectRef().type(js_heap_broker());
maybe_value->AsHeapReference().type(js_heap_broker()); if (type.oddball_type() == HeapObjectType::kAny ||
if (type.oddball_type() == HeapReferenceType::kAny || type.oddball_type() == HeapObjectType::kUndefined ||
type.oddball_type() == HeapReferenceType::kUndefined || type.oddball_type() == HeapObjectType::kHole) {
type.oddball_type() == HeapReferenceType::kHole) {
maybe_value.reset(); maybe_value.reset();
} }
} }
if (!maybe_value.has_value()) { if (!maybe_value.has_value()) {
return SimplifyJSLoadContext(node, jsgraph()->Constant(concrete.object()), return SimplifyJSLoadContext(
depth); node, jsgraph()->Constant(js_heap_broker(), concrete), depth);
} }
// Success. The context load can be replaced with the constant. // Success. The context load can be replaced with the constant.
// TODO(titzer): record the specialization for sharing code across // TODO(titzer): record the specialization for sharing code across
// multiple contexts that have the same value in the corresponding context // multiple contexts that have the same value in the corresponding context
// slot. // slot.
Node* constant = jsgraph_->Constant(maybe_value->object()); Node* constant = jsgraph_->Constant(js_heap_broker(), *maybe_value);
ReplaceWithValue(node, constant); ReplaceWithValue(node, constant);
return Replace(constant); return Replace(constant);
} }
...@@ -206,7 +204,7 @@ Reduction JSContextSpecialization::ReduceJSStoreContext(Node* node) { ...@@ -206,7 +204,7 @@ Reduction JSContextSpecialization::ReduceJSStoreContext(Node* node) {
// or hit a node that does not have a CreateXYZContext operator. // or hit a node that does not have a CreateXYZContext operator.
Node* context = NodeProperties::GetOuterContext(node, &depth); Node* context = NodeProperties::GetOuterContext(node, &depth);
base::Optional<ContextHeapReference> maybe_concrete = base::Optional<ContextRef> maybe_concrete =
GetSpecializationContext(js_heap_broker(), context, &depth, outer()); GetSpecializationContext(js_heap_broker(), context, &depth, outer());
if (!maybe_concrete.has_value()) { if (!maybe_concrete.has_value()) {
// We do not have a concrete context object, so we can only partially reduce // We do not have a concrete context object, so we can only partially reduce
...@@ -215,13 +213,13 @@ Reduction JSContextSpecialization::ReduceJSStoreContext(Node* node) { ...@@ -215,13 +213,13 @@ Reduction JSContextSpecialization::ReduceJSStoreContext(Node* node) {
} }
// Now walk up the concrete context chain for the remaining depth. // Now walk up the concrete context chain for the remaining depth.
ContextHeapReference concrete = maybe_concrete.value(); ContextRef concrete = maybe_concrete.value();
for (; depth > 0; --depth) { for (; depth > 0; --depth) {
concrete = concrete.previous(js_heap_broker()).value(); concrete = concrete.previous(js_heap_broker()).value();
} }
return SimplifyJSStoreContext(node, jsgraph()->Constant(concrete.object()), return SimplifyJSStoreContext(
depth); node, jsgraph()->Constant(js_heap_broker(), concrete), depth);
} }
......
...@@ -47,7 +47,6 @@ Node* JSGraph::CEntryStubConstant(int result_size, SaveFPRegsMode save_doubles, ...@@ -47,7 +47,6 @@ Node* JSGraph::CEntryStubConstant(int result_size, SaveFPRegsMode save_doubles,
} }
Node* JSGraph::Constant(Handle<Object> value) { Node* JSGraph::Constant(Handle<Object> value) {
AllowHandleDereference handle_dereference;
// Dereference the handle to determine if a number constant or other // Dereference the handle to determine if a number constant or other
// canonicalized node can be used. // canonicalized node can be used.
if (value->IsNumber()) { if (value->IsNumber()) {
...@@ -67,6 +66,33 @@ Node* JSGraph::Constant(Handle<Object> value) { ...@@ -67,6 +66,33 @@ Node* JSGraph::Constant(Handle<Object> value) {
} }
} }
Node* JSGraph::Constant(const JSHeapBroker* broker, const ObjectRef& ref) {
if (ref.IsSmi()) return Constant(ref.AsSmi());
HeapObjectType type = ref.AsHeapObjectRef().type(broker);
if (ref.IsHeapNumber()) {
return Constant(ref.AsHeapNumber().value());
} else if (type.oddball_type() == HeapObjectType::kUndefined) {
DCHECK(
ref.object<Object>().equals(isolate()->factory()->undefined_value()));
return UndefinedConstant();
} else if (type.oddball_type() == HeapObjectType::kNull) {
DCHECK(ref.object<Object>().equals(isolate()->factory()->null_value()));
return NullConstant();
} else if (type.oddball_type() == HeapObjectType::kHole) {
DCHECK(ref.object<Object>().equals(isolate()->factory()->the_hole_value()));
return TheHoleConstant();
} else if (type.oddball_type() == HeapObjectType::kBoolean) {
if (ref.object<Object>().equals(isolate()->factory()->true_value())) {
return TrueConstant();
} else {
DCHECK(ref.object<Object>().equals(isolate()->factory()->false_value()));
return FalseConstant();
}
} else {
return HeapConstant(ref.object<HeapObject>());
}
}
Node* JSGraph::Constant(double value) { Node* JSGraph::Constant(double value) {
if (bit_cast<int64_t>(value) == bit_cast<int64_t>(0.0)) return ZeroConstant(); if (bit_cast<int64_t>(value) == bit_cast<int64_t>(0.0)) return ZeroConstant();
if (bit_cast<int64_t>(value) == bit_cast<int64_t>(1.0)) return OneConstant(); if (bit_cast<int64_t>(value) == bit_cast<int64_t>(1.0)) return OneConstant();
......
...@@ -55,6 +55,9 @@ class V8_EXPORT_PRIVATE JSGraph : public MachineGraph { ...@@ -55,6 +55,9 @@ class V8_EXPORT_PRIVATE JSGraph : public MachineGraph {
// canonicalized globals or a number constant should be returned. // canonicalized globals or a number constant should be returned.
Node* Constant(Handle<Object> value); Node* Constant(Handle<Object> value);
// Like above, but doesn't access the heap directly.
Node* Constant(const JSHeapBroker* broker, const ObjectRef& value);
// Creates a NumberConstant node, usually canonicalized. // Creates a NumberConstant node, usually canonicalized.
Node* Constant(double value); Node* Constant(double value);
......
...@@ -9,57 +9,71 @@ namespace v8 { ...@@ -9,57 +9,71 @@ namespace v8 {
namespace internal { namespace internal {
namespace compiler { namespace compiler {
bool ObjectReference::IsSmi() const { HeapObjectRef::HeapObjectRef(Handle<Object> object) : ObjectRef(object) {
AllowHandleDereference allow_handle_dereference; AllowHandleDereference handle_dereference;
return object_->IsSmi(); SLOW_DCHECK(object->IsHeapObject());
} }
int ObjectReference::AsSmi() const { JSFunctionRef::JSFunctionRef(Handle<Object> object) : HeapObjectRef(object) {
AllowHandleDereference allow_handle_dereference; AllowHandleDereference handle_dereference;
return Smi::cast(*object_)->value(); SLOW_DCHECK(object->IsJSFunction());
}
HeapNumberRef::HeapNumberRef(Handle<Object> object) : HeapObjectRef(object) {
AllowHandleDereference handle_dereference;
SLOW_DCHECK(object->IsHeapNumber());
}
ContextRef::ContextRef(Handle<Object> object) : HeapObjectRef(object) {
AllowHandleDereference handle_dereference;
SLOW_DCHECK(object->IsContext());
} }
HeapReference ObjectReference::AsHeapReference() const { bool ObjectRef::IsSmi() const {
AllowHandleDereference allow_handle_dereference; AllowHandleDereference allow_handle_dereference;
return HeapReference(Handle<HeapObject>::cast(object_)); return object_->IsSmi();
} }
base::Optional<ContextHeapReference> ContextHeapReference::previous( int ObjectRef::AsSmi() const { return object<Smi>()->value(); }
HeapObjectRef ObjectRef::AsHeapObjectRef() const {
return HeapObjectRef(object<HeapObject>());
}
base::Optional<ContextRef> ContextRef::previous(
const JSHeapBroker* broker) const { const JSHeapBroker* broker) const {
AllowHandleAllocation handle_allocation; AllowHandleAllocation handle_allocation;
AllowHandleDereference handle_dereference; AllowHandleDereference handle_dereference;
Context* previous = Handle<Context>::cast(object())->previous(); Context* previous = object<Context>()->previous();
if (previous == nullptr) return base::Optional<ContextHeapReference>(); if (previous == nullptr) return base::Optional<ContextRef>();
return broker->HeapReferenceForObject(handle(previous, broker->isolate())) return ContextRef(handle(previous, broker->isolate()));
.AsContext();
} }
base::Optional<ObjectReference> ContextHeapReference::get( base::Optional<ObjectRef> ContextRef::get(const JSHeapBroker* broker,
const JSHeapBroker* broker, int index) const { int index) const {
AllowHandleAllocation handle_allocation; AllowHandleAllocation handle_allocation;
AllowHandleDereference handle_dereference; AllowHandleDereference handle_dereference;
Handle<Object> value(Handle<Context>::cast(object())->get(index), Handle<Object> value(object<Context>()->get(index), broker->isolate());
broker->isolate()); return ObjectRef(value);
return ObjectReference(value);
} }
JSHeapBroker::JSHeapBroker(Isolate* isolate) : isolate_(isolate) {} JSHeapBroker::JSHeapBroker(Isolate* isolate) : isolate_(isolate) {}
HeapReferenceType JSHeapBroker::HeapReferenceTypeFromMap(Map* map) const { HeapObjectType JSHeapBroker::HeapObjectTypeFromMap(Map* map) const {
AllowHandleDereference allow_handle_dereference; AllowHandleDereference allow_handle_dereference;
Heap* heap = isolate_->heap(); Heap* heap = isolate_->heap();
HeapReferenceType::OddballType oddball_type = HeapReferenceType::kNone; HeapObjectType::OddballType oddball_type = HeapObjectType::kNone;
if (map->instance_type() == ODDBALL_TYPE) { if (map->instance_type() == ODDBALL_TYPE) {
if (map == heap->undefined_map()) { if (map == heap->undefined_map()) {
oddball_type = HeapReferenceType::kUndefined; oddball_type = HeapObjectType::kUndefined;
} else if (map == heap->null_map()) { } else if (map == heap->null_map()) {
oddball_type = HeapReferenceType::kNull; oddball_type = HeapObjectType::kNull;
} else if (map == heap->boolean_map()) { } else if (map == heap->boolean_map()) {
oddball_type = HeapReferenceType::kBoolean; oddball_type = HeapObjectType::kBoolean;
} else if (map == heap->the_hole_map()) { } else if (map == heap->the_hole_map()) {
oddball_type = HeapReferenceType::kHole; oddball_type = HeapObjectType::kHole;
} else { } else {
oddball_type = HeapReferenceType::kOther; oddball_type = HeapObjectType::kOther;
DCHECK(map == heap->uninitialized_map() || DCHECK(map == heap->uninitialized_map() ||
map == heap->termination_exception_map() || map == heap->termination_exception_map() ||
map == heap->arguments_marker_map() || map == heap->arguments_marker_map() ||
...@@ -67,17 +81,11 @@ HeapReferenceType JSHeapBroker::HeapReferenceTypeFromMap(Map* map) const { ...@@ -67,17 +81,11 @@ HeapReferenceType JSHeapBroker::HeapReferenceTypeFromMap(Map* map) const {
map == heap->stale_register_map()); map == heap->stale_register_map());
} }
} }
HeapReferenceType::Flags flags(0); HeapObjectType::Flags flags(0);
if (map->is_undetectable()) flags |= HeapReferenceType::kUndetectable; if (map->is_undetectable()) flags |= HeapObjectType::kUndetectable;
if (map->is_callable()) flags |= HeapReferenceType::kCallable; if (map->is_callable()) flags |= HeapObjectType::kCallable;
return HeapReferenceType(map->instance_type(), flags, oddball_type);
}
HeapReference JSHeapBroker::HeapReferenceForObject( return HeapObjectType(map->instance_type(), flags, oddball_type);
Handle<Object> object) const {
AllowHandleDereference allow_handle_dereference;
return HeapReference(Handle<HeapObject>::cast(object));
} }
// static // static
...@@ -88,40 +96,39 @@ base::Optional<int> JSHeapBroker::TryGetSmi(Handle<Object> object) { ...@@ -88,40 +96,39 @@ base::Optional<int> JSHeapBroker::TryGetSmi(Handle<Object> object) {
} }
#define HEAP_KIND_FUNCTIONS_DEF(Name) \ #define HEAP_KIND_FUNCTIONS_DEF(Name) \
bool HeapReference::Is##Name() const { \ bool ObjectRef::Is##Name() const { \
AllowHandleDereference allow_handle_dereference; \ AllowHandleDereference allow_handle_dereference; \
return object_->Is##Name(); \ return object<Object>()->Is##Name(); \
} }
HEAP_BROKER_KIND_LIST(HEAP_KIND_FUNCTIONS_DEF) HEAP_BROKER_KIND_LIST(HEAP_KIND_FUNCTIONS_DEF)
#undef HEAP_KIND_FUNCTIONS_DEF #undef HEAP_KIND_FUNCTIONS_DEF
#define HEAP_DATA_FUNCTIONS_DEF(Name) \ #define HEAP_DATA_FUNCTIONS_DEF(Name) \
Name##HeapReference HeapReference::As##Name() const { \ Name##Ref ObjectRef::As##Name() const { \
AllowHandleDereference allow_handle_dereference; \ SLOW_DCHECK(Is##Name()); \
SLOW_DCHECK(object_->Is##Name()); \ return Name##Ref(object<HeapObject>()); \
return Name##HeapReference(object_); \
} }
HEAP_BROKER_DATA_LIST(HEAP_DATA_FUNCTIONS_DEF) HEAP_BROKER_DATA_LIST(HEAP_DATA_FUNCTIONS_DEF)
#undef HEAP_DATA_FUNCTIONS_DEF #undef HEAP_DATA_FUNCTIONS_DEF
HeapReferenceType HeapReference::type(const JSHeapBroker* broker) const { HeapObjectType HeapObjectRef::type(const JSHeapBroker* broker) const {
AllowHandleDereference allow_handle_dereference; AllowHandleDereference allow_handle_dereference;
return broker->HeapReferenceTypeFromMap(object_->map()); return broker->HeapObjectTypeFromMap(object<HeapObject>()->map());
} }
double NumberHeapReference::value() const { double HeapNumberRef::value() const {
AllowHandleDereference allow_handle_dereference; AllowHandleDereference allow_handle_dereference;
return object()->Number(); return object<HeapObject>()->Number();
} }
bool JSFunctionHeapReference::HasBuiltinFunctionId() const { bool JSFunctionRef::HasBuiltinFunctionId() const {
AllowHandleDereference allow_handle_dereference; AllowHandleDereference allow_handle_dereference;
return JSFunction::cast(*object())->shared()->HasBuiltinFunctionId(); return object<JSFunction>()->shared()->HasBuiltinFunctionId();
} }
BuiltinFunctionId JSFunctionHeapReference::GetBuiltinFunctionId() const { BuiltinFunctionId JSFunctionRef::GetBuiltinFunctionId() const {
AllowHandleDereference allow_handle_dereference; AllowHandleDereference allow_handle_dereference;
return JSFunction::cast(*object())->shared()->builtin_function_id(); return object<JSFunction>()->shared()->builtin_function_id();
} }
} // namespace compiler } // namespace compiler
......
...@@ -14,7 +14,7 @@ namespace v8 { ...@@ -14,7 +14,7 @@ namespace v8 {
namespace internal { namespace internal {
namespace compiler { namespace compiler {
class HeapReferenceType { class HeapObjectType {
public: public:
enum OddballType : uint8_t { enum OddballType : uint8_t {
kNone, // Not an Oddball. kNone, // Not an Oddball.
...@@ -29,8 +29,8 @@ class HeapReferenceType { ...@@ -29,8 +29,8 @@ class HeapReferenceType {
typedef base::Flags<Flag> Flags; typedef base::Flags<Flag> Flags;
HeapReferenceType(InstanceType instance_type, Flags flags, HeapObjectType(InstanceType instance_type, Flags flags,
OddballType oddball_type) OddballType oddball_type)
: instance_type_(instance_type), : instance_type_(instance_type),
oddball_type_(oddball_type), oddball_type_(oddball_type),
flags_(flags) { flags_(flags) {
...@@ -52,98 +52,94 @@ class HeapReferenceType { ...@@ -52,98 +52,94 @@ class HeapReferenceType {
#define HEAP_BROKER_DATA_LIST(V) \ #define HEAP_BROKER_DATA_LIST(V) \
V(Context) \ V(Context) \
V(JSFunction) \ V(HeapNumber) \
V(Number) V(JSFunction)
#define HEAP_BROKER_KIND_LIST(V) \ #define HEAP_BROKER_KIND_LIST(V) \
HEAP_BROKER_DATA_LIST(V) \ HEAP_BROKER_DATA_LIST(V) \
V(InternalizedString) \ V(InternalizedString) \
V(String) V(String)
#define FORWARD_DECL(Name) class Name##HeapReference; #define FORWARD_DECL(Name) class Name##Ref;
HEAP_BROKER_DATA_LIST(FORWARD_DECL) HEAP_BROKER_DATA_LIST(FORWARD_DECL)
#undef FORWARD_DECL #undef FORWARD_DECL
class JSHeapBroker; class JSHeapBroker;
class HeapReference; class HeapObjectRef;
class ObjectReference { class ObjectRef {
public: public:
explicit ObjectReference(Handle<Object> object) : object_(object) {} explicit ObjectRef(Handle<Object> object) : object_(object) {}
template <typename T>
Handle<T> object() const {
AllowHandleDereference handle_dereference;
return Handle<T>::cast(object_);
}
Handle<Object> object() const { return object_; }
bool IsSmi() const; bool IsSmi() const;
int AsSmi() const; int AsSmi() const;
HeapReference AsHeapReference() const; HeapObjectRef AsHeapObjectRef() const;
private:
Handle<Object> object_;
};
class HeapReference {
public:
explicit HeapReference(Handle<HeapObject> object) : object_(object) {}
#define HEAP_IS_METHOD_DECL(Name) bool Is##Name() const; #define HEAP_IS_METHOD_DECL(Name) bool Is##Name() const;
HEAP_BROKER_KIND_LIST(HEAP_IS_METHOD_DECL) HEAP_BROKER_KIND_LIST(HEAP_IS_METHOD_DECL)
#undef HEAP_IS_METHOD_DECL #undef HEAP_IS_METHOD_DECL
#define HEAP_AS_METHOD_DECL(Name) Name##HeapReference As##Name() const; #define HEAP_AS_METHOD_DECL(Name) Name##Ref As##Name() const;
HEAP_BROKER_DATA_LIST(HEAP_AS_METHOD_DECL) HEAP_BROKER_DATA_LIST(HEAP_AS_METHOD_DECL)
#undef HEAP_AS_METHOD_DECL #undef HEAP_AS_METHOD_DECL
HeapReferenceType type(const JSHeapBroker* broker) const; private:
Handle<HeapObject> object() const { return object_; } Handle<Object> object_;
};
class HeapObjectRef : public ObjectRef {
public:
explicit HeapObjectRef(Handle<Object> object);
HeapObjectType type(const JSHeapBroker* broker) const;
private: private:
friend class JSHeapBroker; friend class JSHeapBroker;
Handle<HeapObject> object_;
}; };
class V8_EXPORT_PRIVATE JSHeapBroker : public NON_EXPORTED_BASE(ZoneObject) { class V8_EXPORT_PRIVATE JSHeapBroker : public NON_EXPORTED_BASE(ZoneObject) {
public: public:
JSHeapBroker(Isolate* isolate); JSHeapBroker(Isolate* isolate);
HeapReferenceType HeapReferenceTypeFromMap(Handle<Map> map) const { HeapObjectType HeapObjectTypeFromMap(Handle<Map> map) const {
return HeapReferenceTypeFromMap(*map); AllowHandleDereference handle_dereference;
return HeapObjectTypeFromMap(*map);
} }
HeapReference HeapReferenceForObject(Handle<Object> object) const;
static base::Optional<int> TryGetSmi(Handle<Object> object); static base::Optional<int> TryGetSmi(Handle<Object> object);
Isolate* isolate() const { return isolate_; } Isolate* isolate() const { return isolate_; }
private: private:
friend class HeapReference; friend class HeapObjectRef;
HeapReferenceType HeapReferenceTypeFromMap(Map* map) const; HeapObjectType HeapObjectTypeFromMap(Map* map) const;
Isolate* const isolate_; Isolate* const isolate_;
}; };
class JSFunctionHeapReference : public HeapReference { class JSFunctionRef : public HeapObjectRef {
public: public:
explicit JSFunctionHeapReference(Handle<HeapObject> object) explicit JSFunctionRef(Handle<Object> object);
: HeapReference(object) {}
bool HasBuiltinFunctionId() const; bool HasBuiltinFunctionId() const;
BuiltinFunctionId GetBuiltinFunctionId() const; BuiltinFunctionId GetBuiltinFunctionId() const;
}; };
class NumberHeapReference : public HeapReference { class HeapNumberRef : public HeapObjectRef {
public: public:
explicit NumberHeapReference(Handle<HeapObject> object) explicit HeapNumberRef(Handle<Object> object);
: HeapReference(object) {}
double value() const; double value() const;
}; };
class ContextHeapReference : public HeapReference { class ContextRef : public HeapObjectRef {
public: public:
explicit ContextHeapReference(Handle<HeapObject> object) explicit ContextRef(Handle<Object> object);
: HeapReference(object) {} base::Optional<ContextRef> previous(const JSHeapBroker* broker) const;
base::Optional<ContextHeapReference> previous( base::Optional<ObjectRef> get(const JSHeapBroker* broker, int index) const;
const JSHeapBroker* broker) const;
base::Optional<ObjectReference> get(const JSHeapBroker* broker,
int index) const;
}; };
} // namespace compiler } // namespace compiler
......
...@@ -1405,7 +1405,7 @@ Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) { ...@@ -1405,7 +1405,7 @@ Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) {
if (!fun.IsHeapConstant() || !fun.AsHeapConstant()->Ref().IsJSFunction()) { if (!fun.IsHeapConstant() || !fun.AsHeapConstant()->Ref().IsJSFunction()) {
return Type::NonInternal(); return Type::NonInternal();
} }
JSFunctionHeapReference function = fun.AsHeapConstant()->Ref().AsJSFunction(); JSFunctionRef function = fun.AsHeapConstant()->Ref().AsJSFunction();
if (!function.HasBuiltinFunctionId()) { if (!function.HasBuiltinFunctionId()) {
return Type::NonInternal(); return Type::NonInternal();
} }
......
...@@ -132,7 +132,7 @@ Type::bitset Type::BitsetLub() const { ...@@ -132,7 +132,7 @@ Type::bitset Type::BitsetLub() const {
UNREACHABLE(); UNREACHABLE();
} }
Type::bitset BitsetType::Lub(HeapReferenceType const& type) { Type::bitset BitsetType::Lub(HeapObjectType const& type) {
switch (type.instance_type()) { switch (type.instance_type()) {
case CONS_STRING_TYPE: case CONS_STRING_TYPE:
case CONS_ONE_BYTE_STRING_TYPE: case CONS_ONE_BYTE_STRING_TYPE:
...@@ -164,18 +164,18 @@ Type::bitset BitsetType::Lub(HeapReferenceType const& type) { ...@@ -164,18 +164,18 @@ Type::bitset BitsetType::Lub(HeapReferenceType const& type) {
return kBigInt; return kBigInt;
case ODDBALL_TYPE: case ODDBALL_TYPE:
switch (type.oddball_type()) { switch (type.oddball_type()) {
case HeapReferenceType::kHole: case HeapObjectType::kHole:
return kHole; return kHole;
case HeapReferenceType::kBoolean: case HeapObjectType::kBoolean:
return kBoolean; return kBoolean;
case HeapReferenceType::kNull: case HeapObjectType::kNull:
return kNull; return kNull;
case HeapReferenceType::kUndefined: case HeapObjectType::kUndefined:
return kUndefined; return kUndefined;
case HeapReferenceType::kOther: case HeapObjectType::kOther:
// TODO(neis): We should add a kOtherOddball type. // TODO(neis): We should add a kOtherOddball type.
return kOtherInternal; return kOtherInternal;
case HeapReferenceType::kAny: case HeapObjectType::kAny:
return kOddball | kOtherInternal; return kOddball | kOtherInternal;
default: default:
UNREACHABLE(); UNREACHABLE();
...@@ -447,9 +447,13 @@ bool OtherNumberConstantType::IsOtherNumberConstant(double value) { ...@@ -447,9 +447,13 @@ bool OtherNumberConstantType::IsOtherNumberConstant(double value) {
} }
HeapConstantType::HeapConstantType(BitsetType::bitset bitset, HeapConstantType::HeapConstantType(BitsetType::bitset bitset,
const HeapReference& heap_ref) const HeapObjectRef& heap_ref)
: TypeBase(kHeapConstant), bitset_(bitset), heap_ref_(heap_ref) {} : TypeBase(kHeapConstant), bitset_(bitset), heap_ref_(heap_ref) {}
Handle<HeapObject> HeapConstantType::Value() const {
return heap_ref_.object<HeapObject>();
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Predicates. // Predicates.
...@@ -811,9 +815,9 @@ Type Type::NewConstant(const JSHeapBroker* js_heap_broker, ...@@ -811,9 +815,9 @@ Type Type::NewConstant(const JSHeapBroker* js_heap_broker,
return NewConstant(static_cast<double>(maybe_smi.value()), zone); return NewConstant(static_cast<double>(maybe_smi.value()), zone);
} }
HeapReference heap_ref = js_heap_broker->HeapReferenceForObject(value); HeapObjectRef heap_ref(value);
if (heap_ref.IsNumber()) { if (heap_ref.IsHeapNumber()) {
return NewConstant(heap_ref.AsNumber().value(), zone); return NewConstant(heap_ref.AsHeapNumber().value(), zone);
} }
if (heap_ref.IsString() && !heap_ref.IsInternalizedString()) { if (heap_ref.IsString() && !heap_ref.IsInternalizedString()) {
...@@ -1047,8 +1051,8 @@ Type Type::OtherNumberConstant(double value, Zone* zone) { ...@@ -1047,8 +1051,8 @@ Type Type::OtherNumberConstant(double value, Zone* zone) {
// static // static
Type Type::HeapConstant(const JSHeapBroker* js_heap_broker, Type Type::HeapConstant(const JSHeapBroker* js_heap_broker,
Handle<i::Object> value, Zone* zone) { Handle<i::Object> value, Zone* zone) {
return FromTypeBase(HeapConstantType::New( return FromTypeBase(
js_heap_broker, js_heap_broker->HeapReferenceForObject(value), zone)); HeapConstantType::New(js_heap_broker, HeapObjectRef(value), zone));
} }
// static // static
......
...@@ -251,7 +251,7 @@ class V8_EXPORT_PRIVATE BitsetType { ...@@ -251,7 +251,7 @@ class V8_EXPORT_PRIVATE BitsetType {
static double Max(bitset); static double Max(bitset);
static bitset Glb(double min, double max); static bitset Glb(double min, double max);
static bitset Lub(HeapReferenceType const& type); static bitset Lub(HeapObjectType const& type);
static bitset Lub(double value); static bitset Lub(double value);
static bitset Lub(double min, double max); static bitset Lub(double min, double max);
static bitset ExpandInternals(bitset bits); static bitset ExpandInternals(bitset bits);
...@@ -377,7 +377,7 @@ class V8_EXPORT_PRIVATE Type { ...@@ -377,7 +377,7 @@ class V8_EXPORT_PRIVATE Type {
static Type Intersect(Type type1, Type type2, Zone* zone); static Type Intersect(Type type1, Type type2, Zone* zone);
static Type For(const JSHeapBroker* js_heap_broker, Handle<i::Map> map) { static Type For(const JSHeapBroker* js_heap_broker, Handle<i::Map> map) {
HeapReferenceType type = js_heap_broker->HeapReferenceTypeFromMap(map); HeapObjectType type = js_heap_broker->HeapObjectTypeFromMap(map);
return NewBitset(BitsetType::ExpandInternals(BitsetType::Lub(type))); return NewBitset(BitsetType::ExpandInternals(BitsetType::Lub(type)));
} }
...@@ -534,28 +534,28 @@ class OtherNumberConstantType : public TypeBase { ...@@ -534,28 +534,28 @@ class OtherNumberConstantType : public TypeBase {
class V8_EXPORT_PRIVATE HeapConstantType : public NON_EXPORTED_BASE(TypeBase) { class V8_EXPORT_PRIVATE HeapConstantType : public NON_EXPORTED_BASE(TypeBase) {
public: public:
Handle<HeapObject> Value() const { return heap_ref_.object(); } Handle<HeapObject> Value() const;
const HeapReference& Ref() const { return heap_ref_; } const HeapObjectRef& Ref() const { return heap_ref_; }
private: private:
friend class Type; friend class Type;
friend class BitsetType; friend class BitsetType;
static HeapConstantType* New(const JSHeapBroker* broker, static HeapConstantType* New(const JSHeapBroker* broker,
const HeapReference& heap_ref, Zone* zone) { const HeapObjectRef& heap_ref, Zone* zone) {
DCHECK(!heap_ref.IsNumber()); DCHECK(!heap_ref.IsHeapNumber());
DCHECK_IMPLIES(heap_ref.IsString(), heap_ref.IsInternalizedString()); DCHECK_IMPLIES(heap_ref.IsString(), heap_ref.IsInternalizedString());
BitsetType::bitset bitset = BitsetType::Lub(heap_ref.type(broker)); BitsetType::bitset bitset = BitsetType::Lub(heap_ref.type(broker));
return new (zone->New(sizeof(HeapConstantType))) return new (zone->New(sizeof(HeapConstantType)))
HeapConstantType(bitset, heap_ref); HeapConstantType(bitset, heap_ref);
} }
HeapConstantType(BitsetType::bitset bitset, const HeapReference& heap_ref); HeapConstantType(BitsetType::bitset bitset, const HeapObjectRef& heap_ref);
BitsetType::bitset Lub() const { return bitset_; } BitsetType::bitset Lub() const { return bitset_; }
BitsetType::bitset bitset_; BitsetType::bitset bitset_;
HeapReference heap_ref_; HeapObjectRef heap_ref_;
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment