summaryrefslogtreecommitdiff
path: root/deps/v8/src/crankshaft/typing.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/crankshaft/typing.cc')
-rw-r--r--deps/v8/src/crankshaft/typing.cc167
1 files changed, 92 insertions, 75 deletions
diff --git a/deps/v8/src/crankshaft/typing.cc b/deps/v8/src/crankshaft/typing.cc
index 5961838711..d2b56e255b 100644
--- a/deps/v8/src/crankshaft/typing.cc
+++ b/deps/v8/src/crankshaft/typing.cc
@@ -4,11 +4,12 @@
#include "src/crankshaft/typing.h"
+#include "src/ast/compile-time-value.h"
#include "src/ast/scopes.h"
-#include "src/frames.h"
+#include "src/ast/variables.h"
#include "src/frames-inl.h"
+#include "src/frames.h"
#include "src/ostreams.h"
-#include "src/parsing/parser.h" // for CompileTimeValue; TODO(rossberg): move
#include "src/splay-tree-inl.h"
namespace v8 {
@@ -33,20 +34,20 @@ AstTyper::AstTyper(Isolate* isolate, Zone* zone, Handle<JSFunction> closure,
#ifdef OBJECT_PRINT
- static void PrintObserved(Variable* var, Object* value, Type* type) {
- OFStream os(stdout);
- os << " observed " << (var->IsParameter() ? "param" : "local") << " ";
- var->name()->Print(os);
- os << " : " << Brief(value) << " -> ";
- type->PrintTo(os);
- os << std::endl;
+static void PrintObserved(Variable* var, Object* value, AstType* type) {
+ OFStream os(stdout);
+ os << " observed " << (var->IsParameter() ? "param" : "local") << " ";
+ var->name()->Print(os);
+ os << " : " << Brief(value) << " -> ";
+ type->PrintTo(os);
+ os << std::endl;
}
#endif // OBJECT_PRINT
Effect AstTyper::ObservedOnStack(Object* value) {
- Type* lower = Type::NowOf(value, zone());
- return Effect(Bounds(lower, Type::Any()));
+ AstType* lower = AstType::NowOf(value, zone());
+ return Effect(AstBounds(lower, AstType::Any()));
}
@@ -84,15 +85,16 @@ void AstTyper::ObserveTypesAtOsrEntry(IterationStatement* stmt) {
store_.LookupBounds(parameter_index(i)).lower);
}
- ZoneList<Variable*> local_vars(locals, zone());
- ZoneList<Variable*> context_vars(scope_->ContextLocalCount(), zone());
- ZoneList<Variable*> global_vars(scope_->ContextGlobalCount(), zone());
- scope_->CollectStackAndContextLocals(&local_vars, &context_vars,
- &global_vars);
- for (int i = 0; i < locals; i++) {
- PrintObserved(local_vars.at(i),
- frame->GetExpression(i),
- store_.LookupBounds(stack_local_index(i)).lower);
+ ZoneList<Variable*>* local_vars = scope_->locals();
+ int local_index = 0;
+ for (int i = 0; i < local_vars->length(); i++) {
+ Variable* var = local_vars->at(i);
+ if (var->IsStackLocal()) {
+ PrintObserved(
+ var, frame->GetExpression(local_index),
+ store_.LookupBounds(stack_local_index(local_index)).lower);
+ local_index++;
+ }
}
}
#endif // OBJECT_PRINT
@@ -205,11 +207,12 @@ void AstTyper::VisitSwitchStatement(SwitchStatement* stmt) {
if (!clause->is_default()) {
Expression* label = clause->label();
// Collect type feedback.
- Type* tag_type;
- Type* label_type;
- Type* combined_type;
+ AstType* tag_type;
+ AstType* label_type;
+ AstType* combined_type;
oracle()->CompareType(clause->CompareId(),
- &tag_type, &label_type, &combined_type);
+ clause->CompareOperationFeedbackSlot(), &tag_type,
+ &label_type, &combined_type);
NarrowLowerType(stmt->tag(), tag_type);
NarrowLowerType(label, label_type);
clause->set_compare_type(combined_type);
@@ -366,8 +369,8 @@ void AstTyper::VisitConditional(Conditional* expr) {
store_.Seq(then_effects);
NarrowType(expr,
- Bounds::Either(bounds_->get(expr->then_expression()),
- bounds_->get(expr->else_expression()), zone()));
+ AstBounds::Either(bounds_->get(expr->then_expression()),
+ bounds_->get(expr->else_expression()), zone()));
}
@@ -380,14 +383,14 @@ void AstTyper::VisitVariableProxy(VariableProxy* expr) {
void AstTyper::VisitLiteral(Literal* expr) {
- Type* type = Type::Constant(expr->value(), zone());
- NarrowType(expr, Bounds(type));
+ AstType* type = AstType::Constant(expr->value(), zone());
+ NarrowType(expr, AstBounds(type));
}
void AstTyper::VisitRegExpLiteral(RegExpLiteral* expr) {
// TODO(rossberg): Reintroduce RegExp type.
- NarrowType(expr, Bounds(Type::Object()));
+ NarrowType(expr, AstBounds(AstType::Object()));
}
@@ -415,7 +418,7 @@ void AstTyper::VisitObjectLiteral(ObjectLiteral* expr) {
RECURSE(Visit(prop->value()));
}
- NarrowType(expr, Bounds(Type::Object()));
+ NarrowType(expr, AstBounds(AstType::Object()));
}
@@ -426,7 +429,7 @@ void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) {
RECURSE(Visit(value));
}
- NarrowType(expr, Bounds(Type::Object()));
+ NarrowType(expr, AstBounds(AstType::Object()));
}
@@ -479,7 +482,7 @@ void AstTyper::VisitThrow(Throw* expr) {
RECURSE(Visit(expr->exception()));
// TODO(rossberg): is it worth having a non-termination effect?
- NarrowType(expr, Bounds(Type::None()));
+ NarrowType(expr, AstBounds(AstType::None()));
}
@@ -562,7 +565,7 @@ void AstTyper::VisitCallNew(CallNew* expr) {
RECURSE(Visit(arg));
}
- NarrowType(expr, Bounds(Type::None(), Type::Receiver()));
+ NarrowType(expr, AstBounds(AstType::None(), AstType::Receiver()));
}
@@ -589,13 +592,13 @@ void AstTyper::VisitUnaryOperation(UnaryOperation* expr) {
switch (expr->op()) {
case Token::NOT:
case Token::DELETE:
- NarrowType(expr, Bounds(Type::Boolean()));
+ NarrowType(expr, AstBounds(AstType::Boolean()));
break;
case Token::VOID:
- NarrowType(expr, Bounds(Type::Undefined()));
+ NarrowType(expr, AstBounds(AstType::Undefined()));
break;
case Token::TYPEOF:
- NarrowType(expr, Bounds(Type::InternalizedString()));
+ NarrowType(expr, AstBounds(AstType::InternalizedString()));
break;
default:
UNREACHABLE();
@@ -612,12 +615,13 @@ void AstTyper::VisitCountOperation(CountOperation* expr) {
oracle()->CountReceiverTypes(slot, expr->GetReceiverTypes());
expr->set_store_mode(store_mode);
expr->set_key_type(key_type);
- expr->set_type(oracle()->CountType(expr->CountBinOpFeedbackId()));
+ expr->set_type(oracle()->CountType(expr->CountBinOpFeedbackId(),
+ expr->CountBinaryOpFeedbackSlot()));
// TODO(rossberg): merge the count type with the generic expression type.
RECURSE(Visit(expr->expression()));
- NarrowType(expr, Bounds(Type::SignedSmall(), Type::Number()));
+ NarrowType(expr, AstBounds(AstType::SignedSmall(), AstType::Number()));
VariableProxy* proxy = expr->expression()->AsVariableProxy();
if (proxy != NULL && proxy->var()->IsStackAllocated()) {
@@ -625,17 +629,18 @@ void AstTyper::VisitCountOperation(CountOperation* expr) {
}
}
-
void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
// Collect type feedback.
- Type* type;
- Type* left_type;
- Type* right_type;
+ AstType* type;
+ AstType* left_type;
+ AstType* right_type;
Maybe<int> fixed_right_arg = Nothing<int>();
Handle<AllocationSite> allocation_site;
oracle()->BinaryType(expr->BinaryOperationFeedbackId(),
- &left_type, &right_type, &type, &fixed_right_arg,
- &allocation_site, expr->op());
+ expr->BinaryOperationFeedbackSlot(), &left_type,
+ &right_type, &type, &fixed_right_arg, &allocation_site,
+ expr->op());
+
NarrowLowerType(expr, type);
NarrowLowerType(expr->left(), left_type);
NarrowLowerType(expr->right(), right_type);
@@ -662,19 +667,21 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
left_effects.Alt(right_effects);
store_.Seq(left_effects);
- NarrowType(expr, Bounds::Either(bounds_->get(expr->left()),
- bounds_->get(expr->right()), zone()));
+ NarrowType(expr, AstBounds::Either(bounds_->get(expr->left()),
+ bounds_->get(expr->right()), zone()));
break;
}
case Token::BIT_OR:
case Token::BIT_AND: {
RECURSE(Visit(expr->left()));
RECURSE(Visit(expr->right()));
- Type* upper = Type::Union(bounds_->get(expr->left()).upper,
- bounds_->get(expr->right()).upper, zone());
- if (!upper->Is(Type::Signed32())) upper = Type::Signed32();
- Type* lower = Type::Intersect(Type::SignedSmall(), upper, zone());
- NarrowType(expr, Bounds(lower, upper));
+ AstType* upper =
+ AstType::Union(bounds_->get(expr->left()).upper,
+ bounds_->get(expr->right()).upper, zone());
+ if (!upper->Is(AstType::Signed32())) upper = AstType::Signed32();
+ AstType* lower =
+ AstType::Intersect(AstType::SignedSmall(), upper, zone());
+ NarrowType(expr, AstBounds(lower, upper));
break;
}
case Token::BIT_XOR:
@@ -682,7 +689,7 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
case Token::SAR:
RECURSE(Visit(expr->left()));
RECURSE(Visit(expr->right()));
- NarrowType(expr, Bounds(Type::SignedSmall(), Type::Signed32()));
+ NarrowType(expr, AstBounds(AstType::SignedSmall(), AstType::Signed32()));
break;
case Token::SHR:
RECURSE(Visit(expr->left()));
@@ -690,28 +697,29 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
// TODO(rossberg): The upper bound would be Unsigned32, but since there
// is no 'positive Smi' type for the lower bound, we use the smallest
// union of Smi and Unsigned32 as upper bound instead.
- NarrowType(expr, Bounds(Type::SignedSmall(), Type::Number()));
+ NarrowType(expr, AstBounds(AstType::SignedSmall(), AstType::Number()));
break;
case Token::ADD: {
RECURSE(Visit(expr->left()));
RECURSE(Visit(expr->right()));
- Bounds l = bounds_->get(expr->left());
- Bounds r = bounds_->get(expr->right());
- Type* lower =
+ AstBounds l = bounds_->get(expr->left());
+ AstBounds r = bounds_->get(expr->right());
+ AstType* lower =
!l.lower->IsInhabited() || !r.lower->IsInhabited()
- ? Type::None()
- : l.lower->Is(Type::String()) || r.lower->Is(Type::String())
- ? Type::String()
- : l.lower->Is(Type::Number()) && r.lower->Is(Type::Number())
- ? Type::SignedSmall()
- : Type::None();
- Type* upper =
- l.upper->Is(Type::String()) || r.upper->Is(Type::String())
- ? Type::String()
- : l.upper->Is(Type::Number()) && r.upper->Is(Type::Number())
- ? Type::Number()
- : Type::NumberOrString();
- NarrowType(expr, Bounds(lower, upper));
+ ? AstType::None()
+ : l.lower->Is(AstType::String()) || r.lower->Is(AstType::String())
+ ? AstType::String()
+ : l.lower->Is(AstType::Number()) &&
+ r.lower->Is(AstType::Number())
+ ? AstType::SignedSmall()
+ : AstType::None();
+ AstType* upper =
+ l.upper->Is(AstType::String()) || r.upper->Is(AstType::String())
+ ? AstType::String()
+ : l.upper->Is(AstType::Number()) && r.upper->Is(AstType::Number())
+ ? AstType::Number()
+ : AstType::NumberOrString();
+ NarrowType(expr, AstBounds(lower, upper));
break;
}
case Token::SUB:
@@ -720,7 +728,7 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
case Token::MOD:
RECURSE(Visit(expr->left()));
RECURSE(Visit(expr->right()));
- NarrowType(expr, Bounds(Type::SignedSmall(), Type::Number()));
+ NarrowType(expr, AstBounds(AstType::SignedSmall(), AstType::Number()));
break;
default:
UNREACHABLE();
@@ -730,11 +738,12 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
void AstTyper::VisitCompareOperation(CompareOperation* expr) {
// Collect type feedback.
- Type* left_type;
- Type* right_type;
- Type* combined_type;
+ AstType* left_type;
+ AstType* right_type;
+ AstType* combined_type;
oracle()->CompareType(expr->CompareOperationFeedbackId(),
- &left_type, &right_type, &combined_type);
+ expr->CompareOperationFeedbackSlot(), &left_type,
+ &right_type, &combined_type);
NarrowLowerType(expr->left(), left_type);
NarrowLowerType(expr->right(), right_type);
expr->set_combined_type(combined_type);
@@ -742,7 +751,7 @@ void AstTyper::VisitCompareOperation(CompareOperation* expr) {
RECURSE(Visit(expr->left()));
RECURSE(Visit(expr->right()));
- NarrowType(expr, Bounds(Type::Boolean()));
+ NarrowType(expr, AstBounds(AstType::Boolean()));
}
@@ -767,6 +776,14 @@ void AstTyper::VisitRewritableExpression(RewritableExpression* expr) {
Visit(expr->expression());
}
+int AstTyper::variable_index(Variable* var) {
+ // Stack locals have the range [0 .. l]
+ // Parameters have the range [-1 .. p]
+ // We map this to [-p-2 .. -1, 0 .. l]
+ return var->IsStackLocal()
+ ? stack_local_index(var->index())
+ : var->IsParameter() ? parameter_index(var->index()) : kNoVar;
+}
void AstTyper::VisitDeclarations(ZoneList<Declaration*>* decls) {
for (int i = 0; i < decls->length(); ++i) {