Commit c0a249c4 authored by Jaroslav Sevcik's avatar Jaroslav Sevcik Committed by Commit Bot

[turbofan] Typer accesses js heap through the heap broker.

This moves all accesses from Typer to the broker. This is policed by
DisallowHandleDereferenceScope in Typer::Visitor::Reduce.

Bug: v8:7790
Change-Id: Ic37d029261b3302eedb902a3b2249834a5dd0512
Reviewed-on: https://chromium-review.googlesource.com/1095305
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53659}
parent e1ff9368
......@@ -39,10 +39,47 @@ HeapReferenceType JSHeapBroker::HeapReferenceTypeFromMap(Map* map) const {
return HeapReferenceType(map->instance_type(), flags, oddball_type);
}
HeapReferenceType JSHeapBroker::HeapReferenceTypeForObject(
Handle<HeapObject> object) const {
HeapReference JSHeapBroker::HeapReferenceForObject(
Handle<Object> object) const {
AllowHandleDereference allow_handle_dereference;
return HeapReferenceTypeFromMap(object->map());
Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object);
HeapReferenceType type = HeapReferenceTypeFromMap(heap_object->map());
return HeapReference(heap_object, type);
}
// static
base::Optional<int> JSHeapBroker::TryGetSmi(Handle<Object> object) {
AllowHandleDereference allow_handle_dereference;
if (!object->IsSmi()) return base::Optional<int>();
return Smi::cast(*object)->value();
}
#define HEAP_KIND_FUNCTIONS_DEF(Name) \
bool HeapReference::Is##Name() const { \
AllowHandleDereference allow_handle_dereference; \
return object_->Is##Name(); \
}
HEAP_BROKER_KIND_LIST(HEAP_KIND_FUNCTIONS_DEF)
#undef HEAP_KIND_FUNCTIONS_DEF
NumberHeapData HeapReference::AsNumber() const {
AllowHandleDereference allow_handle_dereference;
return NumberHeapData(object_->Number());
}
JSFunctionHeapData HeapReference::AsJSFunction() const {
AllowHandleDereference allow_handle_dereference;
return JSFunctionHeapData(Handle<JSFunction>::cast(object_));
}
bool JSFunctionHeapData::HasBuiltinFunctionId() const {
AllowHandleDereference allow_handle_dereference;
return function_->shared()->HasBuiltinFunctionId();
}
BuiltinFunctionId JSFunctionHeapData::GetBuiltinFunctionId() const {
AllowHandleDereference allow_handle_dereference;
return function_->shared()->builtin_function_id();
}
} // namespace compiler
......
......@@ -6,6 +6,7 @@
#define V8_COMPILER_JS_HEAP_BROKER_H_
#include "src/base/compiler-specific.h"
#include "src/base/optional.h"
#include "src/globals.h"
#include "src/objects.h"
......@@ -13,6 +14,32 @@ namespace v8 {
namespace internal {
namespace compiler {
class JSFunctionHeapData {
public:
bool HasBuiltinFunctionId() const;
BuiltinFunctionId GetBuiltinFunctionId() const;
private:
friend class HeapReference;
explicit JSFunctionHeapData(Handle<JSFunction> function)
: function_(function) {}
Handle<JSFunction> const function_;
};
class NumberHeapData {
public:
double value() const { return value_; }
private:
friend class HeapReference;
explicit NumberHeapData(double value) : value_(value) {}
double const value_;
};
class HeapReferenceType {
public:
enum OddballType : uint8_t { kUnknown, kBoolean, kUndefined, kNull, kHole };
......@@ -39,6 +66,38 @@ class HeapReferenceType {
Flags const flags_;
};
#define HEAP_BROKER_DATA_LIST(V) \
V(JSFunction) \
V(Number)
#define HEAP_BROKER_KIND_LIST(V) \
HEAP_BROKER_DATA_LIST(V) \
V(String) \
V(InternalizedString)
class HeapReference {
public:
#define HEAP_IS_METHOD_DECL(Name) bool Is##Name() const;
HEAP_BROKER_KIND_LIST(HEAP_IS_METHOD_DECL)
#undef HEAP_IS_METHOD_DECL
#define HEAP_AS_METHOD_DECL(Name) Name##HeapData As##Name() const;
HEAP_BROKER_DATA_LIST(HEAP_AS_METHOD_DECL)
#undef HEAP_AS_METHOD_DECL
const HeapReferenceType& type() const { return type_; }
Handle<HeapObject> value() const { return object_; }
private:
friend class JSHeapBroker;
HeapReference(Handle<HeapObject> object, const HeapReferenceType& type)
: object_(object), type_(type) {}
Handle<HeapObject> const object_;
HeapReferenceType const type_;
};
class V8_EXPORT_PRIVATE JSHeapBroker : public NON_EXPORTED_BASE(ZoneObject) {
public:
JSHeapBroker(Isolate* isolate);
......@@ -47,7 +106,9 @@ class V8_EXPORT_PRIVATE JSHeapBroker : public NON_EXPORTED_BASE(ZoneObject) {
return HeapReferenceTypeFromMap(*map);
}
HeapReferenceType HeapReferenceTypeForObject(Handle<HeapObject> object) const;
HeapReference HeapReferenceForObject(Handle<Object> object) const;
static base::Optional<int> TryGetSmi(Handle<Object> object);
private:
HeapReferenceType HeapReferenceTypeFromMap(Map* map) const;
......
......@@ -87,7 +87,9 @@ namespace {
MaybeHandle<Map> GetStableMapFromObjectType(Type object_type) {
if (object_type.IsHeapConstant()) {
Handle<Map> object_map(object_type.AsHeapConstant()->Value()->map());
Handle<HeapObject> object =
Handle<HeapObject>::cast(object_type.AsHeapConstant()->Value());
Handle<Map> object_map(object->map());
if (object_map->is_stable()) return object_map;
}
return MaybeHandle<Map>();
......
......@@ -64,6 +64,7 @@ class Typer::Visitor : public Reducer {
const char* reducer_name() const override { return "Typer"; }
Reduction Reduce(Node* node) override {
DisallowHandleDereference disallow_handle_dereference;
if (node->op()->ValueOutputCount() == 0) return NoChange();
switch (node->opcode()) {
#define DECLARE_CASE(x) \
......@@ -1400,11 +1401,14 @@ Type Typer::Visitor::TypeJSObjectIsArray(Node* node) { return Type::Boolean(); }
Type Typer::Visitor::TypeDateNow(Node* node) { return Type::Number(); }
Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) {
if (fun.IsHeapConstant() && fun.AsHeapConstant()->Value()->IsJSFunction()) {
Handle<JSFunction> function =
Handle<JSFunction>::cast(fun.AsHeapConstant()->Value());
if (function->shared()->HasBuiltinFunctionId()) {
switch (function->shared()->builtin_function_id()) {
if (!fun.IsHeapConstant() || !fun.AsHeapConstant()->Ref().IsJSFunction()) {
return Type::NonInternal();
}
JSFunctionHeapData function = fun.AsHeapConstant()->Ref().AsJSFunction();
if (!function.HasBuiltinFunctionId()) {
return Type::NonInternal();
}
switch (function.GetBuiltinFunctionId()) {
case kMathRandom:
return Type::PlainNumber();
case kMathFloor:
......@@ -1667,11 +1671,8 @@ Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) {
case kWeakSetHas:
return Type::Boolean();
default:
break;
}
}
}
return Type::NonInternal();
}
}
Type Typer::Visitor::TypeJSCallForwardVarargs(Node* node) {
......
......@@ -331,18 +331,9 @@ Type::bitset BitsetType::Lub(HeapReferenceType const& type) {
UNREACHABLE();
}
Type::bitset BitsetType::Lub(const JSHeapBroker* js_heap_broker,
Handle<HeapObject> value) {
DisallowHeapAllocation no_allocation;
if (value->IsNumber()) {
return Lub(value->Number());
}
return Lub(js_heap_broker->HeapReferenceTypeForObject(value));
}
Type::bitset BitsetType::Lub(double value) {
DisallowHeapAllocation no_allocation;
if (i::IsMinusZero(value)) return kMinusZero;
if (IsMinusZero(value)) return kMinusZero;
if (std::isnan(value)) return kNaN;
if (IsUint32Double(value) || IsInt32Double(value)) return Lub(value, value);
return kOtherNumber;
......@@ -450,15 +441,12 @@ double BitsetType::Max(bitset bits) {
bool OtherNumberConstantType::IsOtherNumberConstant(double value) {
// Not an integer, not NaN, and not -0.
return !std::isnan(value) && !RangeType::IsInteger(value) &&
!i::IsMinusZero(value);
!IsMinusZero(value);
}
HeapConstantType::HeapConstantType(BitsetType::bitset bitset,
i::Handle<i::HeapObject> object)
: TypeBase(kHeapConstant), bitset_(bitset), object_(object) {
DCHECK(!object->IsHeapNumber());
DCHECK_IMPLIES(object->IsString(), object->IsInternalizedString());
}
const HeapReference& heap_ref)
: TypeBase(kHeapConstant), bitset_(bitset), heap_ref_(heap_ref) {}
// -----------------------------------------------------------------------------
// Predicates.
......@@ -804,7 +792,7 @@ Type Type::NormalizeRangeAndBitset(Type range, bitset* bits, Zone* zone) {
Type Type::NewConstant(double value, Zone* zone) {
if (RangeType::IsInteger(value)) {
return Range(value, value, zone);
} else if (i::IsMinusZero(value)) {
} else if (IsMinusZero(value)) {
return Type::MinusZero();
} else if (std::isnan(value)) {
return Type::NaN();
......@@ -816,12 +804,20 @@ Type Type::NewConstant(double value, Zone* zone) {
Type Type::NewConstant(const JSHeapBroker* js_heap_broker,
Handle<i::Object> value, Zone* zone) {
if (value->IsNumber()) {
return NewConstant(value->Number(), zone);
} else if (value->IsString() && !value->IsInternalizedString()) {
auto maybe_smi = JSHeapBroker::TryGetSmi(value);
if (maybe_smi.has_value()) {
return NewConstant(static_cast<double>(maybe_smi.value()), zone);
}
HeapReference heap_ref = js_heap_broker->HeapReferenceForObject(value);
if (heap_ref.IsNumber()) {
return NewConstant(heap_ref.AsNumber().value(), zone);
}
if (heap_ref.IsString() && !heap_ref.IsInternalizedString()) {
return Type::String();
}
return HeapConstant(js_heap_broker, Handle<HeapObject>::cast(value), zone);
return HeapConstant(js_heap_broker, value, zone);
}
Type Type::Union(Type type1, Type type2, Zone* zone) {
......@@ -1025,11 +1021,11 @@ void BitsetType::Print(bitset bits) {
#endif
BitsetType::bitset BitsetType::SignedSmall() {
return i::SmiValuesAre31Bits() ? kSigned31 : kSigned32;
return SmiValuesAre31Bits() ? kSigned31 : kSigned32;
}
BitsetType::bitset BitsetType::UnsignedSmall() {
return i::SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31;
return SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31;
}
// static
......@@ -1048,8 +1044,9 @@ Type Type::OtherNumberConstant(double value, Zone* zone) {
// static
Type Type::HeapConstant(const JSHeapBroker* js_heap_broker,
Handle<HeapObject> value, Zone* zone) {
return FromTypeBase(HeapConstantType::New(js_heap_broker, value, zone));
Handle<i::Object> value, Zone* zone) {
return FromTypeBase(HeapConstantType::New(
js_heap_broker->HeapReferenceForObject(value), zone));
}
// static
......
......@@ -252,8 +252,6 @@ class V8_EXPORT_PRIVATE BitsetType {
static bitset Glb(double min, double max);
static bitset Lub(HeapReferenceType const& type);
static bitset Lub(const JSHeapBroker* js_heap_broker,
Handle<HeapObject> value);
static bitset Lub(double value);
static bitset Lub(double min, double max);
static bitset ExpandInternals(bitset bits);
......@@ -315,7 +313,7 @@ class RangeType : public TypeBase {
double Max() const { return limits_.max; }
static bool IsInteger(double x) {
return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities.
return nearbyint(x) == x && !IsMinusZero(x); // Allows for infinities.
}
private:
......@@ -364,7 +362,7 @@ class V8_EXPORT_PRIVATE Type {
static Type OtherNumberConstant(double value, Zone* zone);
static Type HeapConstant(const JSHeapBroker* js_heap_broker,
Handle<HeapObject> value, Zone* zone);
Handle<i::Object> value, Zone* zone);
static Type Range(double min, double max, Zone* zone);
static Type Range(RangeType::Limits lims, Zone* zone);
static Type Tuple(Type first, Type second, Type third, Zone* zone);
......@@ -536,25 +534,27 @@ class OtherNumberConstantType : public TypeBase {
class V8_EXPORT_PRIVATE HeapConstantType : public NON_EXPORTED_BASE(TypeBase) {
public:
i::Handle<i::HeapObject> Value() const { return object_; }
Handle<HeapObject> Value() const { return heap_ref_.value(); }
const HeapReference& Ref() const { return heap_ref_; }
private:
friend class Type;
friend class BitsetType;
static HeapConstantType* New(const JSHeapBroker* js_heap_broker,
i::Handle<i::HeapObject> value, Zone* zone) {
BitsetType::bitset bitset = BitsetType::Lub(js_heap_broker, value);
static HeapConstantType* New(const HeapReference& heap_ref, Zone* zone) {
DCHECK(!heap_ref.IsNumber());
DCHECK_IMPLIES(heap_ref.IsString(), heap_ref.IsInternalizedString());
BitsetType::bitset bitset = BitsetType::Lub(heap_ref.type());
return new (zone->New(sizeof(HeapConstantType)))
HeapConstantType(bitset, value);
HeapConstantType(bitset, heap_ref);
}
HeapConstantType(BitsetType::bitset bitset, i::Handle<i::HeapObject> object);
HeapConstantType(BitsetType::bitset bitset, const HeapReference& heap_ref);
BitsetType::bitset Lub() const { return bitset_; }
BitsetType::bitset bitset_;
Handle<i::HeapObject> object_;
HeapReference heap_ref_;
};
// -----------------------------------------------------------------------------
......@@ -583,7 +583,7 @@ class StructuralType : public TypeBase {
length_ = length;
}
StructuralType(Kind kind, int length, i::Zone* zone)
StructuralType(Kind kind, int length, Zone* zone)
: TypeBase(kind), length_(length) {
elements_ = reinterpret_cast<Type*>(zone->New(sizeof(Type) * length));
}
......
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