| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index 8da0e82183e912e666bb36fc2b638cf8c40a44f6..2c3059a44d8671fc5ec2f4bd7d82ed38a3b75091 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -1597,6 +1597,7 @@ void HGraphBuilder::BuildCopyElements(HValue* context,
|
|
|
| HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context,
|
| HValue* boilerplate,
|
| + HValue* allocation_site,
|
| AllocationSiteMode mode,
|
| ElementsKind kind,
|
| int length) {
|
| @@ -1633,7 +1634,7 @@ HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context,
|
|
|
| // Create an allocation site info if requested.
|
| if (mode == TRACK_ALLOCATION_SITE) {
|
| - BuildCreateAllocationSiteInfo(object, JSArray::kSize, boilerplate);
|
| + BuildCreateAllocationSiteInfo(object, JSArray::kSize, allocation_site);
|
| }
|
|
|
| if (length > 0) {
|
| @@ -1740,14 +1741,16 @@ void HGraphBuilder::BuildCompareNil(
|
|
|
| HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object,
|
| int previous_object_size,
|
| - HValue* payload) {
|
| - HInnerAllocatedObject* alloc_site = Add<HInnerAllocatedObject>(
|
| + HValue* alloc_site) {
|
| + ASSERT(alloc_site != NULL);
|
| + HInnerAllocatedObject* alloc_site_info = Add<HInnerAllocatedObject>(
|
| previous_object, previous_object_size);
|
| - Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map());
|
| - AddStoreMapConstant(alloc_site, alloc_site_map);
|
| - HObjectAccess access = HObjectAccess::ForAllocationSitePayload();
|
| - AddStore(alloc_site, access, payload);
|
| - return alloc_site;
|
| + Handle<Map> alloc_site_info_map(
|
| + isolate()->heap()->allocation_site_info_map());
|
| + AddStoreMapConstant(alloc_site_info, alloc_site_info_map);
|
| + HObjectAccess access = HObjectAccess::ForAllocationSiteInfoSite();
|
| + AddStore(alloc_site_info, access, alloc_site);
|
| + return alloc_site_info;
|
| }
|
|
|
|
|
| @@ -1780,7 +1783,7 @@ HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder,
|
| constructor_function_(constructor_function) {
|
| mode_ = override_mode == DISABLE_ALLOCATION_SITES
|
| ? DONT_TRACK_ALLOCATION_SITE
|
| - : AllocationSiteInfo::GetMode(kind);
|
| + : AllocationSite::GetMode(kind);
|
| }
|
|
|
|
|
| @@ -4524,6 +4527,7 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
|
| literal = BuildFastLiteral(context,
|
| boilerplate_object,
|
| original_boilerplate_object,
|
| + Handle<Object>::null(),
|
| data_size,
|
| pointer_size,
|
| DONT_TRACK_ALLOCATION_SITE);
|
| @@ -4631,25 +4635,37 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
|
| HValue* context = environment()->LookupContext();
|
| HInstruction* literal;
|
|
|
| + Handle<AllocationSite> site;
|
| Handle<FixedArray> literals(environment()->closure()->literals(), isolate());
|
| - Handle<Object> raw_boilerplate(literals->get(expr->literal_index()),
|
| - isolate());
|
| -
|
| bool uninitialized = false;
|
| - if (raw_boilerplate->IsUndefined()) {
|
| + Handle<Object> literals_cell(literals->get(expr->literal_index()),
|
| + isolate());
|
| + Handle<Object> raw_boilerplate;
|
| + if (literals_cell->IsUndefined()) {
|
| uninitialized = true;
|
| raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate(
|
| isolate(), literals, expr->constant_elements());
|
| if (raw_boilerplate.is_null()) {
|
| return Bailout("array boilerplate creation failed");
|
| }
|
| - literals->set(expr->literal_index(), *raw_boilerplate);
|
| +
|
| + site = isolate()->factory()->NewAllocationSite();
|
| + site->set_payload(*raw_boilerplate);
|
| + literals->set(expr->literal_index(), *site);
|
| +
|
| if (JSObject::cast(*raw_boilerplate)->elements()->map() ==
|
| isolate()->heap()->fixed_cow_array_map()) {
|
| isolate()->counters()->cow_arrays_created_runtime()->Increment();
|
| }
|
| + } else {
|
| + ASSERT(literals_cell->IsAllocationSite());
|
| + site = Handle<AllocationSite>::cast(literals_cell);
|
| + raw_boilerplate = Handle<Object>(site->payload(), isolate());
|
| }
|
|
|
| + ASSERT(!raw_boilerplate.is_null());
|
| + ASSERT(site->IsLiteralSite());
|
| +
|
| Handle<JSObject> original_boilerplate_object =
|
| Handle<JSObject>::cast(raw_boilerplate);
|
| ElementsKind boilerplate_elements_kind =
|
| @@ -4658,7 +4674,7 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
|
| // 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(
|
| + AllocationSiteMode mode = AllocationSite::GetMode(
|
| boilerplate_elements_kind);
|
|
|
| // Check whether to use fast or slow deep-copying for boilerplate.
|
| @@ -4678,6 +4694,7 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
|
| literal = BuildFastLiteral(context,
|
| boilerplate_object,
|
| original_boilerplate_object,
|
| + site,
|
| data_size,
|
| pointer_size,
|
| mode);
|
| @@ -8504,6 +8521,7 @@ HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
|
| HValue* context,
|
| Handle<JSObject> boilerplate_object,
|
| Handle<JSObject> original_boilerplate_object,
|
| + Handle<Object> allocation_site,
|
| int data_size,
|
| int pointer_size,
|
| AllocationSiteMode mode) {
|
| @@ -8541,8 +8559,9 @@ HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
|
|
|
| int offset = 0;
|
| int data_offset = 0;
|
| - BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object, target,
|
| - &offset, data_target, &data_offset, mode);
|
| + BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object,
|
| + allocation_site, target, &offset, data_target,
|
| + &data_offset, mode);
|
| return target;
|
| }
|
|
|
| @@ -8550,11 +8569,30 @@ HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
|
| void HOptimizedGraphBuilder::BuildEmitDeepCopy(
|
| Handle<JSObject> boilerplate_object,
|
| Handle<JSObject> original_boilerplate_object,
|
| + Handle<Object> allocation_site_object,
|
| HInstruction* target,
|
| int* offset,
|
| HInstruction* data_target,
|
| int* data_offset,
|
| AllocationSiteMode mode) {
|
| + Zone* zone = this->zone();
|
| +
|
| + bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE &&
|
| + boilerplate_object->map()->CanTrackAllocationSite();
|
| +
|
| + // If using allocation sites, then the payload on the site should already
|
| + // be filled in as a valid (boilerplate) array.
|
| + ASSERT(!create_allocation_site_info ||
|
| + AllocationSite::cast(*allocation_site_object)->IsLiteralSite());
|
| +
|
| + HInstruction* allocation_site = NULL;
|
| +
|
| + if (create_allocation_site_info) {
|
| + allocation_site = AddInstruction(new(zone) HConstant(
|
| + allocation_site_object, Representation::Tagged()));
|
| + }
|
| +
|
| + // Only elements backing stores for non-COW arrays need to be copied.
|
| Handle<FixedArrayBase> elements(boilerplate_object->elements());
|
| Handle<FixedArrayBase> original_elements(
|
| original_boilerplate_object->elements());
|
| @@ -8600,9 +8638,7 @@ void HOptimizedGraphBuilder::BuildEmitDeepCopy(
|
| boilerplate_object->map()->CanTrackAllocationSite()) {
|
| elements_offset += AllocationSiteInfo::kSize;
|
| *offset += AllocationSiteInfo::kSize;
|
| - HInstruction* original_boilerplate =
|
| - Add<HConstant>(original_boilerplate_object);
|
| - BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate);
|
| + BuildCreateAllocationSiteInfo(target, JSArray::kSize, allocation_site);
|
| }
|
| }
|
|
|
| @@ -8700,9 +8736,10 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
|
| *offset);
|
|
|
| AddStore(object_properties, access, value_instruction);
|
| -
|
| - BuildEmitDeepCopy(value_object, original_value_object, target,
|
| - offset, data_target, data_offset, DONT_TRACK_ALLOCATION_SITE);
|
| + BuildEmitDeepCopy(value_object, original_value_object,
|
| + Handle<Object>::null(), target,
|
| + offset, data_target, data_offset,
|
| + DONT_TRACK_ALLOCATION_SITE);
|
| } else {
|
| Representation representation = details.representation();
|
| HInstruction* value_instruction = Add<HConstant>(value);
|
| @@ -8809,8 +8846,10 @@ void HOptimizedGraphBuilder::BuildEmitFixedArray(
|
| HInstruction* value_instruction = Add<HInnerAllocatedObject>(target,
|
| *offset);
|
| Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind);
|
| - BuildEmitDeepCopy(value_object, original_value_object, target,
|
| - offset, data_target, data_offset, DONT_TRACK_ALLOCATION_SITE);
|
| + BuildEmitDeepCopy(value_object, original_value_object,
|
| + Handle<Object>::null(), target,
|
| + offset, data_target, data_offset,
|
| + DONT_TRACK_ALLOCATION_SITE);
|
| } else {
|
| HInstruction* value_instruction =
|
| Add<HLoadKeyed>(boilerplate_elements, key_constant,
|
|
|