From: yangguo@chromium.org Date: Wed, 18 Dec 2013 10:38:58 +0000 (+0000) Subject: Collect type information based on stack allocated values for OSR. X-Git-Tag: upstream/4.7.83~11357 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=37d5abc93962b95564427c33fce42f62e42863dc;p=platform%2Fupstream%2Fv8.git Collect type information based on stack allocated values for OSR. R=jkummerow@chromium.org, rossberg@chromium.org Review URL: https://codereview.chromium.org/100093004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18343 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/typing.cc b/src/typing.cc index 9458d6dc2..cec5f863d 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(value, isolate())); + return Effect(Bounds(lower, Type::Any(), isolate())); +} + + +#ifdef OBJECT_PRINT + static void PrintObserved(Variable* var, Object* value, Handle 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 local_vars(locals, zone()); + ZoneList 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'. } diff --git a/src/typing.h b/src/typing.h index a111ae5fd..ec9132f16 100644 --- a/src/typing.h +++ b/src/typing.h @@ -58,6 +58,9 @@ class AstTyper: public AstVisitor { private: explicit AstTyper(CompilationInfo* info); + Effect ObservedOnStack(Object* value); + void ObserveTypesAtOsrEntry(IterationStatement* stmt); + static const int kNoVar = INT_MIN; typedef v8::internal::Effects Effects; typedef v8::internal::NestedEffects Store; @@ -82,12 +85,15 @@ class AstTyper: public AstVisitor { } void ExitEffects() { store_ = store_.Pop(); } + int parameter_index(int index) { return -index - 2; } + int stack_local_index(int index) { return index; } + int 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() ? var->index() : - var->IsParameter() ? -var->index() - 2 : kNoVar; + return var->IsStackLocal() ? stack_local_index(var->index()) : + var->IsParameter() ? parameter_index(var->index()) : kNoVar; } void VisitDeclarations(ZoneList* declarations); diff --git a/src/utils.h b/src/utils.h index 3a0936eaa..14a4c5681 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1118,6 +1118,7 @@ class BailoutId { bool IsNone() const { return id_ == kNoneId; } bool operator==(const BailoutId& other) const { return id_ == other.id_; } + bool operator!=(const BailoutId& other) const { return id_ != other.id_; } private: static const int kNoneId = -1;