Chromium Code Reviews| Index: src/hydrogen.cc |
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
| index f62a2835fcca26a4e8a75f1ee2ef31d5e19486a0..2cf3a2e8eb95c4535a994b6a007f001988cd9090 100644 |
| --- a/src/hydrogen.cc |
| +++ b/src/hydrogen.cc |
| @@ -5286,10 +5286,20 @@ static bool LookupSetter(Handle<Map> map, |
| static bool IsFastLiteral(Handle<JSObject> boilerplate, |
| int max_depth, |
| int* max_properties, |
| - int* total_size) { |
| + int* total_size, |
| + bool allocation_sites_enabled) { |
|
danno
2013/02/08 13:44:38
Maybe also pass this boolean flag around as a Allo
mvstanton
2013/02/11 11:11:24
Done. This area felt a little awkward because I ha
|
| ASSERT(max_depth >= 0 && *max_properties >= 0); |
| if (max_depth == 0) return false; |
| + if (allocation_sites_enabled && boilerplate->IsJSArray()) { |
|
danno
2013/02/08 13:44:38
boilerplate->ShouldTrackAllocationInfo instead?, r
mvstanton
2013/02/11 11:11:24
It's helpful in other places in the code too, furt
|
| + ElementsKind value_elements_kind = boilerplate->GetElementsKind(); |
| + AllocationSiteMode mode = AllocationSiteInfo::GetMode( |
| + value_elements_kind); |
| + if (mode == TRACK_ALLOCATION_SITE) { |
| + *total_size += AllocationSiteInfo::kSize; |
| + } |
| + } |
| + |
| Handle<FixedArrayBase> elements(boilerplate->elements()); |
| if (elements->length() > 0 && |
| elements->map() != boilerplate->GetHeap()->fixed_cow_array_map()) { |
| @@ -5306,7 +5316,8 @@ static bool IsFastLiteral(Handle<JSObject> boilerplate, |
| if (!IsFastLiteral(value_object, |
| max_depth - 1, |
| max_properties, |
| - total_size)) { |
| + total_size, |
| + allocation_sites_enabled)) { |
| return false; |
| } |
| } |
| @@ -5330,7 +5341,8 @@ static bool IsFastLiteral(Handle<JSObject> boilerplate, |
| if (!IsFastLiteral(value_object, |
| max_depth - 1, |
| max_properties, |
| - total_size)) { |
| + total_size, |
| + allocation_sites_enabled)) { |
| return false; |
| } |
| } |
| @@ -5350,29 +5362,48 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
| HValue* context = environment()->LookupContext(); |
| HInstruction* literal; |
| + // We don't want to use AllocationSiteInfo when the object literal is |
| + // declared at global scope without a surrounding loop, that means it's |
| + // literal arrays will never be re-created, and therefore don't benefit from |
| + // site info. |
| + bool one_time_code = info()->scope()->is_global_scope() && |
| + current_block()->LoopNestingDepth() == 0; |
|
danno
2013/02/08 13:44:38
Maybe make this a predicate somewhere since you ca
mvstanton
2013/02/11 11:11:24
I made it a predicate on the FullCodeGenerator and
|
| + |
| + AllocationSiteMode mode = FLAG_track_allocation_sites && !one_time_code |
| + ? TRACK_ALLOCATION_SITE |
| + : DONT_TRACK_ALLOCATION_SITE; |
| + |
| // Check whether to use fast or slow deep-copying for boilerplate. |
| int total_size = 0; |
| int max_properties = HFastLiteral::kMaxLiteralProperties; |
| - Handle<Object> boilerplate(closure->literals()->get(expr->literal_index())); |
| - if (boilerplate->IsJSObject() && |
| - IsFastLiteral(Handle<JSObject>::cast(boilerplate), |
| + Handle<Object> original_boilerplate(closure->literals()->get( |
| + expr->literal_index())); |
| + if (original_boilerplate->IsJSObject() && |
| + IsFastLiteral(Handle<JSObject>::cast(original_boilerplate), |
| HFastLiteral::kMaxLiteralDepth, |
| &max_properties, |
| - &total_size)) { |
| - Handle<JSObject> boilerplate_object = Handle<JSObject>::cast(boilerplate); |
| + &total_size, |
| + mode == TRACK_ALLOCATION_SITE)) { |
| + // Copy the boilerplate to prevent unsavory sharing between fullcodegen and |
| + // crankshaft. |
| + Handle<JSObject> original_boilerplate_object = |
| + Handle<JSObject>::cast(original_boilerplate); |
| + Handle<JSObject> boilerplate = DeepCopy(original_boilerplate_object); |
| literal = new(zone()) HFastLiteral(context, |
| - boilerplate_object, |
| + boilerplate, |
| + original_boilerplate_object, |
| total_size, |
| expr->literal_index(), |
| expr->depth(), |
| - DONT_TRACK_ALLOCATION_SITE); |
| + mode); |
| } else { |
| literal = new(zone()) HObjectLiteral(context, |
| expr->constant_properties(), |
| expr->fast_elements(), |
| expr->literal_index(), |
| expr->depth(), |
| - expr->has_function()); |
| + expr->has_function(), |
| + mode); |
| } |
| // The object is expected in the bailout environment during computation |
| @@ -5457,9 +5488,15 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
| HValue* context = environment()->LookupContext(); |
| HInstruction* literal; |
| + bool one_time_code = info()->scope()->is_global_scope() && |
| + current_block()->LoopNestingDepth() == 0; |
|
danno
2013/02/08 13:44:38
predicate for this
mvstanton
2013/02/11 11:11:24
Done.
|
| + |
| + AllocationSiteMode mode = FLAG_track_allocation_sites && !one_time_code |
| + ? TRACK_ALLOCATION_SITE |
| + : DONT_TRACK_ALLOCATION_SITE; |
| + |
| Handle<FixedArray> literals(environment()->closure()->literals()); |
| Handle<Object> raw_boilerplate(literals->get(expr->literal_index())); |
| - |
| if (raw_boilerplate->IsUndefined()) { |
| raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate( |
| isolate(), literals, expr->constant_elements()); |
| @@ -5473,35 +5510,32 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
| } |
| } |
| - Handle<JSObject> boilerplate = Handle<JSObject>::cast(raw_boilerplate); |
| + Handle<JSObject> original_boilerplate = |
| + Handle<JSObject>::cast(raw_boilerplate); |
| ElementsKind boilerplate_elements_kind = |
| - Handle<JSObject>::cast(boilerplate)->GetElementsKind(); |
| - |
| - // TODO(mvstanton): This heuristic is only a temporary solution. In the |
| - // end, we want to quit creating allocation site info after a certain number |
| - // of GCs for a call site. |
| - AllocationSiteMode mode = AllocationSiteInfo::GetMode( |
| - boilerplate_elements_kind); |
| + original_boilerplate->GetElementsKind(); |
| // Check whether to use fast or slow deep-copying for boilerplate. |
| int total_size = 0; |
| int max_properties = HFastLiteral::kMaxLiteralProperties; |
| - if (IsFastLiteral(boilerplate, |
| + if (IsFastLiteral(original_boilerplate, |
| HFastLiteral::kMaxLiteralDepth, |
| &max_properties, |
| - &total_size)) { |
| - if (mode == TRACK_ALLOCATION_SITE) { |
| - total_size += AllocationSiteInfo::kSize; |
| - } |
| + &total_size, |
| + mode == TRACK_ALLOCATION_SITE)) { |
|
danno
2013/02/08 13:44:38
Pass mode rather than a boolean
mvstanton
2013/02/11 11:11:24
Done.
|
| + // Copy the boilerplate to prevent unsavory sharing between fullcodegen and |
| + // crankshaft. |
| + Handle<JSObject> boilerplate = DeepCopy(original_boilerplate); |
| literal = new(zone()) HFastLiteral(context, |
| boilerplate, |
| + original_boilerplate, |
| total_size, |
| expr->literal_index(), |
| expr->depth(), |
| mode); |
| } else { |
| literal = new(zone()) HArrayLiteral(context, |
| - boilerplate, |
| + original_boilerplate, |
| length, |
| expr->literal_index(), |
| expr->depth(), |