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