Commit 5eeed463 authored by verwaest@chromium.org's avatar verwaest@chromium.org

Unify the Count Operation assignment with other assignments.

This does not enable inlining of setters (yet).

R=danno@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15578 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent b7a2c88f
...@@ -5044,7 +5044,8 @@ bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic( ...@@ -5044,7 +5044,8 @@ bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic(
int position, int position,
BailoutId assignment_id, BailoutId assignment_id,
HValue* object, HValue* object,
HValue* value, HValue* store_value,
HValue* result_value,
SmallMapList* types, SmallMapList* types,
Handle<String> name) { Handle<String> name) {
// Use monomorphic store if property lookup results in the same field index // Use monomorphic store if property lookup results in the same field index
...@@ -5090,12 +5091,14 @@ bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic( ...@@ -5090,12 +5091,14 @@ bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic(
HInstruction* store; HInstruction* store;
CHECK_ALIVE_OR_RETURN( CHECK_ALIVE_OR_RETURN(
store = BuildStoreNamedField( store = BuildStoreNamedField(
object, name, value, types->at(count - 1), &lookup), object, name, store_value, types->at(count - 1), &lookup),
true); true);
Push(value); if (result_value != NULL) Push(result_value);
Push(store_value);
store->set_position(position); store->set_position(position);
AddInstruction(store); AddInstruction(store);
AddSimulate(assignment_id); AddSimulate(assignment_id);
if (result_value != NULL) Drop(1);
ast_context()->ReturnValue(Pop()); ast_context()->ReturnValue(Pop());
return true; return true;
} }
...@@ -5106,11 +5109,13 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( ...@@ -5106,11 +5109,13 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
int position, int position,
BailoutId assignment_id, BailoutId assignment_id,
HValue* object, HValue* object,
HValue* value, HValue* store_value,
HValue* result_value,
SmallMapList* types, SmallMapList* types,
Handle<String> name) { Handle<String> name) {
if (TryStorePolymorphicAsMonomorphic( if (TryStorePolymorphicAsMonomorphic(
position, assignment_id, object, value, types, name)) { position, assignment_id, object,
store_value, result_value, types, name)) {
return; return;
} }
...@@ -5136,12 +5141,15 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( ...@@ -5136,12 +5141,15 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
set_current_block(if_true); set_current_block(if_true);
HInstruction* instr; HInstruction* instr;
CHECK_ALIVE( CHECK_ALIVE(instr = BuildStoreNamedField(
instr = BuildStoreNamedField(object, name, value, map, &lookup)); object, name, store_value, map, &lookup));
instr->set_position(position); instr->set_position(position);
// Goto will add the HSimulate for the store. // Goto will add the HSimulate for the store.
AddInstruction(instr); AddInstruction(instr);
if (!ast_context()->IsEffect()) Push(value); if (!ast_context()->IsEffect()) {
if (result_value != NULL) Push(result_value);
Push(store_value);
}
current_block()->Goto(join); current_block()->Goto(join);
set_current_block(if_false); set_current_block(if_false);
...@@ -5154,12 +5162,15 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( ...@@ -5154,12 +5162,15 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
if (count == types->length() && FLAG_deoptimize_uncommon_cases) { if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses);
} else { } else {
HInstruction* instr = BuildStoreNamedGeneric(object, name, value); HInstruction* instr = BuildStoreNamedGeneric(object, name, store_value);
instr->set_position(position); instr->set_position(position);
AddInstruction(instr); AddInstruction(instr);
if (join != NULL) { if (join != NULL) {
if (!ast_context()->IsEffect()) Push(value); if (!ast_context()->IsEffect()) {
if (result_value != NULL) Push(result_value);
Push(store_value);
}
current_block()->Goto(join); current_block()->Goto(join);
} else { } else {
// The HSimulate for the store should not see the stored value in // The HSimulate for the store should not see the stored value in
...@@ -5169,19 +5180,24 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( ...@@ -5169,19 +5180,24 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
if (ast_context()->IsEffect()) { if (ast_context()->IsEffect()) {
AddSimulate(id, REMOVABLE_SIMULATE); AddSimulate(id, REMOVABLE_SIMULATE);
} else { } else {
Push(value); if (result_value != NULL) Push(result_value);
Push(store_value);
AddSimulate(id, REMOVABLE_SIMULATE); AddSimulate(id, REMOVABLE_SIMULATE);
Drop(1); Drop(result_value != NULL ? 2 : 1);
} }
} }
return ast_context()->ReturnValue(value); return ast_context()->ReturnValue(
result_value != NULL ? result_value : store_value);
} }
} }
ASSERT(join != NULL); ASSERT(join != NULL);
join->SetJoinId(id); join->SetJoinId(id);
set_current_block(join); set_current_block(join);
if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); if (!ast_context()->IsEffect()) {
if (result_value != NULL) Drop(1);
ast_context()->ReturnValue(Pop());
}
} }
...@@ -5270,7 +5286,8 @@ void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr, ...@@ -5270,7 +5286,8 @@ void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr,
BailoutId assignment_id, BailoutId assignment_id,
Property* prop, Property* prop,
HValue* object, HValue* object,
HValue* value) { HValue* store_value,
HValue* result_value) {
Literal* key = prop->key()->AsLiteral(); Literal* key = prop->key()->AsLiteral();
Handle<String> name = Handle<String>::cast(key->value()); Handle<String> name = Handle<String>::cast(key->value());
ASSERT(!name.is_null()); ASSERT(!name.is_null());
...@@ -5288,37 +5305,42 @@ void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr, ...@@ -5288,37 +5305,42 @@ void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr,
Handle<JSObject> holder; Handle<JSObject> holder;
if (LookupSetter(map, name, &setter, &holder)) { if (LookupSetter(map, name, &setter, &holder)) {
AddCheckConstantFunction(holder, object, map); AddCheckConstantFunction(holder, object, map);
if (FLAG_inline_accessors && // Don't try to inline if the result_value is different from the
TryInlineSetter(setter, id, assignment_id, value)) { // store_value. That case isn't handled yet by the inlining.
if (result_value == NULL &&
FLAG_inline_accessors &&
TryInlineSetter(setter, id, assignment_id, store_value)) {
return; return;
} }
Drop(2); Drop(2);
Add<HPushArgument>(object); Add<HPushArgument>(object);
Add<HPushArgument>(value); Add<HPushArgument>(store_value);
instr = new(zone()) HCallConstantFunction(setter, 2); instr = new(zone()) HCallConstantFunction(setter, 2);
} else { } else {
Drop(2); Drop(2);
CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object,
name, name,
value, store_value,
map)); map));
} }
} else if (types != NULL && types->length() > 1) { } else if (types != NULL && types->length() > 1) {
Drop(2); Drop(2);
return HandlePolymorphicStoreNamedField( return HandlePolymorphicStoreNamedField(
id, position, assignment_id, object, value, types, name); id, position, assignment_id, object,
store_value, result_value, types, name);
} else { } else {
Drop(2); Drop(2);
instr = BuildStoreNamedGeneric(object, name, value); instr = BuildStoreNamedGeneric(object, name, store_value);
} }
Push(value); if (result_value != NULL) Push(result_value);
Push(store_value);
instr->set_position(position); instr->set_position(position);
AddInstruction(instr); AddInstruction(instr);
if (instr->HasObservableSideEffects()) { if (instr->HasObservableSideEffects()) {
AddSimulate(assignment_id, REMOVABLE_SIMULATE); AddSimulate(assignment_id, REMOVABLE_SIMULATE);
} }
if (result_value != NULL) Drop(1);
return ast_context()->ReturnValue(Pop()); return ast_context()->ReturnValue(Pop());
} }
...@@ -7883,35 +7905,11 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { ...@@ -7883,35 +7905,11 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) {
} }
after = BuildIncrement(returns_original_input, expr); after = BuildIncrement(returns_original_input, expr);
input = Pop();
HInstruction* store;
if (!monomorphic || map->is_observed()) {
// If we don't know the monomorphic type, do a generic store.
CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, after));
} else {
Handle<JSFunction> setter;
Handle<JSObject> holder;
if (LookupSetter(map, name, &setter, &holder)) {
store = BuildCallSetter(object, after, map, setter, holder);
} else {
CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object,
name,
after,
map));
}
}
AddInstruction(store);
// Overwrite the receiver in the bailout environment with the result HValue* result = returns_original_input ? Pop() : NULL;
// of the operation, and the placeholder with the original value if
// necessary.
environment()->SetExpressionStackAt(0, after);
if (returns_original_input) environment()->SetExpressionStackAt(1, input);
if (store->HasObservableSideEffects()) {
AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
}
return BuildStoreNamed(prop, expr->id(), expr->position(),
expr->AssignmentId(), prop, object, after, result);
} else { } else {
// Keyed property. // Keyed property.
if (returns_original_input) Push(graph()->GetConstantUndefined()); if (returns_original_input) Push(graph()->GetConstantUndefined());
......
...@@ -1744,12 +1744,14 @@ class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor { ...@@ -1744,12 +1744,14 @@ class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor {
BailoutId assignment_id, BailoutId assignment_id,
HValue* object, HValue* object,
HValue* value, HValue* value,
HValue* result,
SmallMapList* types, SmallMapList* types,
Handle<String> name); Handle<String> name);
bool TryStorePolymorphicAsMonomorphic(int position, bool TryStorePolymorphicAsMonomorphic(int position,
BailoutId assignment_id, BailoutId assignment_id,
HValue* object, HValue* object,
HValue* value, HValue* value,
HValue* result,
SmallMapList* types, SmallMapList* types,
Handle<String> name); Handle<String> name);
void HandlePolymorphicCallNamed(Call* expr, void HandlePolymorphicCallNamed(Call* expr,
...@@ -1829,7 +1831,8 @@ class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor { ...@@ -1829,7 +1831,8 @@ class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor {
BailoutId assignment_id, BailoutId assignment_id,
Property* prop, Property* prop,
HValue* object, HValue* object,
HValue* value); HValue* store_value,
HValue* result_value = NULL);
HInstruction* BuildStoreNamedField(HValue* object, HInstruction* BuildStoreNamedField(HValue* object,
Handle<String> name, Handle<String> name,
......
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