| Index: src/typing.cc
|
| diff --git a/src/typing.cc b/src/typing.cc
|
| index 9458d6dc2fe401142f7b4e3392cea419fe94500c..cec5f863de11be36cc5c523a728db3ff47fced4c 100644
|
| --- a/src/typing.cc
|
| +++ b/src/typing.cc
|
| @@ -27,6 +27,8 @@
|
|
|
| #include "typing.h"
|
|
|
| +#include "frames.h"
|
| +#include "frames-inl.h"
|
| #include "parser.h" // for CompileTimeValue; TODO(rossberg): should move
|
| #include "scopes.h"
|
|
|
| @@ -68,6 +70,75 @@ void AstTyper::Run(CompilationInfo* info) {
|
|
|
| #undef RECURSE
|
|
|
| +
|
| +Effect AstTyper::ObservedOnStack(Object* value) {
|
| + Type* lower = Type::OfCurrently(Handle<Object>(value, isolate()));
|
| + return Effect(Bounds(lower, Type::Any(), isolate()));
|
| +}
|
| +
|
| +
|
| +#ifdef OBJECT_PRINT
|
| + static void PrintObserved(Variable* var, Object* value, Handle<Type> type) {
|
| + PrintF(" observed %s ", var->IsParameter() ? "param" : "local");
|
| + var->name()->Print();
|
| + PrintF(" : ");
|
| + value->ShortPrint();
|
| + PrintF(" -> ");
|
| + type->TypePrint();
|
| + }
|
| +#endif // OBJECT_PRINT
|
| +
|
| +
|
| +void AstTyper::ObserveTypesAtOsrEntry(IterationStatement* stmt) {
|
| + if (stmt->OsrEntryId() != info_->osr_ast_id()) return;
|
| +
|
| + DisallowHeapAllocation no_gc;
|
| + JavaScriptFrameIterator it(isolate());
|
| + JavaScriptFrame* frame = it.frame();
|
| + Scope* scope = info_->scope();
|
| +
|
| + // Assert that the frame on the stack belongs to the function we want to OSR.
|
| + ASSERT_EQ(*info_->closure(), frame->function());
|
| +
|
| + int params = scope->num_parameters();
|
| + int locals = scope->StackLocalCount();
|
| +
|
| + // Use sequential composition to achieve desired narrowing.
|
| + // The receiver is a parameter with index -1.
|
| + store_.Seq(parameter_index(-1), ObservedOnStack(frame->receiver()));
|
| + for (int i = 0; i < params; i++) {
|
| + store_.Seq(parameter_index(i), ObservedOnStack(frame->GetParameter(i)));
|
| + }
|
| +
|
| + for (int i = 0; i < locals; i++) {
|
| + store_.Seq(stack_local_index(i), ObservedOnStack(frame->GetExpression(i)));
|
| + }
|
| +
|
| +#ifdef OBJECT_PRINT
|
| + if (FLAG_trace_osr && FLAG_print_scopes) {
|
| + PrintObserved(scope->receiver(),
|
| + frame->receiver(),
|
| + store_.LookupBounds(parameter_index(-1)).lower);
|
| +
|
| + for (int i = 0; i < params; i++) {
|
| + PrintObserved(scope->parameter(i),
|
| + frame->GetParameter(i),
|
| + store_.LookupBounds(parameter_index(i)).lower);
|
| + }
|
| +
|
| + ZoneList<Variable*> local_vars(locals, zone());
|
| + ZoneList<Variable*> context_vars(scope->ContextLocalCount(), zone());
|
| + scope->CollectStackAndContextLocals(&local_vars, &context_vars);
|
| + for (int i = 0; i < locals; i++) {
|
| + PrintObserved(local_vars.at(i),
|
| + frame->GetExpression(i),
|
| + store_.LookupBounds(stack_local_index(i)).lower);
|
| + }
|
| + }
|
| +#endif // OBJECT_PRINT
|
| +}
|
| +
|
| +
|
| #define RECURSE(call) \
|
| do { \
|
| ASSERT(!HasStackOverflow()); \
|
| @@ -221,6 +292,7 @@ void AstTyper::VisitDoWhileStatement(DoWhileStatement* stmt) {
|
| // computing the set of variables assigned in only some of the origins of the
|
| // control transfer (such as the loop body here).
|
| store_.Forget(); // Control may transfer here via looping or 'continue'.
|
| + ObserveTypesAtOsrEntry(stmt);
|
| RECURSE(Visit(stmt->body()));
|
| RECURSE(Visit(stmt->cond()));
|
| store_.Forget(); // Control may transfer here via 'break'.
|
| @@ -235,6 +307,7 @@ void AstTyper::VisitWhileStatement(WhileStatement* stmt) {
|
|
|
| store_.Forget(); // Control may transfer here via looping or 'continue'.
|
| RECURSE(Visit(stmt->cond()));
|
| + ObserveTypesAtOsrEntry(stmt);
|
| RECURSE(Visit(stmt->body()));
|
| store_.Forget(); // Control may transfer here via termination or 'break'.
|
| }
|
| @@ -251,6 +324,7 @@ void AstTyper::VisitForStatement(ForStatement* stmt) {
|
|
|
| RECURSE(Visit(stmt->cond()));
|
| }
|
| + ObserveTypesAtOsrEntry(stmt);
|
| RECURSE(Visit(stmt->body()));
|
| if (stmt->next() != NULL) {
|
| store_.Forget(); // Control may transfer here via 'continue'.
|
| @@ -267,6 +341,7 @@ void AstTyper::VisitForInStatement(ForInStatement* stmt) {
|
|
|
| RECURSE(Visit(stmt->enumerable()));
|
| store_.Forget(); // Control may transfer here via looping or 'continue'.
|
| + ObserveTypesAtOsrEntry(stmt);
|
| RECURSE(Visit(stmt->body()));
|
| store_.Forget(); // Control may transfer here via 'break'.
|
| }
|
|
|