| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index ae97d5e4a81e56965e38fb5868f58deae06025e6..ac0502abfbd1352090ba60f809036e7e6a3ef912 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -5682,11 +5682,19 @@ static bool LookupSetter(Handle<Map> map,
|
| static bool IsFastLiteral(Handle<JSObject> boilerplate,
|
| int max_depth,
|
| int* max_properties,
|
| - int* total_size) {
|
| + int* total_size,
|
| + int* allocation_sites_count,
|
| + AllocationSiteMode mode) {
|
| ASSERT(max_depth >= 0 && *max_properties >= 0);
|
| if (max_depth == 0) return false;
|
|
|
| Isolate* isolate = boilerplate->GetIsolate();
|
| + if (mode == TRACK_ALLOCATION_SITE &&
|
| + boilerplate->ShouldTrackAllocationInfo()) {
|
| + *total_size += AllocationSiteInfo::kSize;
|
| + *allocation_sites_count = *allocation_sites_count + 1;
|
| + }
|
| +
|
| Handle<FixedArrayBase> elements(boilerplate->elements());
|
| if (elements->length() > 0 &&
|
| elements->map() != isolate->heap()->fixed_cow_array_map()) {
|
| @@ -5703,7 +5711,9 @@ static bool IsFastLiteral(Handle<JSObject> boilerplate,
|
| if (!IsFastLiteral(value_object,
|
| max_depth - 1,
|
| max_properties,
|
| - total_size)) {
|
| + total_size,
|
| + allocation_sites_count,
|
| + mode)) {
|
| return false;
|
| }
|
| }
|
| @@ -5727,7 +5737,9 @@ static bool IsFastLiteral(Handle<JSObject> boilerplate,
|
| if (!IsFastLiteral(value_object,
|
| max_depth - 1,
|
| max_properties,
|
| - total_size)) {
|
| + total_size,
|
| + allocation_sites_count,
|
| + mode)) {
|
| return false;
|
| }
|
| }
|
| @@ -5747,30 +5759,50 @@ 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.
|
| + AllocationSiteMode mode = FLAG_track_allocation_sites && !IsOneTimeCode()
|
| + ? TRACK_ALLOCATION_SITE
|
| + : DONT_TRACK_ALLOCATION_SITE;
|
| +
|
| // Check whether to use fast or slow deep-copying for boilerplate.
|
| int total_size = 0;
|
| + int allocation_sites_count = 0;
|
| int max_properties = HFastLiteral::kMaxLiteralProperties;
|
| - Handle<Object> boilerplate(closure->literals()->get(expr->literal_index()),
|
| - isolate());
|
| - if (boilerplate->IsJSObject() &&
|
| - IsFastLiteral(Handle<JSObject>::cast(boilerplate),
|
| + Handle<Object> original_boilerplate(closure->literals()->get(
|
| + expr->literal_index()), isolate());
|
| + 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,
|
| + &allocation_sites_count,
|
| + mode)) {
|
| + // 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);
|
| + int size_without_allocation_sites = total_size -
|
| + allocation_sites_count * AllocationSiteInfo::kSize;
|
| literal = new(zone()) HFastLiteral(context,
|
| - boilerplate_object,
|
| + boilerplate,
|
| + original_boilerplate_object,
|
| total_size,
|
| expr->literal_index(),
|
| expr->depth(),
|
| - DONT_TRACK_ALLOCATION_SITE);
|
| + mode,
|
| + size_without_allocation_sites);
|
| } 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
|
| @@ -5855,10 +5887,13 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
|
| HValue* context = environment()->LookupContext();
|
| HInstruction* literal;
|
|
|
| + AllocationSiteMode mode = FLAG_track_allocation_sites && !IsOneTimeCode()
|
| + ? TRACK_ALLOCATION_SITE
|
| + : DONT_TRACK_ALLOCATION_SITE;
|
| +
|
| Handle<FixedArray> literals(environment()->closure()->literals());
|
| Handle<Object> raw_boilerplate(literals->get(expr->literal_index()),
|
| isolate());
|
| -
|
| if (raw_boilerplate->IsUndefined()) {
|
| raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate(
|
| isolate(), literals, expr->constant_elements());
|
| @@ -5872,35 +5907,37 @@ 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 allocation_sites_count = 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,
|
| + &allocation_sites_count,
|
| + mode)) {
|
| + // Copy the boilerplate to prevent unsavory sharing between fullcodegen and
|
| + // crankshaft.
|
| + int size_without_allocation_sites = total_size -
|
| + allocation_sites_count * AllocationSiteInfo::kSize;
|
| + Handle<JSObject> boilerplate = DeepCopy(original_boilerplate);
|
| literal = new(zone()) HFastLiteral(context,
|
| boilerplate,
|
| + original_boilerplate,
|
| total_size,
|
| expr->literal_index(),
|
| expr->depth(),
|
| - mode);
|
| + mode,
|
| + size_without_allocation_sites);
|
| } else {
|
| literal = new(zone()) HArrayLiteral(context,
|
| - boilerplate,
|
| + original_boilerplate,
|
| length,
|
| expr->literal_index(),
|
| expr->depth(),
|
|
|