Reviewers: Jakob, rossberg,
Description:
Collect type information based on stack allocated values for OSR.
[email protected]
Please review this at https://codereview.chromium.org/100093004/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+85, -1 lines):
src/typing.h
src/typing.cc
Index: src/typing.cc
diff --git a/src/typing.cc b/src/typing.cc
index
8487c05eb4af9fe472509c5afc34ae0eb1916053..8fa258176b6498f7d572cf1698ced7ba9691f398
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"
@@ -41,8 +43,11 @@ AstTyper::AstTyper(CompilationInfo* info)
Handle<Context>(info->closure()->context()->native_context()),
info->isolate(),
info->zone()),
- store_(info->zone()) {
+ store_(info->zone()),
+ parameter_types_(NULL),
+ stack_local_types_(NULL) {
InitializeAstVisitor(info->isolate());
+ if (info_->is_osr()) ObserveTypesOnStack();
}
@@ -68,6 +73,78 @@ void AstTyper::Run(CompilationInfo* info) {
#undef RECURSE
+
+Handle<Type> AstTyper::ObserveType(Object* value) {
+ if (value->IsUndefined() || value->IsTheHole()) {
+ return Handle<Type>(Type::None(), isolate());
+ } else {
+ return Handle<Type>(Type::OfCurrently(Handle<Object>(value,
isolate())),
+ isolate());
+ }
+}
+
+
+void AstTyper::ObserveTypesOnStack() {
+ 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->num_stack_slots();
+
+ parameter_types_ = new(zone()) ZoneList<Handle<Type> >(params + 1,
zone());
+ stack_local_types_ = new(zone()) ZoneList<Handle<Type> >(locals, zone());
+
+ // The receiver ('this') is a parameter with index -1. We store it as
+ // element 0 and shift other params up by 1.
+ parameter_types_->Add(ObserveType(frame->receiver()), zone());
+ for (int i = 0; i < params; i++) {
+ parameter_types_->Add(ObserveType(frame->GetParameter(i)), zone());
+ }
+
+ // This includes the function var, if it is stored as a stack local.
+ for (int i = 0; i < locals; i++) {
+ stack_local_types_->Add(ObserveType(frame->GetExpression(i)), zone());
+ }
+}
+
+
+Handle<Type> AstTyper::GetObservedType(Variable* var) {
+ ASSERT(info_->is_osr());
+ ZoneList<Handle<Type> >* list;
+ int index = var->index();
+
+ if (var->IsParameter()) {
+ index += 1;
+ list = parameter_types_;
+ } else {
+ ASSERT(var->IsStackLocal());
+ list = stack_local_types_;
+ }
+
+ // We could also observe the type of context allocated values. We would
go
+ // up the function's scope chain until we find the variable's scope, go
up
+ // the context chain at the same time, and load the value from the
context
+ // slot stored as variable index. But this seems not to be worth the
effort.
+
+ ASSERT(0 <= index && index < list->length());
+ Handle<Type> result = list->at(index);
+
+ if (FLAG_trace_osr && FLAG_print_scopes) {
+ PrintF(" observed %s : ", var->IsParameter() ? "param" : "local");
+ var->name()->Print();
+ PrintF(" -> ");
+ result->TypePrint();
+ }
+
+ return result;
+}
+
+
#define RECURSE(call) \
do { \
ASSERT(!HasStackOverflow()); \
@@ -339,6 +416,7 @@ void AstTyper::VisitVariableProxy(VariableProxy* expr) {
Variable* var = expr->var();
if (var->IsStackAllocated()) {
NarrowType(expr, store_.LookupBounds(variable_index(var)));
+ if (info_->is_osr()) NarrowLowerType(expr, GetObservedType(var));
}
}
Index: src/typing.h
diff --git a/src/typing.h b/src/typing.h
index
6298e5a41b3d6824f45cc6879e408f48014ce9b0..117ec3d4554b3bc914f16cb536769e4be8a1496a
100644
--- a/src/typing.h
+++ b/src/typing.h
@@ -58,6 +58,10 @@ class AstTyper: public AstVisitor {
private:
explicit AstTyper(CompilationInfo* info);
+ Handle<Type> ObserveType(Object* value);
+ void ObserveTypesOnStack();
+ Handle<Type> GetObservedType(Variable* var);
+
static const int kNoVar = INT_MIN;
typedef v8::internal::Effects<int, kNoVar> Effects;
typedef v8::internal::NestedEffects<int, kNoVar> Store;
@@ -65,6 +69,8 @@ class AstTyper: public AstVisitor {
CompilationInfo* info_;
TypeFeedbackOracle oracle_;
Store store_;
+ ZoneList<Handle<Type> >* parameter_types_;
+ ZoneList<Handle<Type> >* stack_local_types_;
TypeFeedbackOracle* oracle() { return &oracle_; }
Zone* zone() const { return info_->zone(); }
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.