Commit 18f6577b authored by verwaest@chromium.org's avatar verwaest@chromium.org

Properly filter types using the initial map from HAllocate.

R=mstarzinger@chromium.org

Review URL: https://chromiumcodereview.appspot.com/23615012

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16572 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 3a3a27b2
......@@ -646,8 +646,15 @@ void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle,
Literal* key = property->key()->AsLiteral();
ASSERT(key != NULL && key->value()->IsString());
Handle<String> name = Handle<String>::cast(key->value());
check_type_ = oracle->GetCallCheckType(this);
receiver_types_.Clear();
oracle->CallReceiverTypes(this, name, call_kind, &receiver_types_);
if (check_type_ == RECEIVER_MAP_CHECK) {
oracle->CallReceiverTypes(this, name, call_kind, &receiver_types_);
is_monomorphic_ = is_monomorphic_ && receiver_types_.length() > 0;
} else {
holder_ = GetPrototypeForPrimitiveCheck(check_type_, oracle->isolate());
receiver_types_.Add(handle(holder_->map()), oracle->zone());
}
#ifdef DEBUG
if (FLAG_enable_slow_asserts) {
int length = receiver_types_.length();
......@@ -657,17 +664,8 @@ void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle,
}
}
#endif
check_type_ = oracle->GetCallCheckType(this);
if (is_monomorphic_) {
Handle<Map> map;
if (receiver_types_.length() > 0) {
ASSERT(check_type_ == RECEIVER_MAP_CHECK);
map = receiver_types_.at(0);
} else {
ASSERT(check_type_ != RECEIVER_MAP_CHECK);
holder_ = GetPrototypeForPrimitiveCheck(check_type_, oracle->isolate());
map = Handle<Map>(holder_->map());
}
Handle<Map> map = receiver_types_.first();
is_monomorphic_ = ComputeTarget(map, name);
}
}
......
......@@ -288,6 +288,14 @@ class SmallMapList V8_FINAL {
Add(map, zone);
}
void FilterForPossibleTransitions(Map* root_map) {
for (int i = list_.length() - 1; i >= 0; i--) {
if (at(i)->FindRootMap() != root_map) {
list_.RemoveElement(list_.at(i));
}
}
}
void Add(Handle<Map> handle, Zone* zone) {
list_.Add(handle.location(), zone);
}
......@@ -366,12 +374,6 @@ class Expression : public AstNode {
UNREACHABLE();
return NULL;
}
Handle<Map> GetMonomorphicReceiverType() {
ASSERT(IsMonomorphic());
SmallMapList* types = GetReceiverTypes();
ASSERT(types != NULL && types->length() == 1);
return types->at(0);
}
virtual KeyedAccessStoreMode GetStoreMode() {
UNREACHABLE();
return STANDARD_STORE;
......
......@@ -4978,6 +4978,21 @@ void HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
}
static bool ComputeReceiverTypes(Expression* expr,
HValue* receiver,
SmallMapList** t) {
SmallMapList* types = expr->GetReceiverTypes();
*t = types;
bool monomorphic = expr->IsMonomorphic();
if (types != NULL && receiver->HasMonomorphicJSObjectType()) {
Map* root_map = receiver->GetMonomorphicJSObjectMap()->FindRootMap();
types->FilterForPossibleTransitions(root_map);
monomorphic = types->length() == 1;
}
return monomorphic && CanInlinePropertyAccess(*types->first());
}
void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr,
BailoutId id,
BailoutId assignment_id,
......@@ -4989,14 +5004,12 @@ void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr,
ASSERT(!name.is_null());
HInstruction* instr = NULL;
SmallMapList* types = expr->GetReceiverTypes();
bool monomorphic = expr->IsMonomorphic();
Handle<Map> map;
if (monomorphic) {
map = types->first();
monomorphic = CanInlinePropertyAccess(*map);
}
SmallMapList* types;
bool monomorphic = ComputeReceiverTypes(expr, object, &types);
if (monomorphic) {
Handle<Map> map = types->first();
Handle<JSFunction> setter;
Handle<JSObject> holder;
if (LookupSetter(map, name, &setter, &holder)) {
......@@ -5692,8 +5705,12 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess(
bool* has_side_effects) {
ASSERT(!expr->IsPropertyName());
HInstruction* instr = NULL;
if (expr->IsMonomorphic()) {
Handle<Map> map = expr->GetMonomorphicReceiverType();
SmallMapList* types;
bool monomorphic = ComputeReceiverTypes(expr, obj, &types);
if (monomorphic) {
Handle<Map> map = types->first();
if (map->has_slow_elements_kind()) {
instr = is_store ? BuildStoreKeyedGeneric(obj, key, val)
: BuildLoadKeyedGeneric(obj, key);
......@@ -5857,19 +5874,13 @@ void HOptimizedGraphBuilder::BuildLoad(Property* expr,
} else if (expr->key()->IsPropertyName()) {
Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
SmallMapList* types = expr->GetReceiverTypes();
HValue* object = Top();
Handle<Map> map;
bool monomorphic = false;
if (expr->IsMonomorphic()) {
map = types->first();
monomorphic = CanInlinePropertyAccess(*map);
} else if (object->HasMonomorphicJSObjectType()) {
map = object->GetMonomorphicJSObjectMap();
monomorphic = CanInlinePropertyAccess(*map);
}
SmallMapList* types;
bool monomorphic = ComputeReceiverTypes(expr, object, &types);
if (monomorphic) {
Handle<Map> map = types->first();
Handle<JSFunction> getter;
Handle<JSObject> holder;
if (LookupGetter(map, name, &getter, &holder)) {
......@@ -6962,23 +6973,19 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
CHECK_ALIVE(VisitExpressions(expr->arguments()));
Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
SmallMapList* types = expr->GetReceiverTypes();
HValue* receiver =
environment()->ExpressionStackAt(expr->arguments()->length());
bool monomorphic = expr->IsMonomorphic();
Handle<Map> receiver_map;
if (monomorphic) {
receiver_map = (types == NULL || types->is_empty())
? Handle<Map>::null()
: types->first();
SmallMapList* types;
bool was_monomorphic = expr->IsMonomorphic();
bool monomorphic = ComputeReceiverTypes(expr, receiver, &types);
if (!was_monomorphic && monomorphic) {
monomorphic = expr->ComputeTarget(types->first(), name);
}
HValue* receiver =
environment()->ExpressionStackAt(expr->arguments()->length());
if (monomorphic) {
if (TryInlineBuiltinMethodCall(expr,
receiver,
receiver_map,
expr->check_type())) {
Handle<Map> map = types->first();
if (TryInlineBuiltinMethodCall(expr, receiver, map, expr->check_type())) {
if (FLAG_trace_inlining) {
PrintF("Inlining builtin ");
expr->target()->ShortPrint();
......@@ -6996,7 +7003,7 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
call = PreProcessCall(
new(zone()) HCallNamed(context, name, argument_count));
} else {
AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
AddCheckConstantFunction(expr->holder(), receiver, map);
if (TryInlineCall(expr)) return;
call = PreProcessCall(
......
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