Commit e829fb4f authored by verwaest@chromium.org's avatar verwaest@chromium.org

Merge assignment handling for Assignment and CompoundAssignment

R=danno@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15226 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent b9e5c586
...@@ -6361,7 +6361,8 @@ void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( ...@@ -6361,7 +6361,8 @@ void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(
bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic( bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic(
Assignment* expr, int position,
BailoutId assignment_id,
HValue* object, HValue* object,
HValue* value, HValue* value,
SmallMapList* types, SmallMapList* types,
...@@ -6412,21 +6413,24 @@ bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic( ...@@ -6412,21 +6413,24 @@ bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic(
object, name, value, types->at(count - 1), &lookup), object, name, value, types->at(count - 1), &lookup),
true); true);
Push(value); Push(value);
store->set_position(expr->position()); store->set_position(position);
AddInstruction(store); AddInstruction(store);
AddSimulate(expr->AssignmentId()); AddSimulate(assignment_id);
ast_context()->ReturnValue(Pop()); ast_context()->ReturnValue(Pop());
return true; return true;
} }
void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
Assignment* expr, BailoutId id,
int position,
BailoutId assignment_id,
HValue* object, HValue* object,
HValue* value, HValue* value,
SmallMapList* types, SmallMapList* types,
Handle<String> name) { Handle<String> name) {
if (TryStorePolymorphicAsMonomorphic(expr, object, value, types, name)) { if (TryStorePolymorphicAsMonomorphic(
position, assignment_id, object, value, types, name)) {
return; return;
} }
...@@ -6454,7 +6458,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( ...@@ -6454,7 +6458,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
HInstruction* instr; HInstruction* instr;
CHECK_ALIVE( CHECK_ALIVE(
instr = BuildStoreNamedField(object, name, value, map, &lookup)); instr = BuildStoreNamedField(object, name, value, map, &lookup));
instr->set_position(expr->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()) Push(value);
...@@ -6471,7 +6475,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( ...@@ -6471,7 +6475,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses);
} else { } else {
HInstruction* instr = BuildStoreNamedGeneric(object, name, value); HInstruction* instr = BuildStoreNamedGeneric(object, name, value);
instr->set_position(expr->position()); instr->set_position(position);
AddInstruction(instr); AddInstruction(instr);
if (join != NULL) { if (join != NULL) {
...@@ -6483,10 +6487,10 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( ...@@ -6483,10 +6487,10 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
// unoptimized code). // unoptimized code).
if (instr->HasObservableSideEffects()) { if (instr->HasObservableSideEffects()) {
if (ast_context()->IsEffect()) { if (ast_context()->IsEffect()) {
AddSimulate(expr->id(), REMOVABLE_SIMULATE); AddSimulate(id, REMOVABLE_SIMULATE);
} else { } else {
Push(value); Push(value);
AddSimulate(expr->id(), REMOVABLE_SIMULATE); AddSimulate(id, REMOVABLE_SIMULATE);
Drop(1); Drop(1);
} }
} }
...@@ -6495,7 +6499,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( ...@@ -6495,7 +6499,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
} }
ASSERT(join != NULL); ASSERT(join != NULL);
join->SetJoinId(expr->id()); join->SetJoinId(id);
set_current_block(join); set_current_block(join);
if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
} }
...@@ -6512,54 +6516,8 @@ void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { ...@@ -6512,54 +6516,8 @@ void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
HValue* value = environment()->ExpressionStackAt(0); HValue* value = environment()->ExpressionStackAt(0);
HValue* object = environment()->ExpressionStackAt(1); HValue* object = environment()->ExpressionStackAt(1);
Literal* key = prop->key()->AsLiteral(); return BuildStoreNamed(expr, expr->id(), expr->position(),
Handle<String> name = Handle<String>::cast(key->handle()); expr->AssignmentId(), prop, object, value);
ASSERT(!name.is_null());
HInstruction* instr = NULL;
SmallMapList* types = expr->GetReceiverTypes();
bool monomorphic = expr->IsMonomorphic();
Handle<Map> map;
if (monomorphic) {
map = types->first();
if (map->is_dictionary_map()) monomorphic = false;
}
if (monomorphic) {
Handle<JSFunction> setter;
Handle<JSObject> holder;
if (LookupSetter(map, name, &setter, &holder)) {
AddCheckConstantFunction(holder, object, map);
if (FLAG_inline_accessors && TryInlineSetter(setter, expr, value)) {
return;
}
Drop(2);
AddInstruction(new(zone()) HPushArgument(object));
AddInstruction(new(zone()) HPushArgument(value));
instr = new(zone()) HCallConstantFunction(setter, 2);
} else {
Drop(2);
CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object,
name,
value,
map));
}
} else if (types != NULL && types->length() > 1) {
Drop(2);
return HandlePolymorphicStoreNamedField(expr, object, value, types, name);
} else {
Drop(2);
instr = BuildStoreNamedGeneric(object, name, value);
}
Push(value);
instr->set_position(expr->position());
AddInstruction(instr);
if (instr->HasObservableSideEffects()) {
AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
}
return ast_context()->ReturnValue(Pop());
} else { } else {
// Keyed store. // Keyed store.
CHECK_ALIVE(VisitForValue(prop->key())); CHECK_ALIVE(VisitForValue(prop->key()));
...@@ -6618,6 +6576,65 @@ void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( ...@@ -6618,6 +6576,65 @@ void HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
} }
void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr,
BailoutId id,
int position,
BailoutId assignment_id,
Property* prop,
HValue* object,
HValue* value) {
Literal* key = prop->key()->AsLiteral();
Handle<String> name = Handle<String>::cast(key->handle());
ASSERT(!name.is_null());
HInstruction* instr = NULL;
SmallMapList* types = expr->GetReceiverTypes();
bool monomorphic = expr->IsMonomorphic();
Handle<Map> map;
if (monomorphic) {
map = types->first();
if (map->is_dictionary_map()) monomorphic = false;
}
if (monomorphic) {
Handle<JSFunction> setter;
Handle<JSObject> holder;
if (LookupSetter(map, name, &setter, &holder)) {
AddCheckConstantFunction(holder, object, map);
if (FLAG_inline_accessors &&
TryInlineSetter(setter, id, assignment_id, value)) {
return;
}
Drop(2);
AddInstruction(new(zone()) HPushArgument(object));
AddInstruction(new(zone()) HPushArgument(value));
instr = new(zone()) HCallConstantFunction(setter, 2);
} else {
Drop(2);
CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object,
name,
value,
map));
}
} else if (types != NULL && types->length() > 1) {
Drop(2);
return HandlePolymorphicStoreNamedField(
id, position, assignment_id, object, value, types, name);
} else {
Drop(2);
instr = BuildStoreNamedGeneric(object, name, value);
}
Push(value);
instr->set_position(position);
AddInstruction(instr);
if (instr->HasObservableSideEffects()) {
AddSimulate(assignment_id, REMOVABLE_SIMULATE);
}
return ast_context()->ReturnValue(Pop());
}
void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
Expression* target = expr->target(); Expression* target = expr->target();
VariableProxy* proxy = target->AsVariableProxy(); VariableProxy* proxy = target->AsVariableProxy();
...@@ -6744,31 +6761,8 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { ...@@ -6744,31 +6761,8 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
AddSimulate(operation->id(), REMOVABLE_SIMULATE); AddSimulate(operation->id(), REMOVABLE_SIMULATE);
} }
HInstruction* store; return BuildStoreNamed(prop, expr->id(), expr->position(),
if (!monomorphic || map->is_observed()) { expr->AssignmentId(), prop, object, instr);
// If we don't know the monomorphic type, do a generic store.
CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, instr));
} else {
Handle<JSFunction> setter;
Handle<JSObject> holder;
if (LookupSetter(map, name, &setter, &holder)) {
store = BuildCallSetter(object, instr, map, setter, holder);
} else {
CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object,
name,
instr,
map));
}
}
AddInstruction(store);
// Drop the simulated receiver and value. Return the value.
Drop(2);
Push(instr);
if (store->HasObservableSideEffects()) {
AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
}
return ast_context()->ReturnValue(Pop());
} else { } else {
// Keyed property. // Keyed property.
CHECK_ALIVE(VisitForValue(prop->obj())); CHECK_ALIVE(VisitForValue(prop->obj()));
...@@ -8231,14 +8225,14 @@ bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter, ...@@ -8231,14 +8225,14 @@ bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter,
bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter, bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter,
Assignment* assignment, BailoutId id,
BailoutId assignment_id,
HValue* implicit_return_value) { HValue* implicit_return_value) {
return TryInline(CALL_AS_METHOD, return TryInline(CALL_AS_METHOD,
setter, setter,
1, 1,
implicit_return_value, implicit_return_value,
assignment->id(), id, assignment_id,
assignment->AssignmentId(),
SETTER_CALL_RETURN); SETTER_CALL_RETURN);
} }
......
...@@ -1669,7 +1669,8 @@ class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor { ...@@ -1669,7 +1669,8 @@ class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor {
bool TryInlineConstruct(CallNew* expr, HValue* implicit_return_value); bool TryInlineConstruct(CallNew* expr, HValue* implicit_return_value);
bool TryInlineGetter(Handle<JSFunction> getter, Property* prop); bool TryInlineGetter(Handle<JSFunction> getter, Property* prop);
bool TryInlineSetter(Handle<JSFunction> setter, bool TryInlineSetter(Handle<JSFunction> setter,
Assignment* assignment, BailoutId id,
BailoutId assignment_id,
HValue* implicit_return_value); HValue* implicit_return_value);
bool TryInlineApply(Handle<JSFunction> function, bool TryInlineApply(Handle<JSFunction> function,
Call* expr, Call* expr,
...@@ -1702,12 +1703,15 @@ class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor { ...@@ -1702,12 +1703,15 @@ class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor {
HValue* object, HValue* object,
SmallMapList* types, SmallMapList* types,
Handle<String> name); Handle<String> name);
void HandlePolymorphicStoreNamedField(Assignment* expr, void HandlePolymorphicStoreNamedField(BailoutId id,
int position,
BailoutId assignment_id,
HValue* object, HValue* object,
HValue* value, HValue* value,
SmallMapList* types, SmallMapList* types,
Handle<String> name); Handle<String> name);
bool TryStorePolymorphicAsMonomorphic(Assignment* expr, bool TryStorePolymorphicAsMonomorphic(int position,
BailoutId assignment_id,
HValue* object, HValue* object,
HValue* value, HValue* value,
SmallMapList* types, SmallMapList* types,
...@@ -1783,6 +1787,14 @@ class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor { ...@@ -1783,6 +1787,14 @@ class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor {
void AddCheckMapsWithTransitions(HValue* object, void AddCheckMapsWithTransitions(HValue* object,
Handle<Map> map); Handle<Map> map);
void BuildStoreNamed(Expression* expression,
BailoutId id,
int position,
BailoutId assignment_id,
Property* prop,
HValue* object,
HValue* value);
HInstruction* BuildStoreNamedField(HValue* object, HInstruction* BuildStoreNamedField(HValue* object,
Handle<String> name, Handle<String> name,
HValue* value, HValue* value,
......
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