Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index ab037f3a3186c1986f2e4b40c4953f7e77bcc2c3..80546917f13478ccbec9514fee5b2402bd9ae6bd 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -5757,7 +5757,7 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
// The object is expected in the bailout environment during computation |
// of the property values and is the value of the entire expression. |
Push(literal); |
- |
+ int store_slot_index = 0; |
for (int i = 0; i < expr->properties()->length(); i++) { |
ObjectLiteral::Property* property = expr->properties()->at(i); |
if (property->is_computed_name()) return Bailout(kComputedPropertyName); |
@@ -5778,23 +5778,14 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
CHECK_ALIVE(VisitForValue(value)); |
HValue* value = Pop(); |
- // Add [[HomeObject]] to function literals. |
- if (FunctionLiteral::NeedsHomeObject(property->value())) { |
- Handle<Symbol> sym = isolate()->factory()->home_object_symbol(); |
- HInstruction* store_home = BuildKeyedGeneric( |
- STORE, NULL, value, Add<HConstant>(sym), literal); |
- AddInstruction(store_home); |
- DCHECK(store_home->HasObservableSideEffects()); |
- Add<HSimulate>(property->value()->id(), REMOVABLE_SIMULATE); |
- } |
- |
Handle<Map> map = property->GetReceiverType(); |
Handle<String> name = key->AsPropertyName(); |
HValue* store; |
+ FeedbackVectorICSlot slot = expr->GetNthSlot(store_slot_index++); |
if (map.is_null()) { |
// If we don't know the monomorphic type, do a generic store. |
- CHECK_ALIVE(store = BuildNamedGeneric( |
- STORE, NULL, literal, name, value)); |
+ CHECK_ALIVE(store = BuildNamedGeneric(STORE, NULL, slot, literal, |
+ name, value)); |
} else { |
PropertyAccessInfo info(this, STORE, map, name); |
if (info.CanAccessMonomorphic()) { |
@@ -5804,8 +5795,8 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
&info, literal, checked_literal, value, |
BailoutId::None(), BailoutId::None()); |
} else { |
- CHECK_ALIVE(store = BuildNamedGeneric( |
- STORE, NULL, literal, name, value)); |
+ CHECK_ALIVE(store = BuildNamedGeneric(STORE, NULL, slot, |
+ literal, name, value)); |
} |
} |
if (store->IsInstruction()) { |
@@ -5813,6 +5804,17 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
} |
DCHECK(store->HasObservableSideEffects()); |
Add<HSimulate>(key->id(), REMOVABLE_SIMULATE); |
+ |
+ // Add [[HomeObject]] to function literals. |
+ if (FunctionLiteral::NeedsHomeObject(property->value())) { |
+ Handle<Symbol> sym = isolate()->factory()->home_object_symbol(); |
+ HInstruction* store_home = BuildNamedGeneric( |
+ STORE, NULL, expr->GetNthSlot(store_slot_index++), value, sym, |
+ literal); |
+ AddInstruction(store_home); |
+ DCHECK(store_home->HasObservableSideEffects()); |
+ Add<HSimulate>(property->value()->id(), REMOVABLE_SIMULATE); |
+ } |
} else { |
CHECK_ALIVE(VisitForEffect(value)); |
} |
@@ -5827,6 +5829,9 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
} |
} |
+ // Crankshaft may not consume all the slots because it doesn't emit accessors. |
+ DCHECK(!FLAG_vector_stores || store_slot_index <= expr->slot_count()); |
+ |
if (expr->has_function()) { |
// Return the result of the transformation to fast properties |
// instead of the original since this operation changes the map |
@@ -6461,9 +6466,9 @@ HValue* HOptimizedGraphBuilder::BuildMonomorphicAccess( |
void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess( |
- PropertyAccessType access_type, Expression* expr, BailoutId ast_id, |
- BailoutId return_id, HValue* object, HValue* value, SmallMapList* maps, |
- Handle<String> name) { |
+ PropertyAccessType access_type, Expression* expr, FeedbackVectorICSlot slot, |
+ BailoutId ast_id, BailoutId return_id, HValue* object, HValue* value, |
+ SmallMapList* maps, Handle<String> name) { |
// Something did not match; must use a polymorphic load. |
int count = 0; |
HBasicBlock* join = NULL; |
@@ -6581,8 +6586,8 @@ void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess( |
FinishExitWithHardDeoptimization( |
Deoptimizer::kUnknownMapInPolymorphicAccess); |
} else { |
- HInstruction* instr = BuildNamedGeneric(access_type, expr, object, name, |
- value); |
+ HInstruction* instr = |
+ BuildNamedGeneric(access_type, expr, slot, object, name, value); |
AddInstruction(instr); |
if (!ast_context()->IsEffect()) Push(access_type == LOAD ? instr : value); |
@@ -6630,10 +6635,9 @@ static bool AreStringTypes(SmallMapList* maps) { |
} |
-void HOptimizedGraphBuilder::BuildStore(Expression* expr, |
- Property* prop, |
- BailoutId ast_id, |
- BailoutId return_id, |
+void HOptimizedGraphBuilder::BuildStore(Expression* expr, Property* prop, |
+ FeedbackVectorICSlot slot, |
+ BailoutId ast_id, BailoutId return_id, |
bool is_uninitialized) { |
if (!prop->key()->IsPropertyName()) { |
// Keyed store. |
@@ -6641,8 +6645,9 @@ void HOptimizedGraphBuilder::BuildStore(Expression* expr, |
HValue* key = Pop(); |
HValue* object = Pop(); |
bool has_side_effects = false; |
- HValue* result = HandleKeyedElementAccess( |
- object, key, value, expr, ast_id, return_id, STORE, &has_side_effects); |
+ HValue* result = |
+ HandleKeyedElementAccess(object, key, value, expr, slot, ast_id, |
+ return_id, STORE, &has_side_effects); |
if (has_side_effects) { |
if (!ast_context()->IsEffect()) Push(value); |
Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
@@ -6660,8 +6665,8 @@ void HOptimizedGraphBuilder::BuildStore(Expression* expr, |
Handle<String> name = Handle<String>::cast(key->value()); |
DCHECK(!name.is_null()); |
- HValue* access = BuildNamedAccess(STORE, ast_id, return_id, expr, object, |
- name, value, is_uninitialized); |
+ HValue* access = BuildNamedAccess(STORE, ast_id, return_id, expr, slot, |
+ object, name, value, is_uninitialized); |
if (access == NULL) return; |
if (!ast_context()->IsEffect()) Push(value); |
@@ -6682,7 +6687,7 @@ void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { |
CHECK_ALIVE(VisitForValue(prop->key())); |
} |
CHECK_ALIVE(VisitForValue(expr->value())); |
- BuildStore(expr, prop, expr->id(), |
+ BuildStore(expr, prop, expr->AssignmentSlot(), expr->id(), |
expr->AssignmentId(), expr->IsUninitialized()); |
} |
@@ -6691,8 +6696,7 @@ void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { |
// superclass of Assignment and CountOperation, we cannot just pass the |
// owning expression instead of position and ast_id separately. |
void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( |
- Variable* var, |
- HValue* value, |
+ Variable* var, HValue* value, FeedbackVectorICSlot ic_slot, |
BailoutId ast_id) { |
Handle<GlobalObject> global(current_info()->global_object()); |
@@ -6800,6 +6804,11 @@ void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( |
HStoreNamedGeneric* instr = |
Add<HStoreNamedGeneric>(global_object, var->name(), value, |
function_language_mode(), PREMONOMORPHIC); |
+ if (FLAG_vector_stores) { |
+ Handle<TypeFeedbackVector> vector = |
+ handle(current_feedback_vector(), isolate()); |
+ instr->SetVectorAndSlot(vector, ic_slot); |
+ } |
USE(instr); |
DCHECK(instr->HasObservableSideEffects()); |
Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
@@ -6828,8 +6837,7 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
switch (var->location()) { |
case VariableLocation::GLOBAL: |
case VariableLocation::UNALLOCATED: |
- HandleGlobalVariableAssignment(var, |
- Top(), |
+ HandleGlobalVariableAssignment(var, Top(), expr->AssignmentSlot(), |
expr->AssignmentId()); |
break; |
@@ -6905,7 +6913,7 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
Push(BuildBinaryOperation(operation, left, right, PUSH_BEFORE_SIMULATE)); |
- BuildStore(expr, prop, expr->id(), |
+ BuildStore(expr, prop, expr->AssignmentSlot(), expr->id(), |
expr->AssignmentId(), expr->IsUninitialized()); |
} else { |
return Bailout(kInvalidLhsInCompoundAssignment); |
@@ -6956,8 +6964,7 @@ void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { |
case VariableLocation::GLOBAL: |
case VariableLocation::UNALLOCATED: |
CHECK_ALIVE(VisitForValue(expr->value())); |
- HandleGlobalVariableAssignment(var, |
- Top(), |
+ HandleGlobalVariableAssignment(var, Top(), expr->AssignmentSlot(), |
expr->AssignmentId()); |
return ast_context()->ReturnValue(Pop()); |
@@ -7104,8 +7111,8 @@ HInstruction* HGraphBuilder::BuildLoadStringLength(HValue* string) { |
HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric( |
- PropertyAccessType access_type, Expression* expr, HValue* object, |
- Handle<String> name, HValue* value, bool is_uninitialized) { |
+ PropertyAccessType access_type, Expression* expr, FeedbackVectorICSlot slot, |
+ HValue* object, Handle<Name> name, HValue* value, bool is_uninitialized) { |
if (is_uninitialized) { |
Add<HDeoptimize>( |
Deoptimizer::kInsufficientTypeFeedbackForGenericNamedAccess, |
@@ -7114,7 +7121,6 @@ HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric( |
if (access_type == LOAD) { |
Handle<TypeFeedbackVector> vector = |
handle(current_feedback_vector(), isolate()); |
- FeedbackVectorICSlot slot = expr->AsProperty()->PropertyFeedbackSlot(); |
if (!expr->AsProperty()->key()->IsPropertyName()) { |
// It's possible that a keyed load of a constant string was converted |
@@ -7133,19 +7139,36 @@ HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric( |
result->SetVectorAndSlot(vector, slot); |
return result; |
} else { |
- return New<HStoreNamedGeneric>(object, name, value, |
- function_language_mode(), PREMONOMORPHIC); |
+ if (FLAG_vector_stores && |
+ current_feedback_vector()->GetKind(slot) == Code::KEYED_STORE_IC) { |
+ // It's possible that a keyed store of a constant string was converted |
+ // to a named store. Here, at the last minute, we need to make sure to |
+ // use a generic Keyed Store if we are using the type vector, because |
+ // it has to share information with full code. |
+ HConstant* key = Add<HConstant>(name); |
+ HStoreKeyedGeneric* result = New<HStoreKeyedGeneric>( |
+ object, key, value, function_language_mode(), PREMONOMORPHIC); |
+ Handle<TypeFeedbackVector> vector = |
+ handle(current_feedback_vector(), isolate()); |
+ result->SetVectorAndSlot(vector, slot); |
+ return result; |
+ } |
+ |
+ HStoreNamedGeneric* result = New<HStoreNamedGeneric>( |
+ object, name, value, function_language_mode(), PREMONOMORPHIC); |
+ if (FLAG_vector_stores) { |
+ Handle<TypeFeedbackVector> vector = |
+ handle(current_feedback_vector(), isolate()); |
+ result->SetVectorAndSlot(vector, slot); |
+ } |
+ return result; |
} |
} |
- |
HInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric( |
- PropertyAccessType access_type, |
- Expression* expr, |
- HValue* object, |
- HValue* key, |
- HValue* value) { |
+ PropertyAccessType access_type, Expression* expr, FeedbackVectorICSlot slot, |
+ HValue* object, HValue* key, HValue* value) { |
if (access_type == LOAD) { |
InlineCacheState initial_state = expr->AsProperty()->GetInlineCacheState(); |
HLoadKeyedGeneric* result = New<HLoadKeyedGeneric>( |
@@ -7156,13 +7179,18 @@ HInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric( |
// We need to pass vector information. |
Handle<TypeFeedbackVector> vector = |
handle(current_feedback_vector(), isolate()); |
- FeedbackVectorICSlot slot = expr->AsProperty()->PropertyFeedbackSlot(); |
result->SetVectorAndSlot(vector, slot); |
} |
return result; |
} else { |
- return New<HStoreKeyedGeneric>(object, key, value, function_language_mode(), |
- PREMONOMORPHIC); |
+ HStoreKeyedGeneric* result = New<HStoreKeyedGeneric>( |
+ object, key, value, function_language_mode(), PREMONOMORPHIC); |
+ if (FLAG_vector_stores) { |
+ Handle<TypeFeedbackVector> vector = |
+ handle(current_feedback_vector(), isolate()); |
+ result->SetVectorAndSlot(vector, slot); |
+ } |
+ return result; |
} |
} |
@@ -7299,14 +7327,9 @@ HInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad( |
HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( |
- Expression* expr, |
- HValue* object, |
- HValue* key, |
- HValue* val, |
- SmallMapList* maps, |
- PropertyAccessType access_type, |
- KeyedAccessStoreMode store_mode, |
- bool* has_side_effects) { |
+ Expression* expr, FeedbackVectorICSlot slot, HValue* object, HValue* key, |
+ HValue* val, SmallMapList* maps, PropertyAccessType access_type, |
+ KeyedAccessStoreMode store_mode, bool* has_side_effects) { |
*has_side_effects = false; |
BuildCheckHeapObject(object); |
@@ -7334,8 +7357,8 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( |
possible_transitioned_maps.Add(map); |
} |
if (IsSloppyArgumentsElements(elements_kind)) { |
- HInstruction* result = BuildKeyedGeneric(access_type, expr, object, key, |
- val); |
+ HInstruction* result = |
+ BuildKeyedGeneric(access_type, expr, slot, object, key, val); |
*has_side_effects = result->HasObservableSideEffects(); |
return AddInstruction(result); |
} |
@@ -7371,8 +7394,8 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( |
Handle<Map> untransitionable_map = untransitionable_maps[0]; |
HInstruction* instr = NULL; |
if (!CanInlineElementAccess(untransitionable_map)) { |
- instr = AddInstruction(BuildKeyedGeneric(access_type, expr, object, key, |
- val)); |
+ instr = AddInstruction( |
+ BuildKeyedGeneric(access_type, expr, slot, object, key, val)); |
} else { |
instr = BuildMonomorphicElementAccess( |
object, key, val, transition, untransitionable_map, access_type, |
@@ -7396,8 +7419,8 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( |
set_current_block(this_map); |
HInstruction* access = NULL; |
if (!CanInlineElementAccess(map)) { |
- access = AddInstruction(BuildKeyedGeneric(access_type, expr, object, key, |
- val)); |
+ access = AddInstruction( |
+ BuildKeyedGeneric(access_type, expr, slot, object, key, val)); |
} else { |
DCHECK(IsFastElementsKind(elements_kind) || |
IsFixedTypedArrayElementsKind(elements_kind)); |
@@ -7436,9 +7459,9 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( |
HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( |
- HValue* obj, HValue* key, HValue* val, Expression* expr, BailoutId ast_id, |
- BailoutId return_id, PropertyAccessType access_type, |
- bool* has_side_effects) { |
+ HValue* obj, HValue* key, HValue* val, Expression* expr, |
+ FeedbackVectorICSlot slot, BailoutId ast_id, BailoutId return_id, |
+ PropertyAccessType access_type, bool* has_side_effects) { |
if (key->ActualValue()->IsConstant()) { |
Handle<Object> constant = |
HConstant::cast(key->ActualValue())->handle(isolate()); |
@@ -7450,7 +7473,7 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( |
Handle<String>::cast(constant)); |
} |
HValue* access = |
- BuildNamedAccess(access_type, ast_id, return_id, expr, obj, |
+ BuildNamedAccess(access_type, ast_id, return_id, expr, slot, obj, |
Handle<String>::cast(constant), val, false); |
if (access == NULL || access->IsPhi() || |
HInstruction::cast(access)->IsLinked()) { |
@@ -7509,15 +7532,15 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( |
if (monomorphic) { |
Handle<Map> map = maps->first(); |
if (!CanInlineElementAccess(map)) { |
- instr = AddInstruction(BuildKeyedGeneric(access_type, expr, obj, key, |
- val)); |
+ instr = AddInstruction( |
+ BuildKeyedGeneric(access_type, expr, slot, obj, key, val)); |
} else { |
BuildCheckHeapObject(obj); |
instr = BuildMonomorphicElementAccess( |
obj, key, val, NULL, map, access_type, expr->GetStoreMode()); |
} |
} else if (!force_generic && (maps != NULL && !maps->is_empty())) { |
- return HandlePolymorphicElementAccess(expr, obj, key, val, maps, |
+ return HandlePolymorphicElementAccess(expr, slot, obj, key, val, maps, |
access_type, expr->GetStoreMode(), |
has_side_effects); |
} else { |
@@ -7533,7 +7556,8 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( |
Deoptimizer::SOFT); |
} |
} |
- instr = AddInstruction(BuildKeyedGeneric(access_type, expr, obj, key, val)); |
+ instr = AddInstruction( |
+ BuildKeyedGeneric(access_type, expr, slot, obj, key, val)); |
} |
*has_side_effects = instr->HasObservableSideEffects(); |
return instr; |
@@ -7621,8 +7645,8 @@ bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) { |
HValue* HOptimizedGraphBuilder::BuildNamedAccess( |
PropertyAccessType access, BailoutId ast_id, BailoutId return_id, |
- Expression* expr, HValue* object, Handle<String> name, HValue* value, |
- bool is_uninitialized) { |
+ Expression* expr, FeedbackVectorICSlot slot, HValue* object, |
+ Handle<String> name, HValue* value, bool is_uninitialized) { |
SmallMapList* maps; |
ComputeReceiverTypes(expr, object, &maps, zone()); |
DCHECK(maps != NULL); |
@@ -7630,8 +7654,8 @@ HValue* HOptimizedGraphBuilder::BuildNamedAccess( |
if (maps->length() > 0) { |
PropertyAccessInfo info(this, access, maps->first(), name); |
if (!info.CanAccessAsMonomorphic(maps)) { |
- HandlePolymorphicNamedFieldAccess(access, expr, ast_id, return_id, object, |
- value, maps, name); |
+ HandlePolymorphicNamedFieldAccess(access, expr, slot, ast_id, return_id, |
+ object, value, maps, name); |
return NULL; |
} |
@@ -7649,7 +7673,8 @@ HValue* HOptimizedGraphBuilder::BuildNamedAccess( |
&info, object, checked_object, value, ast_id, return_id); |
} |
- return BuildNamedGeneric(access, expr, object, name, value, is_uninitialized); |
+ return BuildNamedGeneric(access, expr, slot, object, name, value, |
+ is_uninitialized); |
} |
@@ -7677,8 +7702,9 @@ void HOptimizedGraphBuilder::BuildLoad(Property* expr, |
Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); |
HValue* object = Pop(); |
- HValue* value = BuildNamedAccess(LOAD, ast_id, expr->LoadId(), expr, object, |
- name, NULL, expr->IsUninitialized()); |
+ HValue* value = BuildNamedAccess(LOAD, ast_id, expr->LoadId(), expr, |
+ expr->PropertyFeedbackSlot(), object, name, |
+ NULL, expr->IsUninitialized()); |
if (value == NULL) return; |
if (value->IsPhi()) return ast_context()->ReturnValue(value); |
instr = HInstruction::cast(value); |
@@ -7690,7 +7716,8 @@ void HOptimizedGraphBuilder::BuildLoad(Property* expr, |
bool has_side_effects = false; |
HValue* load = HandleKeyedElementAccess( |
- obj, key, NULL, expr, ast_id, expr->LoadId(), LOAD, &has_side_effects); |
+ obj, key, NULL, expr, expr->PropertyFeedbackSlot(), ast_id, |
+ expr->LoadId(), LOAD, &has_side_effects); |
if (has_side_effects) { |
if (ast_context()->IsEffect()) { |
Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
@@ -7973,8 +8000,9 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(Call* expr, |
FinishExitWithHardDeoptimization(Deoptimizer::kUnknownMapInPolymorphicCall); |
} else { |
Property* prop = expr->expression()->AsProperty(); |
- HInstruction* function = BuildNamedGeneric( |
- LOAD, prop, receiver, name, NULL, prop->IsUninitialized()); |
+ HInstruction* function = |
+ BuildNamedGeneric(LOAD, prop, prop->PropertyFeedbackSlot(), receiver, |
+ name, NULL, prop->IsUninitialized()); |
AddInstruction(function); |
Push(function); |
AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); |
@@ -10431,18 +10459,15 @@ HInstruction* HOptimizedGraphBuilder::BuildIncrement( |
} |
-void HOptimizedGraphBuilder::BuildStoreForEffect(Expression* expr, |
- Property* prop, |
- BailoutId ast_id, |
- BailoutId return_id, |
- HValue* object, |
- HValue* key, |
- HValue* value) { |
+void HOptimizedGraphBuilder::BuildStoreForEffect( |
+ Expression* expr, Property* prop, FeedbackVectorICSlot slot, |
+ BailoutId ast_id, BailoutId return_id, HValue* object, HValue* key, |
+ HValue* value) { |
EffectContext for_effect(this); |
Push(object); |
if (key != NULL) Push(key); |
Push(value); |
- BuildStore(expr, prop, ast_id, return_id); |
+ BuildStore(expr, prop, slot, ast_id, return_id); |
} |
@@ -10485,8 +10510,7 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { |
switch (var->location()) { |
case VariableLocation::GLOBAL: |
case VariableLocation::UNALLOCATED: |
- HandleGlobalVariableAssignment(var, |
- after, |
+ HandleGlobalVariableAssignment(var, after, expr->CountSlot(), |
expr->AssignmentId()); |
break; |
@@ -10552,13 +10576,14 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { |
// Drop object and key to push it again in the effect context below. |
Drop(key == NULL ? 1 : 2); |
environment()->SetExpressionStackAt(0, input); |
- CHECK_ALIVE(BuildStoreForEffect( |
- expr, prop, expr->id(), expr->AssignmentId(), object, key, after)); |
+ CHECK_ALIVE(BuildStoreForEffect(expr, prop, expr->CountSlot(), expr->id(), |
+ expr->AssignmentId(), object, key, after)); |
return ast_context()->ReturnValue(Pop()); |
} |
environment()->SetExpressionStackAt(0, after); |
- return BuildStore(expr, prop, expr->id(), expr->AssignmentId()); |
+ return BuildStore(expr, prop, expr->CountSlot(), expr->id(), |
+ expr->AssignmentId()); |
} |