Commit 978fe70b authored by mvstanton's avatar mvstanton Committed by Commit bot

[Turbofan] Introduce OtherNumberConstant.

With this CL, we devolve all Constants introduced as they are with an object handle into

* Range - for integers
* Nan
* MinusZero
* OtherNumberConstant - for doubles
* HeapConstant

We reduce the amount we have to inspect an object handle during optimization. Also, simplifications result. For example, you never have to check if a Range contains a HeapConstant.

BUG=

Review-Url: https://codereview.chromium.org/2381523002
Cr-Commit-Position: refs/heads/master@{#40041}
parent 1f89d369
...@@ -330,9 +330,9 @@ bool HasInstanceTypeWitness(Node* receiver, Node* effect, ...@@ -330,9 +330,9 @@ bool HasInstanceTypeWitness(Node* receiver, Node* effect,
for (int i = 1; i < dominator->op()->ValueInputCount(); ++i) { for (int i = 1; i < dominator->op()->ValueInputCount(); ++i) {
Node* const map = NodeProperties::GetValueInput(dominator, i); Node* const map = NodeProperties::GetValueInput(dominator, i);
Type* const map_type = NodeProperties::GetType(map); Type* const map_type = NodeProperties::GetType(map);
if (!map_type->IsConstant()) return false; if (!map_type->IsHeapConstant()) return false;
Handle<Map> const map_value = Handle<Map> const map_value =
Handle<Map>::cast(map_type->AsConstant()->Value()); Handle<Map>::cast(map_type->AsHeapConstant()->Value());
if (map_value->instance_type() != instance_type) return false; if (map_value->instance_type() != instance_type) return false;
} }
return true; return true;
......
...@@ -231,13 +231,12 @@ Reduction JSCreateLowering::ReduceJSCreate(Node* node) { ...@@ -231,13 +231,12 @@ Reduction JSCreateLowering::ReduceJSCreate(Node* node) {
Type* const new_target_type = NodeProperties::GetType(new_target); Type* const new_target_type = NodeProperties::GetType(new_target);
Node* const effect = NodeProperties::GetEffectInput(node); Node* const effect = NodeProperties::GetEffectInput(node);
// Extract constructor and original constructor function. // Extract constructor and original constructor function.
if (target_type->IsConstant() && if (target_type->IsHeapConstant() && new_target_type->IsHeapConstant() &&
new_target_type->IsConstant() && new_target_type->AsHeapConstant()->Value()->IsJSFunction()) {
new_target_type->AsConstant()->Value()->IsJSFunction()) {
Handle<JSFunction> constructor = Handle<JSFunction> constructor =
Handle<JSFunction>::cast(target_type->AsConstant()->Value()); Handle<JSFunction>::cast(target_type->AsHeapConstant()->Value());
Handle<JSFunction> original_constructor = Handle<JSFunction> original_constructor =
Handle<JSFunction>::cast(new_target_type->AsConstant()->Value()); Handle<JSFunction>::cast(new_target_type->AsHeapConstant()->Value());
DCHECK(constructor->IsConstructor()); DCHECK(constructor->IsConstructor());
DCHECK(original_constructor->IsConstructor()); DCHECK(original_constructor->IsConstructor());
......
...@@ -82,16 +82,16 @@ class JSBinopReduction final { ...@@ -82,16 +82,16 @@ class JSBinopReduction final {
if (BothInputsAre(Type::String()) || if (BothInputsAre(Type::String()) ||
((lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) && ((lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) &&
BinaryOperationHintOf(node_->op()) == BinaryOperationHint::kString)) { BinaryOperationHintOf(node_->op()) == BinaryOperationHint::kString)) {
if (left_type()->IsConstant() && if (left_type()->IsHeapConstant() &&
left_type()->AsConstant()->Value()->IsString()) { left_type()->AsHeapConstant()->Value()->IsString()) {
Handle<String> left_string = Handle<String> left_string =
Handle<String>::cast(left_type()->AsConstant()->Value()); Handle<String>::cast(left_type()->AsHeapConstant()->Value());
if (left_string->length() >= ConsString::kMinLength) return true; if (left_string->length() >= ConsString::kMinLength) return true;
} }
if (right_type()->IsConstant() && if (right_type()->IsHeapConstant() &&
right_type()->AsConstant()->Value()->IsString()) { right_type()->AsHeapConstant()->Value()->IsString()) {
Handle<String> right_string = Handle<String> right_string =
Handle<String>::cast(right_type()->AsConstant()->Value()); Handle<String>::cast(right_type()->AsHeapConstant()->Value());
if (right_string->length() >= ConsString::kMinLength) return true; if (right_string->length() >= ConsString::kMinLength) return true;
} }
} }
...@@ -447,7 +447,6 @@ class JSBinopReduction final { ...@@ -447,7 +447,6 @@ class JSBinopReduction final {
// - immediately put in type bounds for all new nodes // - immediately put in type bounds for all new nodes
// - relax effects from generic but not-side-effecting operations // - relax effects from generic but not-side-effecting operations
JSTypedLowering::JSTypedLowering(Editor* editor, JSTypedLowering::JSTypedLowering(Editor* editor,
CompilationDependencies* dependencies, CompilationDependencies* dependencies,
Flags flags, JSGraph* jsgraph, Zone* zone) Flags flags, JSGraph* jsgraph, Zone* zone)
...@@ -456,7 +455,7 @@ JSTypedLowering::JSTypedLowering(Editor* editor, ...@@ -456,7 +455,7 @@ JSTypedLowering::JSTypedLowering(Editor* editor,
flags_(flags), flags_(flags),
jsgraph_(jsgraph), jsgraph_(jsgraph),
the_hole_type_( the_hole_type_(
Type::Constant(factory()->the_hole_value(), graph()->zone())), Type::HeapConstant(factory()->the_hole_value(), graph()->zone())),
type_cache_(TypeCache::Get()) { type_cache_(TypeCache::Get()) {
for (size_t k = 0; k < arraysize(shifted_int32_ranges_); ++k) { for (size_t k = 0; k < arraysize(shifted_int32_ranges_); ++k) {
double min = kMinInt / (1 << k); double min = kMinInt / (1 << k);
...@@ -598,9 +597,9 @@ Reduction JSTypedLowering::ReduceCreateConsString(Node* node) { ...@@ -598,9 +597,9 @@ Reduction JSTypedLowering::ReduceCreateConsString(Node* node) {
// Determine the {first} length. // Determine the {first} length.
Node* first_length = Node* first_length =
first_type->IsConstant() first_type->IsHeapConstant()
? jsgraph()->Constant( ? jsgraph()->Constant(
Handle<String>::cast(first_type->AsConstant()->Value()) Handle<String>::cast(first_type->AsHeapConstant()->Value())
->length()) ->length())
: effect = graph()->NewNode( : effect = graph()->NewNode(
simplified()->LoadField(AccessBuilder::ForStringLength()), simplified()->LoadField(AccessBuilder::ForStringLength()),
...@@ -608,9 +607,9 @@ Reduction JSTypedLowering::ReduceCreateConsString(Node* node) { ...@@ -608,9 +607,9 @@ Reduction JSTypedLowering::ReduceCreateConsString(Node* node) {
// Determine the {second} length. // Determine the {second} length.
Node* second_length = Node* second_length =
second_type->IsConstant() second_type->IsHeapConstant()
? jsgraph()->Constant( ? jsgraph()->Constant(
Handle<String>::cast(second_type->AsConstant()->Value()) Handle<String>::cast(second_type->AsHeapConstant()->Value())
->length()) ->length())
: effect = graph()->NewNode( : effect = graph()->NewNode(
simplified()->LoadField(AccessBuilder::ForStringLength()), simplified()->LoadField(AccessBuilder::ForStringLength()),
...@@ -980,8 +979,8 @@ Reduction JSTypedLowering::ReduceJSToLength(Node* node) { ...@@ -980,8 +979,8 @@ Reduction JSTypedLowering::ReduceJSToLength(Node* node) {
Reduction JSTypedLowering::ReduceJSToNumberInput(Node* input) { Reduction JSTypedLowering::ReduceJSToNumberInput(Node* input) {
// Try constant-folding of JSToNumber with constant inputs. // Try constant-folding of JSToNumber with constant inputs.
Type* input_type = NodeProperties::GetType(input); Type* input_type = NodeProperties::GetType(input);
if (input_type->IsConstant()) { if (input_type->IsHeapConstant()) {
Handle<Object> input_value = input_type->AsConstant()->Value(); Handle<Object> input_value = input_type->AsHeapConstant()->Value();
if (input_value->IsString()) { if (input_value->IsString()) {
return Replace(jsgraph()->Constant( return Replace(jsgraph()->Constant(
String::ToNumber(Handle<String>::cast(input_value)))); String::ToNumber(Handle<String>::cast(input_value))));
...@@ -1280,13 +1279,13 @@ Reduction JSTypedLowering::ReduceJSInstanceOf(Node* node) { ...@@ -1280,13 +1279,13 @@ Reduction JSTypedLowering::ReduceJSInstanceOf(Node* node) {
Node* effect = r.effect(); Node* effect = r.effect();
Node* control = r.control(); Node* control = r.control();
if (!r.right_type()->IsConstant() || if (!r.right_type()->IsHeapConstant() ||
!r.right_type()->AsConstant()->Value()->IsJSFunction()) { !r.right_type()->AsHeapConstant()->Value()->IsJSFunction()) {
return NoChange(); return NoChange();
} }
Handle<JSFunction> function = Handle<JSFunction> function =
Handle<JSFunction>::cast(r.right_type()->AsConstant()->Value()); Handle<JSFunction>::cast(r.right_type()->AsHeapConstant()->Value());
Handle<SharedFunctionInfo> shared(function->shared(), isolate()); Handle<SharedFunctionInfo> shared(function->shared(), isolate());
// Make sure the prototype of {function} is the %FunctionPrototype%, and it // Make sure the prototype of {function} is the %FunctionPrototype%, and it
...@@ -1485,9 +1484,9 @@ Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) { ...@@ -1485,9 +1484,9 @@ Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) {
// with the global proxy unconditionally. // with the global proxy unconditionally.
if (receiver_type->Is(Type::NullOrUndefined()) || if (receiver_type->Is(Type::NullOrUndefined()) ||
mode == ConvertReceiverMode::kNullOrUndefined) { mode == ConvertReceiverMode::kNullOrUndefined) {
if (context_type->IsConstant()) { if (context_type->IsHeapConstant()) {
Handle<JSObject> global_proxy( Handle<JSObject> global_proxy(
Handle<Context>::cast(context_type->AsConstant()->Value()) Handle<Context>::cast(context_type->AsHeapConstant()->Value())
->global_proxy(), ->global_proxy(),
isolate()); isolate());
receiver = jsgraph()->Constant(global_proxy); receiver = jsgraph()->Constant(global_proxy);
...@@ -1590,9 +1589,9 @@ Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) { ...@@ -1590,9 +1589,9 @@ Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) {
Node* eglobal = effect; Node* eglobal = effect;
Node* rglobal; Node* rglobal;
{ {
if (context_type->IsConstant()) { if (context_type->IsHeapConstant()) {
Handle<JSObject> global_proxy( Handle<JSObject> global_proxy(
Handle<Context>::cast(context_type->AsConstant()->Value()) Handle<Context>::cast(context_type->AsHeapConstant()->Value())
->global_proxy(), ->global_proxy(),
isolate()); isolate());
rglobal = jsgraph()->Constant(global_proxy); rglobal = jsgraph()->Constant(global_proxy);
...@@ -1715,10 +1714,10 @@ Reduction JSTypedLowering::ReduceJSCallConstruct(Node* node) { ...@@ -1715,10 +1714,10 @@ Reduction JSTypedLowering::ReduceJSCallConstruct(Node* node) {
Node* control = NodeProperties::GetControlInput(node); Node* control = NodeProperties::GetControlInput(node);
// Check if {target} is a known JSFunction. // Check if {target} is a known JSFunction.
if (target_type->IsConstant() && if (target_type->IsHeapConstant() &&
target_type->AsConstant()->Value()->IsJSFunction()) { target_type->AsHeapConstant()->Value()->IsJSFunction()) {
Handle<JSFunction> function = Handle<JSFunction> function =
Handle<JSFunction>::cast(target_type->AsConstant()->Value()); Handle<JSFunction>::cast(target_type->AsHeapConstant()->Value());
Handle<SharedFunctionInfo> shared(function->shared(), isolate()); Handle<SharedFunctionInfo> shared(function->shared(), isolate());
const int builtin_index = shared->construct_stub()->builtin_index(); const int builtin_index = shared->construct_stub()->builtin_index();
const bool is_builtin = (builtin_index != -1); const bool is_builtin = (builtin_index != -1);
...@@ -1800,10 +1799,10 @@ Reduction JSTypedLowering::ReduceJSCallFunction(Node* node) { ...@@ -1800,10 +1799,10 @@ Reduction JSTypedLowering::ReduceJSCallFunction(Node* node) {
} }
// Check if {target} is a known JSFunction. // Check if {target} is a known JSFunction.
if (target_type->IsConstant() && if (target_type->IsHeapConstant() &&
target_type->AsConstant()->Value()->IsJSFunction()) { target_type->AsHeapConstant()->Value()->IsJSFunction()) {
Handle<JSFunction> function = Handle<JSFunction> function =
Handle<JSFunction>::cast(target_type->AsConstant()->Value()); Handle<JSFunction>::cast(target_type->AsHeapConstant()->Value());
Handle<SharedFunctionInfo> shared(function->shared(), isolate()); Handle<SharedFunctionInfo> shared(function->shared(), isolate());
const int builtin_index = shared->code()->builtin_index(); const int builtin_index = shared->code()->builtin_index();
const bool is_builtin = (builtin_index != -1); const bool is_builtin = (builtin_index != -1);
......
...@@ -19,14 +19,14 @@ namespace compiler { ...@@ -19,14 +19,14 @@ namespace compiler {
OperationTyper::OperationTyper(Isolate* isolate, Zone* zone) OperationTyper::OperationTyper(Isolate* isolate, Zone* zone)
: zone_(zone), cache_(TypeCache::Get()) { : zone_(zone), cache_(TypeCache::Get()) {
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
infinity_ = Type::Constant(factory->infinity_value(), zone); infinity_ = Type::NewConstant(factory->infinity_value(), zone);
minus_infinity_ = Type::Constant(factory->minus_infinity_value(), zone); minus_infinity_ = Type::NewConstant(factory->minus_infinity_value(), zone);
Type* truncating_to_zero = Type::MinusZeroOrNaN(); Type* truncating_to_zero = Type::MinusZeroOrNaN();
DCHECK(!truncating_to_zero->Maybe(Type::Integral32())); DCHECK(!truncating_to_zero->Maybe(Type::Integral32()));
singleton_false_ = Type::Constant(factory->false_value(), zone); singleton_false_ = Type::HeapConstant(factory->false_value(), zone);
singleton_true_ = Type::Constant(factory->true_value(), zone); singleton_true_ = Type::HeapConstant(factory->true_value(), zone);
singleton_the_hole_ = Type::Constant(factory->the_hole_value(), zone); singleton_the_hole_ = Type::HeapConstant(factory->the_hole_value(), zone);
signed32ish_ = Type::Union(Type::Signed32(), truncating_to_zero, zone); signed32ish_ = Type::Union(Type::Signed32(), truncating_to_zero, zone);
unsigned32ish_ = Type::Union(Type::Unsigned32(), truncating_to_zero, zone); unsigned32ish_ = Type::Union(Type::Unsigned32(), truncating_to_zero, zone);
} }
......
...@@ -1031,10 +1031,10 @@ class RepresentationSelector { ...@@ -1031,10 +1031,10 @@ class RepresentationSelector {
// undefined, because these special oddballs are always in the root set. // undefined, because these special oddballs are always in the root set.
return kNoWriteBarrier; return kNoWriteBarrier;
} }
if (value_type->IsConstant() && if (value_type->IsHeapConstant() &&
value_type->AsConstant()->Value()->IsHeapObject()) { value_type->AsHeapConstant()->Value()->IsHeapObject()) {
Handle<HeapObject> value_object = Handle<HeapObject> value_object =
Handle<HeapObject>::cast(value_type->AsConstant()->Value()); Handle<HeapObject>::cast(value_type->AsHeapConstant()->Value());
RootIndexMap root_index_map(jsgraph_->isolate()); RootIndexMap root_index_map(jsgraph_->isolate());
int root_index = root_index_map.Lookup(*value_object); int root_index = root_index_map.Lookup(*value_object);
if (root_index != RootIndexMap::kInvalidRootIndex && if (root_index != RootIndexMap::kInvalidRootIndex &&
......
...@@ -22,8 +22,9 @@ TypedOptimization::TypedOptimization(Editor* editor, ...@@ -22,8 +22,9 @@ TypedOptimization::TypedOptimization(Editor* editor,
dependencies_(dependencies), dependencies_(dependencies),
flags_(flags), flags_(flags),
jsgraph_(jsgraph), jsgraph_(jsgraph),
true_type_(Type::Constant(factory()->true_value(), graph()->zone())), true_type_(Type::HeapConstant(factory()->true_value(), graph()->zone())),
false_type_(Type::Constant(factory()->false_value(), graph()->zone())), false_type_(
Type::HeapConstant(factory()->false_value(), graph()->zone())),
type_cache_(TypeCache::Get()) {} type_cache_(TypeCache::Get()) {}
TypedOptimization::~TypedOptimization() {} TypedOptimization::~TypedOptimization() {}
...@@ -43,8 +44,9 @@ Reduction TypedOptimization::Reduce(Node* node) { ...@@ -43,8 +44,9 @@ Reduction TypedOptimization::Reduce(Node* node) {
// the Operator::kNoDeopt property). // the Operator::kNoDeopt property).
Type* upper = NodeProperties::GetType(node); Type* upper = NodeProperties::GetType(node);
if (upper->IsInhabited()) { if (upper->IsInhabited()) {
if (upper->IsConstant()) { if (upper->IsHeapConstant()) {
Node* replacement = jsgraph()->Constant(upper->AsConstant()->Value()); Node* replacement =
jsgraph()->Constant(upper->AsHeapConstant()->Value());
ReplaceWithValue(node, replacement); ReplaceWithValue(node, replacement);
return Changed(replacement); return Changed(replacement);
} else if (upper->Is(Type::MinusZero())) { } else if (upper->Is(Type::MinusZero())) {
...@@ -96,10 +98,11 @@ Reduction TypedOptimization::Reduce(Node* node) { ...@@ -96,10 +98,11 @@ Reduction TypedOptimization::Reduce(Node* node) {
namespace { namespace {
MaybeHandle<Map> GetStableMapFromObjectType(Type* object_type) { MaybeHandle<Map> GetStableMapFromObjectType(Type* object_type) {
if (object_type->IsConstant() && if (object_type->IsHeapConstant() &&
object_type->AsConstant()->Value()->IsHeapObject()) { object_type->AsHeapConstant()->Value()->IsHeapObject()) {
Handle<Map> object_map( Handle<Map> object_map(
Handle<HeapObject>::cast(object_type->AsConstant()->Value())->map()); Handle<HeapObject>::cast(object_type->AsHeapConstant()->Value())
->map());
if (object_map->is_stable()) return object_map; if (object_map->is_stable()) return object_map;
} }
return MaybeHandle<Map>(); return MaybeHandle<Map>();
...@@ -121,8 +124,8 @@ Reduction TypedOptimization::ReduceCheckMaps(Node* node) { ...@@ -121,8 +124,8 @@ Reduction TypedOptimization::ReduceCheckMaps(Node* node) {
for (int i = 1; i < node->op()->ValueInputCount(); ++i) { for (int i = 1; i < node->op()->ValueInputCount(); ++i) {
Node* const map = NodeProperties::GetValueInput(node, i); Node* const map = NodeProperties::GetValueInput(node, i);
Type* const map_type = NodeProperties::GetType(map); Type* const map_type = NodeProperties::GetType(map);
if (map_type->IsConstant() && if (map_type->IsHeapConstant() &&
map_type->AsConstant()->Value().is_identical_to(object_map)) { map_type->AsHeapConstant()->Value().is_identical_to(object_map)) {
if (object_map->CanTransition()) { if (object_map->CanTransition()) {
dependencies()->AssumeMapStable(object_map); dependencies()->AssumeMapStable(object_map);
} }
......
...@@ -41,9 +41,9 @@ Typer::Typer(Isolate* isolate, Graph* graph) ...@@ -41,9 +41,9 @@ Typer::Typer(Isolate* isolate, Graph* graph)
Zone* zone = this->zone(); Zone* zone = this->zone();
Factory* const factory = isolate->factory(); Factory* const factory = isolate->factory();
singleton_false_ = Type::Constant(factory->false_value(), zone); singleton_false_ = Type::HeapConstant(factory->false_value(), zone);
singleton_true_ = Type::Constant(factory->true_value(), zone); singleton_true_ = Type::HeapConstant(factory->true_value(), zone);
singleton_the_hole_ = Type::Constant(factory->the_hole_value(), zone); singleton_the_hole_ = Type::HeapConstant(factory->the_hole_value(), zone);
falsish_ = Type::Union( falsish_ = Type::Union(
Type::Undetectable(), Type::Undetectable(),
Type::Union(Type::Union(singleton_false_, cache_.kZeroish, zone), Type::Union(Type::Union(singleton_false_, cache_.kZeroish, zone),
...@@ -604,15 +604,10 @@ Type* Typer::Visitor::TypeFloat64Constant(Node* node) { ...@@ -604,15 +604,10 @@ Type* Typer::Visitor::TypeFloat64Constant(Node* node) {
Type* Typer::Visitor::TypeNumberConstant(Node* node) { Type* Typer::Visitor::TypeNumberConstant(Node* node) {
Factory* f = isolate()->factory();
double number = OpParameter<double>(node); double number = OpParameter<double>(node);
if (Type::IsInteger(number)) { return Type::NewConstant(number, zone());
return Type::Range(number, number, zone());
}
return Type::Constant(f->NewNumber(number), zone());
} }
Type* Typer::Visitor::TypeHeapConstant(Node* node) { Type* Typer::Visitor::TypeHeapConstant(Node* node) {
return TypeConstant(OpParameter<Handle<HeapObject>>(node)); return TypeConstant(OpParameter<Handle<HeapObject>>(node));
} }
...@@ -836,7 +831,7 @@ Type* Typer::Visitor::JSEqualTyper(Type* lhs, Type* rhs, Typer* t) { ...@@ -836,7 +831,7 @@ Type* Typer::Visitor::JSEqualTyper(Type* lhs, Type* rhs, Typer* t) {
(lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) { (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) {
return t->singleton_false_; return t->singleton_false_;
} }
if (lhs->IsConstant() && rhs->Is(lhs)) { if (lhs->IsHeapConstant() && rhs->Is(lhs)) {
// Types are equal and are inhabited only by a single semantic value, // Types are equal and are inhabited only by a single semantic value,
// which is not nan due to the earlier check. // which is not nan due to the earlier check.
return t->singleton_true_; return t->singleton_true_;
...@@ -873,7 +868,7 @@ Type* Typer::Visitor::JSStrictEqualTyper(Type* lhs, Type* rhs, Typer* t) { ...@@ -873,7 +868,7 @@ Type* Typer::Visitor::JSStrictEqualTyper(Type* lhs, Type* rhs, Typer* t) {
!lhs->Maybe(rhs)) { !lhs->Maybe(rhs)) {
return t->singleton_false_; return t->singleton_false_;
} }
if (lhs->IsConstant() && rhs->Is(lhs)) { if (lhs->IsHeapConstant() && rhs->Is(lhs)) {
// Types are equal and are inhabited only by a single semantic value, // Types are equal and are inhabited only by a single semantic value,
// which is not nan due to the earlier check. // which is not nan due to the earlier check.
return t->singleton_true_; return t->singleton_true_;
...@@ -907,7 +902,7 @@ Typer::Visitor::ComparisonOutcome Typer::Visitor::JSCompareTyper(Type* lhs, ...@@ -907,7 +902,7 @@ Typer::Visitor::ComparisonOutcome Typer::Visitor::JSCompareTyper(Type* lhs,
if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return kComparisonUndefined; if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return kComparisonUndefined;
ComparisonOutcome result; ComparisonOutcome result;
if (lhs->IsConstant() && rhs->Is(lhs)) { if (lhs->IsHeapConstant() && rhs->Is(lhs)) {
// Types are equal and are inhabited only by a single semantic value. // Types are equal and are inhabited only by a single semantic value.
result = kComparisonFalse; result = kComparisonFalse;
} else if (lhs->Min() >= rhs->Max()) { } else if (lhs->Min() >= rhs->Max()) {
...@@ -1021,23 +1016,26 @@ Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { ...@@ -1021,23 +1016,26 @@ Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
Type* Typer::Visitor::JSTypeOfTyper(Type* type, Typer* t) { Type* Typer::Visitor::JSTypeOfTyper(Type* type, Typer* t) {
Factory* const f = t->isolate()->factory(); Factory* const f = t->isolate()->factory();
if (type->Is(Type::Boolean())) { if (type->Is(Type::Boolean())) {
return Type::Constant(f->boolean_string(), t->zone()); return Type::HeapConstant(f->boolean_string(), t->zone());
} else if (type->Is(Type::Number())) { } else if (type->Is(Type::Number())) {
return Type::Constant(f->number_string(), t->zone()); return Type::HeapConstant(f->number_string(), t->zone());
} else if (type->Is(Type::String())) { } else if (type->Is(Type::String())) {
return Type::Constant(f->string_string(), t->zone()); return Type::HeapConstant(f->string_string(), t->zone());
} else if (type->Is(Type::Symbol())) { } else if (type->Is(Type::Symbol())) {
return Type::Constant(f->symbol_string(), t->zone()); return Type::HeapConstant(f->symbol_string(), t->zone());
} else if (type->Is(Type::Union(Type::Undefined(), Type::OtherUndetectable(), } else if (type->Is(Type::Union(Type::Undefined(), Type::OtherUndetectable(),
t->zone()))) { t->zone()))) {
return Type::Constant(f->undefined_string(), t->zone()); return Type::HeapConstant(f->undefined_string(), t->zone());
} else if (type->Is(Type::Null())) { } else if (type->Is(Type::Null())) {
return Type::Constant(f->object_string(), t->zone()); return Type::HeapConstant(f->object_string(), t->zone());
} else if (type->Is(Type::Function())) { } else if (type->Is(Type::Function())) {
return Type::Constant(f->function_string(), t->zone()); return Type::HeapConstant(f->function_string(), t->zone());
} else if (type->IsConstant()) { } else if (type->IsHeapConstant()) {
return Type::Constant( return Type::HeapConstant(
Object::TypeOf(t->isolate(), type->AsConstant()->Value()), t->zone()); Object::TypeOf(t->isolate(), type->AsHeapConstant()->Value()),
t->zone());
} else if (type->IsOtherNumberConstant()) {
return Type::HeapConstant(f->number_string(), t->zone());
} }
return Type::InternalizedString(); return Type::InternalizedString();
} }
...@@ -1292,9 +1290,9 @@ Type* Typer::Visitor::TypeJSCallConstruct(Node* node) { ...@@ -1292,9 +1290,9 @@ Type* Typer::Visitor::TypeJSCallConstruct(Node* node) {
Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) { Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) {
if (fun->IsConstant() && fun->AsConstant()->Value()->IsJSFunction()) { if (fun->IsHeapConstant() && fun->AsHeapConstant()->Value()->IsJSFunction()) {
Handle<JSFunction> function = Handle<JSFunction> function =
Handle<JSFunction>::cast(fun->AsConstant()->Value()); Handle<JSFunction>::cast(fun->AsHeapConstant()->Value());
if (function->shared()->HasBuiltinFunctionId()) { if (function->shared()->HasBuiltinFunctionId()) {
switch (function->shared()->builtin_function_id()) { switch (function->shared()->builtin_function_id()) {
case kMathRandom: case kMathRandom:
...@@ -1537,7 +1535,7 @@ Type* Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) { ...@@ -1537,7 +1535,7 @@ Type* Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) {
// static // static
Type* Typer::Visitor::ReferenceEqualTyper(Type* lhs, Type* rhs, Typer* t) { Type* Typer::Visitor::ReferenceEqualTyper(Type* lhs, Type* rhs, Typer* t) {
if (lhs->IsConstant() && rhs->Is(lhs)) { if (lhs->IsHeapConstant() && rhs->Is(lhs)) {
return t->singleton_true_; return t->singleton_true_;
} }
return Type::Boolean(); return Type::Boolean();
...@@ -1564,7 +1562,7 @@ Type* Typer::Visitor::StringFromCharCodeTyper(Type* type, Typer* t) { ...@@ -1564,7 +1562,7 @@ Type* Typer::Visitor::StringFromCharCodeTyper(Type* type, Typer* t) {
if (min == max) { if (min == max) {
uint32_t code = static_cast<uint32_t>(min) & String::kMaxUtf16CodeUnitU; uint32_t code = static_cast<uint32_t>(min) & String::kMaxUtf16CodeUnitU;
Handle<String> string = f->LookupSingleCharacterStringFromCode(code); Handle<String> string = f->LookupSingleCharacterStringFromCode(code);
return Type::Constant(string, t->zone()); return Type::HeapConstant(string, t->zone());
} }
return Type::String(); return Type::String();
} }
...@@ -1577,7 +1575,7 @@ Type* Typer::Visitor::StringFromCodePointTyper(Type* type, Typer* t) { ...@@ -1577,7 +1575,7 @@ Type* Typer::Visitor::StringFromCodePointTyper(Type* type, Typer* t) {
if (min == max) { if (min == max) {
uint32_t code = static_cast<uint32_t>(min) & String::kMaxUtf16CodeUnitU; uint32_t code = static_cast<uint32_t>(min) & String::kMaxUtf16CodeUnitU;
Handle<String> string = f->LookupSingleCharacterStringFromCode(code); Handle<String> string = f->LookupSingleCharacterStringFromCode(code);
return Type::Constant(string, t->zone()); return Type::HeapConstant(string, t->zone());
} }
return Type::String(); return Type::String();
} }
...@@ -1752,7 +1750,7 @@ Type* Typer::Visitor::TypeConstant(Handle<Object> value) { ...@@ -1752,7 +1750,7 @@ Type* Typer::Visitor::TypeConstant(Handle<Object> value) {
if (Type::IsInteger(*value)) { if (Type::IsInteger(*value)) {
return Type::Range(value->Number(), value->Number(), zone()); return Type::Range(value->Number(), value->Number(), zone());
} }
return Type::Constant(value, zone()); return Type::NewConstant(value, zone());
} }
} // namespace compiler } // namespace compiler
......
...@@ -56,12 +56,6 @@ bool Type::Contains(RangeType* lhs, RangeType* rhs) { ...@@ -56,12 +56,6 @@ bool Type::Contains(RangeType* lhs, RangeType* rhs) {
return lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max(); return lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max();
} }
bool Type::Contains(RangeType* lhs, ConstantType* rhs) {
DisallowHeapAllocation no_allocation;
return IsInteger(*rhs->Value()) && lhs->Min() <= rhs->Value()->Number() &&
rhs->Value()->Number() <= lhs->Max();
}
bool Type::Contains(RangeType* range, i::Object* val) { bool Type::Contains(RangeType* range, i::Object* val) {
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
return IsInteger(val) && range->Min() <= val->Number() && return IsInteger(val) && range->Min() <= val->Number() &&
...@@ -82,7 +76,8 @@ double Type::Min() { ...@@ -82,7 +76,8 @@ double Type::Min() {
return min; return min;
} }
if (this->IsRange()) return this->AsRange()->Min(); if (this->IsRange()) return this->AsRange()->Min();
if (this->IsConstant()) return this->AsConstant()->Value()->Number(); if (this->IsOtherNumberConstant())
return this->AsOtherNumberConstant()->Value();
UNREACHABLE(); UNREACHABLE();
return 0; return 0;
} }
...@@ -98,7 +93,8 @@ double Type::Max() { ...@@ -98,7 +93,8 @@ double Type::Max() {
return max; return max;
} }
if (this->IsRange()) return this->AsRange()->Max(); if (this->IsRange()) return this->AsRange()->Max();
if (this->IsConstant()) return this->AsConstant()->Value()->Number(); if (this->IsOtherNumberConstant())
return this->AsOtherNumberConstant()->Value();
UNREACHABLE(); UNREACHABLE();
return 0; return 0;
} }
...@@ -139,7 +135,9 @@ Type::bitset BitsetType::Lub(Type* type) { ...@@ -139,7 +135,9 @@ Type::bitset BitsetType::Lub(Type* type) {
} }
return bitset; return bitset;
} }
if (type->IsConstant()) return type->AsConstant()->Lub(); if (type->IsHeapConstant()) return type->AsHeapConstant()->Lub();
if (type->IsOtherNumberConstant())
return type->AsOtherNumberConstant()->Lub();
if (type->IsRange()) return type->AsRange()->Lub(); if (type->IsRange()) return type->AsRange()->Lub();
if (type->IsTuple()) return kOtherInternal; if (type->IsTuple()) return kOtherInternal;
UNREACHABLE(); UNREACHABLE();
...@@ -390,14 +388,43 @@ double BitsetType::Max(bitset bits) { ...@@ -390,14 +388,43 @@ double BitsetType::Max(bitset bits) {
return std::numeric_limits<double>::quiet_NaN(); return std::numeric_limits<double>::quiet_NaN();
} }
// static
bool OtherNumberConstantType::IsOtherNumberConstant(double value) {
// Not an integer, not NaN, and not -0.
return !std::isnan(value) && !Type::IsInteger(value) &&
!i::IsMinusZero(value);
}
// static
bool OtherNumberConstantType::IsOtherNumberConstant(Object* value) {
return value->IsHeapNumber() &&
IsOtherNumberConstant(HeapNumber::cast(value)->value());
}
HeapConstantType::HeapConstantType(BitsetType::bitset bitset,
i::Handle<i::Object> object)
: TypeBase(kHeapConstant), bitset_(bitset), object_(object) {
// All number types should be expressed as Ranges, OtherNumberConstants,
// or bitsets (nan, negative-zero).
DCHECK(!object->IsSmi() && !object->IsHeapNumber());
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Predicates. // Predicates.
bool Type::SimplyEquals(Type* that) { bool Type::SimplyEquals(Type* that) {
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
if (this->IsConstant()) { if (this->IsHeapConstant()) {
return that->IsConstant() && return that->IsHeapConstant() &&
*this->AsConstant()->Value() == *that->AsConstant()->Value(); *this->AsHeapConstant()->Value() == *that->AsHeapConstant()->Value();
}
if (this->IsOtherNumberConstant()) {
return that->IsOtherNumberConstant() &&
this->AsOtherNumberConstant()->Value() ==
that->AsOtherNumberConstant()->Value();
}
if (this->IsRange()) {
if (that->IsHeapConstant() || that->IsOtherNumberConstant()) return false;
} }
if (this->IsTuple()) { if (this->IsTuple()) {
if (!that->IsTuple()) return false; if (!that->IsTuple()) return false;
...@@ -446,9 +473,7 @@ bool Type::SlowIs(Type* that) { ...@@ -446,9 +473,7 @@ bool Type::SlowIs(Type* that) {
} }
if (that->IsRange()) { if (that->IsRange()) {
return (this->IsRange() && Contains(that->AsRange(), this->AsRange())) || return (this->IsRange() && Contains(that->AsRange(), this->AsRange()));
(this->IsConstant() &&
Contains(that->AsRange(), this->AsConstant()));
} }
if (this->IsRange()) return false; if (this->IsRange()) return false;
...@@ -481,9 +506,6 @@ bool Type::Maybe(Type* that) { ...@@ -481,9 +506,6 @@ bool Type::Maybe(Type* that) {
if (this->IsBitset() && that->IsBitset()) return true; if (this->IsBitset() && that->IsBitset()) return true;
if (this->IsRange()) { if (this->IsRange()) {
if (that->IsConstant()) {
return Contains(this->AsRange(), that->AsConstant());
}
if (that->IsRange()) { if (that->IsRange()) {
return Overlap(this->AsRange(), that->AsRange()); return Overlap(this->AsRange(), that->AsRange());
} }
...@@ -673,9 +695,6 @@ int Type::IntersectAux(Type* lhs, Type* rhs, UnionType* result, int size, ...@@ -673,9 +695,6 @@ int Type::IntersectAux(Type* lhs, Type* rhs, UnionType* result, int size,
} }
return size; return size;
} }
if (rhs->IsConstant() && Contains(lhs->AsRange(), rhs->AsConstant())) {
return AddToUnion(rhs, result, size, zone);
}
if (rhs->IsRange()) { if (rhs->IsRange()) {
RangeType::Limits lim = RangeType::Limits::Intersect( RangeType::Limits lim = RangeType::Limits::Intersect(
RangeType::Limits(lhs->AsRange()), RangeType::Limits(rhs->AsRange())); RangeType::Limits(lhs->AsRange()), RangeType::Limits(rhs->AsRange()));
...@@ -743,6 +762,29 @@ Type* Type::NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone) { ...@@ -743,6 +762,29 @@ Type* Type::NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone) {
return RangeType::New(range_min, range_max, zone); return RangeType::New(range_min, range_max, zone);
} }
Type* Type::NewConstant(double value, Zone* zone) {
if (IsInteger(value)) {
return Range(value, value, zone);
} else if (i::IsMinusZero(value)) {
return Type::MinusZero();
} else if (std::isnan(value)) {
return Type::NaN();
}
DCHECK(OtherNumberConstantType::IsOtherNumberConstant(value));
return OtherNumberConstant(value, zone);
}
Type* Type::NewConstant(i::Handle<i::Object> value, Zone* zone) {
if (IsInteger(*value)) {
double v = value->Number();
return Range(v, v, zone);
} else if (value->IsHeapNumber()) {
return NewConstant(value->Number(), zone);
}
return HeapConstant(value, zone);
}
Type* Type::Union(Type* type1, Type* type2, Zone* zone) { Type* Type::Union(Type* type1, Type* type2, Zone* zone) {
// Fast case: bit sets. // Fast case: bit sets.
if (type1->IsBitset() && type2->IsBitset()) { if (type1->IsBitset() && type2->IsBitset()) {
...@@ -833,17 +875,14 @@ Type* Type::NormalizeUnion(Type* union_type, int size, Zone* zone) { ...@@ -833,17 +875,14 @@ Type* Type::NormalizeUnion(Type* union_type, int size, Zone* zone) {
return union_type; return union_type;
} }
// -----------------------------------------------------------------------------
// Iteration.
int Type::NumConstants() { int Type::NumConstants() {
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
if (this->IsConstant()) { if (this->IsHeapConstant() || this->IsOtherNumberConstant()) {
return 1; return 1;
} else if (this->IsUnion()) { } else if (this->IsUnion()) {
int result = 0; int result = 0;
for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
if (this->AsUnion()->Get(i)->IsConstant()) ++result; if (this->AsUnion()->Get(i)->IsHeapConstant()) ++result;
} }
return result; return result;
} else { } else {
...@@ -905,8 +944,11 @@ void Type::PrintTo(std::ostream& os) { ...@@ -905,8 +944,11 @@ void Type::PrintTo(std::ostream& os) {
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
if (this->IsBitset()) { if (this->IsBitset()) {
BitsetType::Print(os, this->AsBitset()); BitsetType::Print(os, this->AsBitset());
} else if (this->IsConstant()) { } else if (this->IsHeapConstant()) {
os << "Constant(" << Brief(*this->AsConstant()->Value()) << ")"; os << "HeapConstant(" << Brief(*this->AsHeapConstant()->Value()) << ")";
} else if (this->IsOtherNumberConstant()) {
os << "OtherNumberConstant(" << this->AsOtherNumberConstant()->Value()
<< ")";
} else if (this->IsRange()) { } else if (this->IsRange()) {
std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed); std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed);
std::streamsize saved_precision = os.precision(0); std::streamsize saved_precision = os.precision(0);
......
...@@ -263,7 +263,7 @@ class TypeBase { ...@@ -263,7 +263,7 @@ class TypeBase {
protected: protected:
friend class Type; friend class Type;
enum Kind { kConstant, kTuple, kUnion, kRange }; enum Kind { kHeapConstant, kOtherNumberConstant, kTuple, kUnion, kRange };
Kind kind() const { return kind_; } Kind kind() const { return kind_; }
explicit TypeBase(Kind kind) : kind_(kind) {} explicit TypeBase(Kind kind) : kind_(kind) {}
...@@ -287,7 +287,38 @@ class TypeBase { ...@@ -287,7 +287,38 @@ class TypeBase {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Constant types. // Constant types.
class ConstantType : public TypeBase { class OtherNumberConstantType : public TypeBase {
public:
double Value() { return value_; }
static bool IsOtherNumberConstant(double value);
static bool IsOtherNumberConstant(Object* value);
private:
friend class Type;
friend class BitsetType;
static Type* New(double value, Zone* zone) {
return AsType(new (zone->New(sizeof(OtherNumberConstantType)))
OtherNumberConstantType(value)); // NOLINT
}
static OtherNumberConstantType* cast(Type* type) {
DCHECK(IsKind(type, kOtherNumberConstant));
return static_cast<OtherNumberConstantType*>(FromType(type));
}
explicit OtherNumberConstantType(double value)
: TypeBase(kOtherNumberConstant), value_(value) {
CHECK(IsOtherNumberConstant(value));
}
BitsetType::bitset Lub() { return BitsetType::kOtherNumber; }
double value_;
};
class HeapConstantType : public TypeBase {
public: public:
i::Handle<i::Object> Value() { return object_; } i::Handle<i::Object> Value() { return object_; }
...@@ -297,24 +328,22 @@ class ConstantType : public TypeBase { ...@@ -297,24 +328,22 @@ class ConstantType : public TypeBase {
static Type* New(i::Handle<i::Object> value, Zone* zone) { static Type* New(i::Handle<i::Object> value, Zone* zone) {
BitsetType::bitset bitset = BitsetType::Lub(*value); BitsetType::bitset bitset = BitsetType::Lub(*value);
return AsType(new (zone->New(sizeof(ConstantType))) return AsType(new (zone->New(sizeof(HeapConstantType)))
ConstantType(bitset, value)); HeapConstantType(bitset, value));
} }
static ConstantType* cast(Type* type) { static HeapConstantType* cast(Type* type) {
DCHECK(IsKind(type, kConstant)); DCHECK(IsKind(type, kHeapConstant));
return static_cast<ConstantType*>(FromType(type)); return static_cast<HeapConstantType*>(FromType(type));
} }
ConstantType(BitsetType::bitset bitset, i::Handle<i::Object> object) HeapConstantType(BitsetType::bitset bitset, i::Handle<i::Object> object);
: TypeBase(kConstant), bitset_(bitset), object_(object) {}
BitsetType::bitset Lub() { return bitset_; } BitsetType::bitset Lub() { return bitset_; }
BitsetType::bitset bitset_; BitsetType::bitset bitset_;
Handle<i::Object> object_; Handle<i::Object> object_;
}; };
// TODO(neis): Also cache value if numerical.
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Range types. // Range types.
...@@ -474,8 +503,11 @@ class Type { ...@@ -474,8 +503,11 @@ class Type {
return BitsetType::New(BitsetType::UnsignedSmall()); return BitsetType::New(BitsetType::UnsignedSmall());
} }
static Type* Constant(i::Handle<i::Object> value, Zone* zone) { static Type* OtherNumberConstant(double value, Zone* zone) {
return ConstantType::New(value, zone); return OtherNumberConstantType::New(value, zone);
}
static Type* HeapConstant(i::Handle<i::Object> value, Zone* zone) {
return HeapConstantType::New(value, zone);
} }
static Type* Range(double min, double max, Zone* zone) { static Type* Range(double min, double max, Zone* zone) {
return RangeType::New(min, max, zone); return RangeType::New(min, max, zone);
...@@ -488,6 +520,10 @@ class Type { ...@@ -488,6 +520,10 @@ class Type {
return tuple; return tuple;
} }
// NewConstant is a factory that returns Constant, Range or Number.
static Type* NewConstant(i::Handle<i::Object> value, Zone* zone);
static Type* NewConstant(double value, Zone* zone);
static Type* Union(Type* type1, Type* type2, Zone* zone); static Type* Union(Type* type1, Type* type2, Zone* zone);
static Type* Intersect(Type* type1, Type* type2, Zone* zone); static Type* Intersect(Type* type1, Type* type2, Zone* zone);
...@@ -515,10 +551,16 @@ class Type { ...@@ -515,10 +551,16 @@ class Type {
// Inspection. // Inspection.
bool IsRange() { return IsKind(TypeBase::kRange); } bool IsRange() { return IsKind(TypeBase::kRange); }
bool IsConstant() { return IsKind(TypeBase::kConstant); } bool IsHeapConstant() { return IsKind(TypeBase::kHeapConstant); }
bool IsOtherNumberConstant() {
return IsKind(TypeBase::kOtherNumberConstant);
}
bool IsTuple() { return IsKind(TypeBase::kTuple); } bool IsTuple() { return IsKind(TypeBase::kTuple); }
ConstantType* AsConstant() { return ConstantType::cast(this); } HeapConstantType* AsHeapConstant() { return HeapConstantType::cast(this); }
OtherNumberConstantType* AsOtherNumberConstant() {
return OtherNumberConstantType::cast(this);
}
RangeType* AsRange() { return RangeType::cast(this); } RangeType* AsRange() { return RangeType::cast(this); }
TupleType* AsTuple() { return TupleType::cast(this); } TupleType* AsTuple() { return TupleType::cast(this); }
...@@ -582,7 +624,6 @@ class Type { ...@@ -582,7 +624,6 @@ class Type {
static bool Overlap(RangeType* lhs, RangeType* rhs); static bool Overlap(RangeType* lhs, RangeType* rhs);
static bool Contains(RangeType* lhs, RangeType* rhs); static bool Contains(RangeType* lhs, RangeType* rhs);
static bool Contains(RangeType* range, ConstantType* constant);
static bool Contains(RangeType* range, i::Object* val); static bool Contains(RangeType* range, i::Object* val);
static int UpdateRange(Type* type, UnionType* result, int size, Zone* zone); static int UpdateRange(Type* type, UnionType* result, int size, Zone* zone);
......
This diff is collapsed.
...@@ -54,27 +54,37 @@ class Types { ...@@ -54,27 +54,37 @@ class Types {
JS_OBJECT_TYPE, JSObject::kHeaderSize); JS_OBJECT_TYPE, JSObject::kHeaderSize);
smi = handle(Smi::FromInt(666), isolate); smi = handle(Smi::FromInt(666), isolate);
boxed_smi = isolate->factory()->NewHeapNumber(666);
signed32 = isolate->factory()->NewHeapNumber(0x40000000); signed32 = isolate->factory()->NewHeapNumber(0x40000000);
float1 = isolate->factory()->NewHeapNumber(1.53);
float2 = isolate->factory()->NewHeapNumber(0.53);
// float3 is identical to float1 in order to test that OtherNumberConstant
// types are equal by double value and not by handle pointer value.
float3 = isolate->factory()->NewHeapNumber(1.53);
object1 = isolate->factory()->NewJSObjectFromMap(object_map); object1 = isolate->factory()->NewJSObjectFromMap(object_map);
object2 = isolate->factory()->NewJSObjectFromMap(object_map); object2 = isolate->factory()->NewJSObjectFromMap(object_map);
array = isolate->factory()->NewJSArray(20); array = isolate->factory()->NewJSArray(20);
uninitialized = isolate->factory()->uninitialized_value(); uninitialized = isolate->factory()->uninitialized_value();
SmiConstant = Type::Constant(smi, zone); SmiConstant = Type::NewConstant(smi, zone);
Signed32Constant = Type::Constant(signed32, zone); Signed32Constant = Type::NewConstant(signed32, zone);
ObjectConstant1 = Type::Constant(object1, zone); ObjectConstant1 = Type::HeapConstant(object1, zone);
ObjectConstant2 = Type::Constant(object2, zone); ObjectConstant2 = Type::HeapConstant(object2, zone);
ArrayConstant = Type::Constant(array, zone); ArrayConstant = Type::HeapConstant(array, zone);
UninitializedConstant = Type::Constant(uninitialized, zone); UninitializedConstant = Type::HeapConstant(uninitialized, zone);
values.push_back(smi); values.push_back(smi);
values.push_back(boxed_smi);
values.push_back(signed32); values.push_back(signed32);
values.push_back(object1); values.push_back(object1);
values.push_back(object2); values.push_back(object2);
values.push_back(array); values.push_back(array);
values.push_back(uninitialized); values.push_back(uninitialized);
values.push_back(float1);
values.push_back(float2);
values.push_back(float3);
for (ValueVector::iterator it = values.begin(); it != values.end(); ++it) { for (ValueVector::iterator it = values.begin(); it != values.end(); ++it) {
types.push_back(Type::Constant(*it, zone)); types.push_back(Type::NewConstant(*it, zone));
} }
integers.push_back(isolate->factory()->NewNumber(-V8_INFINITY)); integers.push_back(isolate->factory()->NewNumber(-V8_INFINITY));
...@@ -98,7 +108,11 @@ class Types { ...@@ -98,7 +108,11 @@ class Types {
Handle<i::Map> object_map; Handle<i::Map> object_map;
Handle<i::Smi> smi; Handle<i::Smi> smi;
Handle<i::HeapNumber> boxed_smi;
Handle<i::HeapNumber> signed32; Handle<i::HeapNumber> signed32;
Handle<i::HeapNumber> float1;
Handle<i::HeapNumber> float2;
Handle<i::HeapNumber> float3;
Handle<i::JSObject> object1; Handle<i::JSObject> object1;
Handle<i::JSObject> object2; Handle<i::JSObject> object2;
Handle<i::JSArray> array; Handle<i::JSArray> array;
...@@ -129,8 +143,12 @@ class Types { ...@@ -129,8 +143,12 @@ class Types {
Type* Of(Handle<i::Object> value) { return Type::Of(value, zone_); } Type* Of(Handle<i::Object> value) { return Type::Of(value, zone_); }
Type* Constant(Handle<i::Object> value) { Type* NewConstant(Handle<i::Object> value) {
return Type::Constant(value, zone_); return Type::NewConstant(value, zone_);
}
Type* HeapConstant(Handle<i::Object> value) {
return Type::HeapConstant(value, zone_);
} }
Type* Range(double min, double max) { return Type::Range(min, max, zone_); } Type* Range(double min, double max) { return Type::Range(min, max, zone_); }
...@@ -170,7 +188,7 @@ class Types { ...@@ -170,7 +188,7 @@ class Types {
} }
case 1: { // constant case 1: { // constant
int i = rng_->NextInt(static_cast<int>(values.size())); int i = rng_->NextInt(static_cast<int>(values.size()));
return Type::Constant(values[i], zone_); return Type::NewConstant(values[i], zone_);
} }
case 2: { // range case 2: { // range
int i = rng_->NextInt(static_cast<int>(integers.size())); int i = rng_->NextInt(static_cast<int>(integers.size()));
......
...@@ -54,7 +54,7 @@ Node* GraphTest::NumberConstant(volatile double value) { ...@@ -54,7 +54,7 @@ Node* GraphTest::NumberConstant(volatile double value) {
Node* GraphTest::HeapConstant(const Handle<HeapObject>& value) { Node* GraphTest::HeapConstant(const Handle<HeapObject>& value) {
Node* node = graph()->NewNode(common()->HeapConstant(value)); Node* node = graph()->NewNode(common()->HeapConstant(value));
Type* type = Type::Constant(value, zone()); Type* type = Type::HeapConstant(value, zone());
NodeProperties::SetType(node, type); NodeProperties::SetType(node, type);
return node; return node;
} }
......
...@@ -65,7 +65,7 @@ class JSCreateLoweringTest : public TypedGraphTest { ...@@ -65,7 +65,7 @@ class JSCreateLoweringTest : public TypedGraphTest {
TEST_F(JSCreateLoweringTest, JSCreate) { TEST_F(JSCreateLoweringTest, JSCreate) {
Handle<JSFunction> function = isolate()->object_function(); Handle<JSFunction> function = isolate()->object_function();
Node* const target = Parameter(Type::Constant(function, graph()->zone())); Node* const target = Parameter(Type::HeapConstant(function, graph()->zone()));
Node* const context = Parameter(Type::Any()); Node* const context = Parameter(Type::Any());
Node* const effect = graph()->start(); Node* const effect = graph()->start();
Reduction r = Reduce(graph()->NewNode(javascript()->Create(), target, target, Reduction r = Reduce(graph()->NewNode(javascript()->Create(), target, target,
......
...@@ -88,7 +88,7 @@ class TypedOptimizationTest : public TypedGraphTest { ...@@ -88,7 +88,7 @@ class TypedOptimizationTest : public TypedGraphTest {
TEST_F(TypedOptimizationTest, ParameterWithMinusZero) { TEST_F(TypedOptimizationTest, ParameterWithMinusZero) {
{ {
Reduction r = Reduce( Reduction r = Reduce(
Parameter(Type::Constant(factory()->minus_zero_value(), zone()))); Parameter(Type::NewConstant(factory()->minus_zero_value(), zone())));
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsNumberConstant(-0.0)); EXPECT_THAT(r.replacement(), IsNumberConstant(-0.0));
} }
...@@ -98,9 +98,9 @@ TEST_F(TypedOptimizationTest, ParameterWithMinusZero) { ...@@ -98,9 +98,9 @@ TEST_F(TypedOptimizationTest, ParameterWithMinusZero) {
EXPECT_THAT(r.replacement(), IsNumberConstant(-0.0)); EXPECT_THAT(r.replacement(), IsNumberConstant(-0.0));
} }
{ {
Reduction r = Reduce(Parameter( Reduction r = Reduce(Parameter(Type::Union(
Type::Union(Type::MinusZero(), Type::MinusZero(), Type::NewConstant(factory()->NewNumber(0), zone()),
Type::Constant(factory()->NewNumber(0), zone()), zone()))); zone())));
EXPECT_FALSE(r.Changed()); EXPECT_FALSE(r.Changed());
} }
} }
...@@ -108,7 +108,7 @@ TEST_F(TypedOptimizationTest, ParameterWithMinusZero) { ...@@ -108,7 +108,7 @@ TEST_F(TypedOptimizationTest, ParameterWithMinusZero) {
TEST_F(TypedOptimizationTest, ParameterWithNull) { TEST_F(TypedOptimizationTest, ParameterWithNull) {
Handle<HeapObject> null = factory()->null_value(); Handle<HeapObject> null = factory()->null_value();
{ {
Reduction r = Reduce(Parameter(Type::Constant(null, zone()))); Reduction r = Reduce(Parameter(Type::NewConstant(null, zone())));
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsHeapConstant(null)); EXPECT_THAT(r.replacement(), IsHeapConstant(null));
} }
...@@ -125,13 +125,13 @@ TEST_F(TypedOptimizationTest, ParameterWithNaN) { ...@@ -125,13 +125,13 @@ TEST_F(TypedOptimizationTest, ParameterWithNaN) {
std::numeric_limits<double>::signaling_NaN()}; std::numeric_limits<double>::signaling_NaN()};
TRACED_FOREACH(double, nan, kNaNs) { TRACED_FOREACH(double, nan, kNaNs) {
Handle<Object> constant = factory()->NewNumber(nan); Handle<Object> constant = factory()->NewNumber(nan);
Reduction r = Reduce(Parameter(Type::Constant(constant, zone()))); Reduction r = Reduce(Parameter(Type::NewConstant(constant, zone())));
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsNumberConstant(IsNaN())); EXPECT_THAT(r.replacement(), IsNumberConstant(IsNaN()));
} }
{ {
Reduction r = Reduction r =
Reduce(Parameter(Type::Constant(factory()->nan_value(), zone()))); Reduce(Parameter(Type::NewConstant(factory()->nan_value(), zone())));
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsNumberConstant(IsNaN())); EXPECT_THAT(r.replacement(), IsNumberConstant(IsNaN()));
} }
...@@ -145,7 +145,7 @@ TEST_F(TypedOptimizationTest, ParameterWithNaN) { ...@@ -145,7 +145,7 @@ TEST_F(TypedOptimizationTest, ParameterWithNaN) {
TEST_F(TypedOptimizationTest, ParameterWithPlainNumber) { TEST_F(TypedOptimizationTest, ParameterWithPlainNumber) {
TRACED_FOREACH(double, value, kFloat64Values) { TRACED_FOREACH(double, value, kFloat64Values) {
Handle<Object> constant = factory()->NewNumber(value); Handle<Object> constant = factory()->NewNumber(value);
Reduction r = Reduce(Parameter(Type::Constant(constant, zone()))); Reduction r = Reduce(Parameter(Type::NewConstant(constant, zone())));
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsNumberConstant(value)); EXPECT_THAT(r.replacement(), IsNumberConstant(value));
} }
...@@ -164,7 +164,7 @@ TEST_F(TypedOptimizationTest, ParameterWithUndefined) { ...@@ -164,7 +164,7 @@ TEST_F(TypedOptimizationTest, ParameterWithUndefined) {
EXPECT_THAT(r.replacement(), IsHeapConstant(undefined)); EXPECT_THAT(r.replacement(), IsHeapConstant(undefined));
} }
{ {
Reduction r = Reduce(Parameter(Type::Constant(undefined, zone()))); Reduction r = Reduce(Parameter(Type::NewConstant(undefined, zone())));
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsHeapConstant(undefined)); EXPECT_THAT(r.replacement(), IsHeapConstant(undefined));
} }
...@@ -182,9 +182,9 @@ TEST_F(TypedOptimizationTest, JSToBooleanWithFalsish) { ...@@ -182,9 +182,9 @@ TEST_F(TypedOptimizationTest, JSToBooleanWithFalsish) {
Type::Undefined(), Type::Undefined(),
Type::Union( Type::Union(
Type::Undetectable(), Type::Undetectable(),
Type::Union( Type::Union(Type::NewConstant(
Type::Constant(factory()->false_value(), zone()), factory()->false_value(), zone()),
Type::Range(0.0, 0.0, zone()), zone()), Type::Range(0.0, 0.0, zone()), zone()),
zone()), zone()),
zone()), zone()),
zone()), zone()),
...@@ -201,7 +201,7 @@ TEST_F(TypedOptimizationTest, JSToBooleanWithFalsish) { ...@@ -201,7 +201,7 @@ TEST_F(TypedOptimizationTest, JSToBooleanWithFalsish) {
TEST_F(TypedOptimizationTest, JSToBooleanWithTruish) { TEST_F(TypedOptimizationTest, JSToBooleanWithTruish) {
Node* input = Parameter( Node* input = Parameter(
Type::Union( Type::Union(
Type::Constant(factory()->true_value(), zone()), Type::NewConstant(factory()->true_value(), zone()),
Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone()), Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone()),
zone()), zone()),
0); 0);
......
...@@ -135,7 +135,7 @@ class TyperTest : public TypedGraphTest { ...@@ -135,7 +135,7 @@ class TyperTest : public TypedGraphTest {
for (int x1 = lmin; x1 < lmin + width; x1++) { for (int x1 = lmin; x1 < lmin + width; x1++) {
for (int x2 = rmin; x2 < rmin + width; x2++) { for (int x2 = rmin; x2 < rmin + width; x2++) {
double result_value = opfun(x1, x2); double result_value = opfun(x1, x2);
Type* result_type = Type::Constant( Type* result_type = Type::NewConstant(
isolate()->factory()->NewNumber(result_value), zone()); isolate()->factory()->NewNumber(result_value), zone());
EXPECT_TRUE(result_type->Is(expected_type)); EXPECT_TRUE(result_type->Is(expected_type));
} }
...@@ -156,7 +156,7 @@ class TyperTest : public TypedGraphTest { ...@@ -156,7 +156,7 @@ class TyperTest : public TypedGraphTest {
double x1 = RandomInt(r1->AsRange()); double x1 = RandomInt(r1->AsRange());
double x2 = RandomInt(r2->AsRange()); double x2 = RandomInt(r2->AsRange());
double result_value = opfun(x1, x2); double result_value = opfun(x1, x2);
Type* result_type = Type::Constant( Type* result_type = Type::NewConstant(
isolate()->factory()->NewNumber(result_value), zone()); isolate()->factory()->NewNumber(result_value), zone());
EXPECT_TRUE(result_type->Is(expected_type)); EXPECT_TRUE(result_type->Is(expected_type));
} }
...@@ -173,10 +173,10 @@ class TyperTest : public TypedGraphTest { ...@@ -173,10 +173,10 @@ class TyperTest : public TypedGraphTest {
double x1 = RandomInt(r1->AsRange()); double x1 = RandomInt(r1->AsRange());
double x2 = RandomInt(r2->AsRange()); double x2 = RandomInt(r2->AsRange());
bool result_value = opfun(x1, x2); bool result_value = opfun(x1, x2);
Type* result_type = Type* result_type = Type::NewConstant(
Type::Constant(result_value ? isolate()->factory()->true_value() result_value ? isolate()->factory()->true_value()
: isolate()->factory()->false_value(), : isolate()->factory()->false_value(),
zone()); zone());
EXPECT_TRUE(result_type->Is(expected_type)); EXPECT_TRUE(result_type->Is(expected_type));
} }
} }
...@@ -192,7 +192,7 @@ class TyperTest : public TypedGraphTest { ...@@ -192,7 +192,7 @@ class TyperTest : public TypedGraphTest {
int32_t x1 = static_cast<int32_t>(RandomInt(r1->AsRange())); int32_t x1 = static_cast<int32_t>(RandomInt(r1->AsRange()));
int32_t x2 = static_cast<int32_t>(RandomInt(r2->AsRange())); int32_t x2 = static_cast<int32_t>(RandomInt(r2->AsRange()));
double result_value = opfun(x1, x2); double result_value = opfun(x1, x2);
Type* result_type = Type::Constant( Type* result_type = Type::NewConstant(
isolate()->factory()->NewNumber(result_value), zone()); isolate()->factory()->NewNumber(result_value), zone());
EXPECT_TRUE(result_type->Is(expected_type)); EXPECT_TRUE(result_type->Is(expected_type));
} }
......
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