Commit f8a4afa7 authored by mvstanton's avatar mvstanton Committed by Commit bot

VectorICs: Crankshaft adaptations to deal with vector store ics.

Also, a one line fix in TurboFan to call the correct store ic.

BUG=

Review URL: https://codereview.chromium.org/1266983002

Cr-Commit-Position: refs/heads/master@{#29952}
parent 1667c15e
...@@ -409,7 +409,8 @@ void JSGenericLowering::LowerJSStoreGlobal(Node* node) { ...@@ -409,7 +409,8 @@ void JSGenericLowering::LowerJSStoreGlobal(Node* node) {
ReplaceWithStubCall(node, callable, flags); ReplaceWithStubCall(node, callable, flags);
} else { } else {
Callable callable = CodeFactory::StoreIC(isolate(), p.language_mode()); Callable callable = CodeFactory::StoreICInOptimizedCode(
isolate(), p.language_mode(), UNINITIALIZED);
node->RemoveInput(0); // script context node->RemoveInput(0); // script context
node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name())); node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
if (FLAG_vector_stores) { if (FLAG_vector_stores) {
......
...@@ -5757,7 +5757,7 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -5757,7 +5757,7 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
// The object is expected in the bailout environment during computation // The object is expected in the bailout environment during computation
// of the property values and is the value of the entire expression. // of the property values and is the value of the entire expression.
Push(literal); Push(literal);
int store_slot_index = 0;
for (int i = 0; i < expr->properties()->length(); i++) { for (int i = 0; i < expr->properties()->length(); i++) {
ObjectLiteral::Property* property = expr->properties()->at(i); ObjectLiteral::Property* property = expr->properties()->at(i);
if (property->is_computed_name()) return Bailout(kComputedPropertyName); if (property->is_computed_name()) return Bailout(kComputedPropertyName);
...@@ -5778,23 +5778,14 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -5778,23 +5778,14 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
CHECK_ALIVE(VisitForValue(value)); CHECK_ALIVE(VisitForValue(value));
HValue* value = Pop(); 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<Map> map = property->GetReceiverType();
Handle<String> name = key->AsPropertyName(); Handle<String> name = key->AsPropertyName();
HValue* store; HValue* store;
FeedbackVectorICSlot slot = expr->GetNthSlot(store_slot_index++);
if (map.is_null()) { if (map.is_null()) {
// If we don't know the monomorphic type, do a generic store. // If we don't know the monomorphic type, do a generic store.
CHECK_ALIVE(store = BuildNamedGeneric( CHECK_ALIVE(store = BuildNamedGeneric(STORE, NULL, slot, literal,
STORE, NULL, literal, name, value)); name, value));
} else { } else {
PropertyAccessInfo info(this, STORE, map, name); PropertyAccessInfo info(this, STORE, map, name);
if (info.CanAccessMonomorphic()) { if (info.CanAccessMonomorphic()) {
...@@ -5804,8 +5795,8 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -5804,8 +5795,8 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
&info, literal, checked_literal, value, &info, literal, checked_literal, value,
BailoutId::None(), BailoutId::None()); BailoutId::None(), BailoutId::None());
} else { } else {
CHECK_ALIVE(store = BuildNamedGeneric( CHECK_ALIVE(store = BuildNamedGeneric(STORE, NULL, slot,
STORE, NULL, literal, name, value)); literal, name, value));
} }
} }
if (store->IsInstruction()) { if (store->IsInstruction()) {
...@@ -5813,6 +5804,17 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -5813,6 +5804,17 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
} }
DCHECK(store->HasObservableSideEffects()); DCHECK(store->HasObservableSideEffects());
Add<HSimulate>(key->id(), REMOVABLE_SIMULATE); 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 { } else {
CHECK_ALIVE(VisitForEffect(value)); CHECK_ALIVE(VisitForEffect(value));
} }
...@@ -5827,6 +5829,9 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -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()) { if (expr->has_function()) {
// Return the result of the transformation to fast properties // Return the result of the transformation to fast properties
// instead of the original since this operation changes the map // instead of the original since this operation changes the map
...@@ -6461,9 +6466,9 @@ HValue* HOptimizedGraphBuilder::BuildMonomorphicAccess( ...@@ -6461,9 +6466,9 @@ HValue* HOptimizedGraphBuilder::BuildMonomorphicAccess(
void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess( void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess(
PropertyAccessType access_type, Expression* expr, BailoutId ast_id, PropertyAccessType access_type, Expression* expr, FeedbackVectorICSlot slot,
BailoutId return_id, HValue* object, HValue* value, SmallMapList* maps, BailoutId ast_id, BailoutId return_id, HValue* object, HValue* value,
Handle<String> name) { SmallMapList* maps, Handle<String> name) {
// Something did not match; must use a polymorphic load. // Something did not match; must use a polymorphic load.
int count = 0; int count = 0;
HBasicBlock* join = NULL; HBasicBlock* join = NULL;
...@@ -6581,8 +6586,8 @@ void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess( ...@@ -6581,8 +6586,8 @@ void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess(
FinishExitWithHardDeoptimization( FinishExitWithHardDeoptimization(
Deoptimizer::kUnknownMapInPolymorphicAccess); Deoptimizer::kUnknownMapInPolymorphicAccess);
} else { } else {
HInstruction* instr = BuildNamedGeneric(access_type, expr, object, name, HInstruction* instr =
value); BuildNamedGeneric(access_type, expr, slot, object, name, value);
AddInstruction(instr); AddInstruction(instr);
if (!ast_context()->IsEffect()) Push(access_type == LOAD ? instr : value); if (!ast_context()->IsEffect()) Push(access_type == LOAD ? instr : value);
...@@ -6630,10 +6635,9 @@ static bool AreStringTypes(SmallMapList* maps) { ...@@ -6630,10 +6635,9 @@ static bool AreStringTypes(SmallMapList* maps) {
} }
void HOptimizedGraphBuilder::BuildStore(Expression* expr, void HOptimizedGraphBuilder::BuildStore(Expression* expr, Property* prop,
Property* prop, FeedbackVectorICSlot slot,
BailoutId ast_id, BailoutId ast_id, BailoutId return_id,
BailoutId return_id,
bool is_uninitialized) { bool is_uninitialized) {
if (!prop->key()->IsPropertyName()) { if (!prop->key()->IsPropertyName()) {
// Keyed store. // Keyed store.
...@@ -6641,8 +6645,9 @@ void HOptimizedGraphBuilder::BuildStore(Expression* expr, ...@@ -6641,8 +6645,9 @@ void HOptimizedGraphBuilder::BuildStore(Expression* expr,
HValue* key = Pop(); HValue* key = Pop();
HValue* object = Pop(); HValue* object = Pop();
bool has_side_effects = false; bool has_side_effects = false;
HValue* result = HandleKeyedElementAccess( HValue* result =
object, key, value, expr, ast_id, return_id, STORE, &has_side_effects); HandleKeyedElementAccess(object, key, value, expr, slot, ast_id,
return_id, STORE, &has_side_effects);
if (has_side_effects) { if (has_side_effects) {
if (!ast_context()->IsEffect()) Push(value); if (!ast_context()->IsEffect()) Push(value);
Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
...@@ -6660,8 +6665,8 @@ void HOptimizedGraphBuilder::BuildStore(Expression* expr, ...@@ -6660,8 +6665,8 @@ void HOptimizedGraphBuilder::BuildStore(Expression* expr,
Handle<String> name = Handle<String>::cast(key->value()); Handle<String> name = Handle<String>::cast(key->value());
DCHECK(!name.is_null()); DCHECK(!name.is_null());
HValue* access = BuildNamedAccess(STORE, ast_id, return_id, expr, object, HValue* access = BuildNamedAccess(STORE, ast_id, return_id, expr, slot,
name, value, is_uninitialized); object, name, value, is_uninitialized);
if (access == NULL) return; if (access == NULL) return;
if (!ast_context()->IsEffect()) Push(value); if (!ast_context()->IsEffect()) Push(value);
...@@ -6682,7 +6687,7 @@ void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { ...@@ -6682,7 +6687,7 @@ void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
CHECK_ALIVE(VisitForValue(prop->key())); CHECK_ALIVE(VisitForValue(prop->key()));
} }
CHECK_ALIVE(VisitForValue(expr->value())); CHECK_ALIVE(VisitForValue(expr->value()));
BuildStore(expr, prop, expr->id(), BuildStore(expr, prop, expr->AssignmentSlot(), expr->id(),
expr->AssignmentId(), expr->IsUninitialized()); expr->AssignmentId(), expr->IsUninitialized());
} }
...@@ -6691,8 +6696,7 @@ void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { ...@@ -6691,8 +6696,7 @@ void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
// superclass of Assignment and CountOperation, we cannot just pass the // superclass of Assignment and CountOperation, we cannot just pass the
// owning expression instead of position and ast_id separately. // owning expression instead of position and ast_id separately.
void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( void HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
Variable* var, Variable* var, HValue* value, FeedbackVectorICSlot ic_slot,
HValue* value,
BailoutId ast_id) { BailoutId ast_id) {
Handle<GlobalObject> global(current_info()->global_object()); Handle<GlobalObject> global(current_info()->global_object());
...@@ -6800,6 +6804,11 @@ void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( ...@@ -6800,6 +6804,11 @@ void HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
HStoreNamedGeneric* instr = HStoreNamedGeneric* instr =
Add<HStoreNamedGeneric>(global_object, var->name(), value, Add<HStoreNamedGeneric>(global_object, var->name(), value,
function_language_mode(), PREMONOMORPHIC); function_language_mode(), PREMONOMORPHIC);
if (FLAG_vector_stores) {
Handle<TypeFeedbackVector> vector =
handle(current_feedback_vector(), isolate());
instr->SetVectorAndSlot(vector, ic_slot);
}
USE(instr); USE(instr);
DCHECK(instr->HasObservableSideEffects()); DCHECK(instr->HasObservableSideEffects());
Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
...@@ -6828,8 +6837,7 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { ...@@ -6828,8 +6837,7 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
switch (var->location()) { switch (var->location()) {
case VariableLocation::GLOBAL: case VariableLocation::GLOBAL:
case VariableLocation::UNALLOCATED: case VariableLocation::UNALLOCATED:
HandleGlobalVariableAssignment(var, HandleGlobalVariableAssignment(var, Top(), expr->AssignmentSlot(),
Top(),
expr->AssignmentId()); expr->AssignmentId());
break; break;
...@@ -6905,7 +6913,7 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { ...@@ -6905,7 +6913,7 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
Push(BuildBinaryOperation(operation, left, right, PUSH_BEFORE_SIMULATE)); Push(BuildBinaryOperation(operation, left, right, PUSH_BEFORE_SIMULATE));
BuildStore(expr, prop, expr->id(), BuildStore(expr, prop, expr->AssignmentSlot(), expr->id(),
expr->AssignmentId(), expr->IsUninitialized()); expr->AssignmentId(), expr->IsUninitialized());
} else { } else {
return Bailout(kInvalidLhsInCompoundAssignment); return Bailout(kInvalidLhsInCompoundAssignment);
...@@ -6956,8 +6964,7 @@ void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { ...@@ -6956,8 +6964,7 @@ void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) {
case VariableLocation::GLOBAL: case VariableLocation::GLOBAL:
case VariableLocation::UNALLOCATED: case VariableLocation::UNALLOCATED:
CHECK_ALIVE(VisitForValue(expr->value())); CHECK_ALIVE(VisitForValue(expr->value()));
HandleGlobalVariableAssignment(var, HandleGlobalVariableAssignment(var, Top(), expr->AssignmentSlot(),
Top(),
expr->AssignmentId()); expr->AssignmentId());
return ast_context()->ReturnValue(Pop()); return ast_context()->ReturnValue(Pop());
...@@ -7104,8 +7111,8 @@ HInstruction* HGraphBuilder::BuildLoadStringLength(HValue* string) { ...@@ -7104,8 +7111,8 @@ HInstruction* HGraphBuilder::BuildLoadStringLength(HValue* string) {
HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric( HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric(
PropertyAccessType access_type, Expression* expr, HValue* object, PropertyAccessType access_type, Expression* expr, FeedbackVectorICSlot slot,
Handle<String> name, HValue* value, bool is_uninitialized) { HValue* object, Handle<Name> name, HValue* value, bool is_uninitialized) {
if (is_uninitialized) { if (is_uninitialized) {
Add<HDeoptimize>( Add<HDeoptimize>(
Deoptimizer::kInsufficientTypeFeedbackForGenericNamedAccess, Deoptimizer::kInsufficientTypeFeedbackForGenericNamedAccess,
...@@ -7114,7 +7121,6 @@ HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric( ...@@ -7114,7 +7121,6 @@ HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric(
if (access_type == LOAD) { if (access_type == LOAD) {
Handle<TypeFeedbackVector> vector = Handle<TypeFeedbackVector> vector =
handle(current_feedback_vector(), isolate()); handle(current_feedback_vector(), isolate());
FeedbackVectorICSlot slot = expr->AsProperty()->PropertyFeedbackSlot();
if (!expr->AsProperty()->key()->IsPropertyName()) { if (!expr->AsProperty()->key()->IsPropertyName()) {
// It's possible that a keyed load of a constant string was converted // It's possible that a keyed load of a constant string was converted
...@@ -7133,19 +7139,36 @@ HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric( ...@@ -7133,19 +7139,36 @@ HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric(
result->SetVectorAndSlot(vector, slot); result->SetVectorAndSlot(vector, slot);
return result; return result;
} else { } else {
return New<HStoreNamedGeneric>(object, name, value, if (FLAG_vector_stores &&
function_language_mode(), PREMONOMORPHIC); 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( HInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric(
PropertyAccessType access_type, PropertyAccessType access_type, Expression* expr, FeedbackVectorICSlot slot,
Expression* expr, HValue* object, HValue* key, HValue* value) {
HValue* object,
HValue* key,
HValue* value) {
if (access_type == LOAD) { if (access_type == LOAD) {
InlineCacheState initial_state = expr->AsProperty()->GetInlineCacheState(); InlineCacheState initial_state = expr->AsProperty()->GetInlineCacheState();
HLoadKeyedGeneric* result = New<HLoadKeyedGeneric>( HLoadKeyedGeneric* result = New<HLoadKeyedGeneric>(
...@@ -7156,13 +7179,18 @@ HInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric( ...@@ -7156,13 +7179,18 @@ HInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric(
// We need to pass vector information. // We need to pass vector information.
Handle<TypeFeedbackVector> vector = Handle<TypeFeedbackVector> vector =
handle(current_feedback_vector(), isolate()); handle(current_feedback_vector(), isolate());
FeedbackVectorICSlot slot = expr->AsProperty()->PropertyFeedbackSlot();
result->SetVectorAndSlot(vector, slot); result->SetVectorAndSlot(vector, slot);
} }
return result; return result;
} else { } else {
return New<HStoreKeyedGeneric>(object, key, value, function_language_mode(), HStoreKeyedGeneric* result = New<HStoreKeyedGeneric>(
PREMONOMORPHIC); 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( ...@@ -7299,14 +7327,9 @@ HInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad(
HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
Expression* expr, Expression* expr, FeedbackVectorICSlot slot, HValue* object, HValue* key,
HValue* object, HValue* val, SmallMapList* maps, PropertyAccessType access_type,
HValue* key, KeyedAccessStoreMode store_mode, bool* has_side_effects) {
HValue* val,
SmallMapList* maps,
PropertyAccessType access_type,
KeyedAccessStoreMode store_mode,
bool* has_side_effects) {
*has_side_effects = false; *has_side_effects = false;
BuildCheckHeapObject(object); BuildCheckHeapObject(object);
...@@ -7334,8 +7357,8 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( ...@@ -7334,8 +7357,8 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
possible_transitioned_maps.Add(map); possible_transitioned_maps.Add(map);
} }
if (IsSloppyArgumentsElements(elements_kind)) { if (IsSloppyArgumentsElements(elements_kind)) {
HInstruction* result = BuildKeyedGeneric(access_type, expr, object, key, HInstruction* result =
val); BuildKeyedGeneric(access_type, expr, slot, object, key, val);
*has_side_effects = result->HasObservableSideEffects(); *has_side_effects = result->HasObservableSideEffects();
return AddInstruction(result); return AddInstruction(result);
} }
...@@ -7371,8 +7394,8 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( ...@@ -7371,8 +7394,8 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
Handle<Map> untransitionable_map = untransitionable_maps[0]; Handle<Map> untransitionable_map = untransitionable_maps[0];
HInstruction* instr = NULL; HInstruction* instr = NULL;
if (!CanInlineElementAccess(untransitionable_map)) { if (!CanInlineElementAccess(untransitionable_map)) {
instr = AddInstruction(BuildKeyedGeneric(access_type, expr, object, key, instr = AddInstruction(
val)); BuildKeyedGeneric(access_type, expr, slot, object, key, val));
} else { } else {
instr = BuildMonomorphicElementAccess( instr = BuildMonomorphicElementAccess(
object, key, val, transition, untransitionable_map, access_type, object, key, val, transition, untransitionable_map, access_type,
...@@ -7396,8 +7419,8 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( ...@@ -7396,8 +7419,8 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
set_current_block(this_map); set_current_block(this_map);
HInstruction* access = NULL; HInstruction* access = NULL;
if (!CanInlineElementAccess(map)) { if (!CanInlineElementAccess(map)) {
access = AddInstruction(BuildKeyedGeneric(access_type, expr, object, key, access = AddInstruction(
val)); BuildKeyedGeneric(access_type, expr, slot, object, key, val));
} else { } else {
DCHECK(IsFastElementsKind(elements_kind) || DCHECK(IsFastElementsKind(elements_kind) ||
IsFixedTypedArrayElementsKind(elements_kind)); IsFixedTypedArrayElementsKind(elements_kind));
...@@ -7436,9 +7459,9 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( ...@@ -7436,9 +7459,9 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess(
HValue* obj, HValue* key, HValue* val, Expression* expr, BailoutId ast_id, HValue* obj, HValue* key, HValue* val, Expression* expr,
BailoutId return_id, PropertyAccessType access_type, FeedbackVectorICSlot slot, BailoutId ast_id, BailoutId return_id,
bool* has_side_effects) { PropertyAccessType access_type, bool* has_side_effects) {
if (key->ActualValue()->IsConstant()) { if (key->ActualValue()->IsConstant()) {
Handle<Object> constant = Handle<Object> constant =
HConstant::cast(key->ActualValue())->handle(isolate()); HConstant::cast(key->ActualValue())->handle(isolate());
...@@ -7450,7 +7473,7 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( ...@@ -7450,7 +7473,7 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess(
Handle<String>::cast(constant)); Handle<String>::cast(constant));
} }
HValue* access = 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); Handle<String>::cast(constant), val, false);
if (access == NULL || access->IsPhi() || if (access == NULL || access->IsPhi() ||
HInstruction::cast(access)->IsLinked()) { HInstruction::cast(access)->IsLinked()) {
...@@ -7509,15 +7532,15 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( ...@@ -7509,15 +7532,15 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess(
if (monomorphic) { if (monomorphic) {
Handle<Map> map = maps->first(); Handle<Map> map = maps->first();
if (!CanInlineElementAccess(map)) { if (!CanInlineElementAccess(map)) {
instr = AddInstruction(BuildKeyedGeneric(access_type, expr, obj, key, instr = AddInstruction(
val)); BuildKeyedGeneric(access_type, expr, slot, obj, key, val));
} else { } else {
BuildCheckHeapObject(obj); BuildCheckHeapObject(obj);
instr = BuildMonomorphicElementAccess( instr = BuildMonomorphicElementAccess(
obj, key, val, NULL, map, access_type, expr->GetStoreMode()); obj, key, val, NULL, map, access_type, expr->GetStoreMode());
} }
} else if (!force_generic && (maps != NULL && !maps->is_empty())) { } 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(), access_type, expr->GetStoreMode(),
has_side_effects); has_side_effects);
} else { } else {
...@@ -7533,7 +7556,8 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( ...@@ -7533,7 +7556,8 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess(
Deoptimizer::SOFT); 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(); *has_side_effects = instr->HasObservableSideEffects();
return instr; return instr;
...@@ -7621,8 +7645,8 @@ bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) { ...@@ -7621,8 +7645,8 @@ bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) {
HValue* HOptimizedGraphBuilder::BuildNamedAccess( HValue* HOptimizedGraphBuilder::BuildNamedAccess(
PropertyAccessType access, BailoutId ast_id, BailoutId return_id, PropertyAccessType access, BailoutId ast_id, BailoutId return_id,
Expression* expr, HValue* object, Handle<String> name, HValue* value, Expression* expr, FeedbackVectorICSlot slot, HValue* object,
bool is_uninitialized) { Handle<String> name, HValue* value, bool is_uninitialized) {
SmallMapList* maps; SmallMapList* maps;
ComputeReceiverTypes(expr, object, &maps, zone()); ComputeReceiverTypes(expr, object, &maps, zone());
DCHECK(maps != NULL); DCHECK(maps != NULL);
...@@ -7630,8 +7654,8 @@ HValue* HOptimizedGraphBuilder::BuildNamedAccess( ...@@ -7630,8 +7654,8 @@ HValue* HOptimizedGraphBuilder::BuildNamedAccess(
if (maps->length() > 0) { if (maps->length() > 0) {
PropertyAccessInfo info(this, access, maps->first(), name); PropertyAccessInfo info(this, access, maps->first(), name);
if (!info.CanAccessAsMonomorphic(maps)) { if (!info.CanAccessAsMonomorphic(maps)) {
HandlePolymorphicNamedFieldAccess(access, expr, ast_id, return_id, object, HandlePolymorphicNamedFieldAccess(access, expr, slot, ast_id, return_id,
value, maps, name); object, value, maps, name);
return NULL; return NULL;
} }
...@@ -7649,7 +7673,8 @@ HValue* HOptimizedGraphBuilder::BuildNamedAccess( ...@@ -7649,7 +7673,8 @@ HValue* HOptimizedGraphBuilder::BuildNamedAccess(
&info, object, checked_object, value, ast_id, return_id); &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, ...@@ -7677,8 +7702,9 @@ void HOptimizedGraphBuilder::BuildLoad(Property* expr,
Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
HValue* object = Pop(); HValue* object = Pop();
HValue* value = BuildNamedAccess(LOAD, ast_id, expr->LoadId(), expr, object, HValue* value = BuildNamedAccess(LOAD, ast_id, expr->LoadId(), expr,
name, NULL, expr->IsUninitialized()); expr->PropertyFeedbackSlot(), object, name,
NULL, expr->IsUninitialized());
if (value == NULL) return; if (value == NULL) return;
if (value->IsPhi()) return ast_context()->ReturnValue(value); if (value->IsPhi()) return ast_context()->ReturnValue(value);
instr = HInstruction::cast(value); instr = HInstruction::cast(value);
...@@ -7690,7 +7716,8 @@ void HOptimizedGraphBuilder::BuildLoad(Property* expr, ...@@ -7690,7 +7716,8 @@ void HOptimizedGraphBuilder::BuildLoad(Property* expr,
bool has_side_effects = false; bool has_side_effects = false;
HValue* load = HandleKeyedElementAccess( 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 (has_side_effects) {
if (ast_context()->IsEffect()) { if (ast_context()->IsEffect()) {
Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
...@@ -7973,8 +8000,9 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(Call* expr, ...@@ -7973,8 +8000,9 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
FinishExitWithHardDeoptimization(Deoptimizer::kUnknownMapInPolymorphicCall); FinishExitWithHardDeoptimization(Deoptimizer::kUnknownMapInPolymorphicCall);
} else { } else {
Property* prop = expr->expression()->AsProperty(); Property* prop = expr->expression()->AsProperty();
HInstruction* function = BuildNamedGeneric( HInstruction* function =
LOAD, prop, receiver, name, NULL, prop->IsUninitialized()); BuildNamedGeneric(LOAD, prop, prop->PropertyFeedbackSlot(), receiver,
name, NULL, prop->IsUninitialized());
AddInstruction(function); AddInstruction(function);
Push(function); Push(function);
AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
...@@ -10431,18 +10459,15 @@ HInstruction* HOptimizedGraphBuilder::BuildIncrement( ...@@ -10431,18 +10459,15 @@ HInstruction* HOptimizedGraphBuilder::BuildIncrement(
} }
void HOptimizedGraphBuilder::BuildStoreForEffect(Expression* expr, void HOptimizedGraphBuilder::BuildStoreForEffect(
Property* prop, Expression* expr, Property* prop, FeedbackVectorICSlot slot,
BailoutId ast_id, BailoutId ast_id, BailoutId return_id, HValue* object, HValue* key,
BailoutId return_id,
HValue* object,
HValue* key,
HValue* value) { HValue* value) {
EffectContext for_effect(this); EffectContext for_effect(this);
Push(object); Push(object);
if (key != NULL) Push(key); if (key != NULL) Push(key);
Push(value); 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) { ...@@ -10485,8 +10510,7 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) {
switch (var->location()) { switch (var->location()) {
case VariableLocation::GLOBAL: case VariableLocation::GLOBAL:
case VariableLocation::UNALLOCATED: case VariableLocation::UNALLOCATED:
HandleGlobalVariableAssignment(var, HandleGlobalVariableAssignment(var, after, expr->CountSlot(),
after,
expr->AssignmentId()); expr->AssignmentId());
break; break;
...@@ -10552,13 +10576,14 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { ...@@ -10552,13 +10576,14 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) {
// Drop object and key to push it again in the effect context below. // Drop object and key to push it again in the effect context below.
Drop(key == NULL ? 1 : 2); Drop(key == NULL ? 1 : 2);
environment()->SetExpressionStackAt(0, input); environment()->SetExpressionStackAt(0, input);
CHECK_ALIVE(BuildStoreForEffect( CHECK_ALIVE(BuildStoreForEffect(expr, prop, expr->CountSlot(), expr->id(),
expr, prop, expr->id(), expr->AssignmentId(), object, key, after)); expr->AssignmentId(), object, key, after));
return ast_context()->ReturnValue(Pop()); return ast_context()->ReturnValue(Pop());
} }
environment()->SetExpressionStackAt(0, after); environment()->SetExpressionStackAt(0, after);
return BuildStore(expr, prop, expr->id(), expr->AssignmentId()); return BuildStore(expr, prop, expr->CountSlot(), expr->id(),
expr->AssignmentId());
} }
......
...@@ -2453,20 +2453,16 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { ...@@ -2453,20 +2453,16 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
Handle<JSFunction> caller, Handle<JSFunction> caller,
const char* failure_reason); const char* failure_reason);
void HandleGlobalVariableAssignment(Variable* var, void HandleGlobalVariableAssignment(Variable* var, HValue* value,
HValue* value, FeedbackVectorICSlot ic_slot,
BailoutId ast_id); BailoutId ast_id);
void HandlePropertyAssignment(Assignment* expr); void HandlePropertyAssignment(Assignment* expr);
void HandleCompoundAssignment(Assignment* expr); void HandleCompoundAssignment(Assignment* expr);
void HandlePolymorphicNamedFieldAccess(PropertyAccessType access_type, void HandlePolymorphicNamedFieldAccess(
Expression* expr, PropertyAccessType access_type, Expression* expr,
BailoutId ast_id, FeedbackVectorICSlot slot, BailoutId ast_id, BailoutId return_id,
BailoutId return_id, HValue* object, HValue* value, SmallMapList* types, Handle<String> name);
HValue* object,
HValue* value,
SmallMapList* types,
Handle<String> name);
HValue* BuildAllocateExternalElements( HValue* BuildAllocateExternalElements(
ExternalArrayType array_type, ExternalArrayType array_type,
...@@ -2715,7 +2711,8 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { ...@@ -2715,7 +2711,8 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
HValue* BuildNamedAccess(PropertyAccessType access, BailoutId ast_id, HValue* BuildNamedAccess(PropertyAccessType access, BailoutId ast_id,
BailoutId reutrn_id, Expression* expr, BailoutId reutrn_id, Expression* expr,
HValue* object, Handle<String> name, HValue* value, FeedbackVectorICSlot slot, HValue* object,
Handle<String> name, HValue* value,
bool is_uninitialized = false); bool is_uninitialized = false);
void HandlePolymorphicCallNamed(Call* expr, void HandlePolymorphicCallNamed(Call* expr,
...@@ -2751,10 +2748,8 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { ...@@ -2751,10 +2748,8 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
HInstruction* BuildIncrement(bool returns_original_input, HInstruction* BuildIncrement(bool returns_original_input,
CountOperation* expr); CountOperation* expr);
HInstruction* BuildKeyedGeneric(PropertyAccessType access_type, HInstruction* BuildKeyedGeneric(PropertyAccessType access_type,
Expression* expr, Expression* expr, FeedbackVectorICSlot slot,
HValue* object, HValue* object, HValue* key, HValue* value);
HValue* key,
HValue* value);
HInstruction* TryBuildConsolidatedElementLoad(HValue* object, HInstruction* TryBuildConsolidatedElementLoad(HValue* object,
HValue* key, HValue* key,
...@@ -2771,24 +2766,21 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { ...@@ -2771,24 +2766,21 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
PropertyAccessType access_type, PropertyAccessType access_type,
KeyedAccessStoreMode store_mode); KeyedAccessStoreMode store_mode);
HValue* HandlePolymorphicElementAccess(Expression* expr, HValue* HandlePolymorphicElementAccess(
HValue* object, Expression* expr, FeedbackVectorICSlot slot, HValue* object, HValue* key,
HValue* key, HValue* val, SmallMapList* maps, PropertyAccessType access_type,
HValue* val, KeyedAccessStoreMode store_mode, bool* has_side_effects);
SmallMapList* maps,
PropertyAccessType access_type,
KeyedAccessStoreMode store_mode,
bool* has_side_effects);
HValue* HandleKeyedElementAccess(HValue* obj, HValue* key, HValue* val, HValue* HandleKeyedElementAccess(HValue* obj, HValue* key, HValue* val,
Expression* expr, BailoutId ast_id, Expression* expr, FeedbackVectorICSlot slot,
BailoutId return_id, BailoutId ast_id, BailoutId return_id,
PropertyAccessType access_type, PropertyAccessType access_type,
bool* has_side_effects); bool* has_side_effects);
HInstruction* BuildNamedGeneric(PropertyAccessType access, Expression* expr, HInstruction* BuildNamedGeneric(PropertyAccessType access, Expression* expr,
HValue* object, Handle<String> name, FeedbackVectorICSlot slot, HValue* object,
HValue* value, bool is_uninitialized = false); Handle<Name> name, HValue* value,
bool is_uninitialized = false);
HCheckMaps* AddCheckMap(HValue* object, Handle<Map> map); HCheckMaps* AddCheckMap(HValue* object, Handle<Map> map);
...@@ -2798,19 +2790,14 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { ...@@ -2798,19 +2790,14 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
HValue* object, HValue* object,
HValue* key); HValue* key);
void BuildStoreForEffect(Expression* expression, void BuildStoreForEffect(Expression* expression, Property* prop,
Property* prop, FeedbackVectorICSlot slot, BailoutId ast_id,
BailoutId ast_id, BailoutId return_id, HValue* object, HValue* key,
BailoutId return_id,
HValue* object,
HValue* key,
HValue* value); HValue* value);
void BuildStore(Expression* expression, void BuildStore(Expression* expression, Property* prop,
Property* prop, FeedbackVectorICSlot slot, BailoutId ast_id,
BailoutId ast_id, BailoutId return_id, bool is_uninitialized = false);
BailoutId return_id,
bool is_uninitialized = false);
HInstruction* BuildLoadNamedField(PropertyAccessInfo* info, HInstruction* BuildLoadNamedField(PropertyAccessInfo* info,
HValue* checked_object); HValue* checked_object);
......
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