| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index db8de3f180325bb92a63af3c1408eeba2a484934..31f97f8ab6e2d415f04a381799da2bdca23a0027 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -30,6 +30,7 @@
|
| #include <algorithm>
|
|
|
| #include "v8.h"
|
| +#include "allocation-site-scopes.h"
|
| #include "codegen.h"
|
| #include "full-codegen.h"
|
| #include "hashmap.h"
|
| @@ -4349,6 +4350,9 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
|
| if (!boilerplate.is_null() &&
|
| IsFastLiteral(boilerplate, kMaxFastLiteralDepth, &max_properties)) {
|
| literal = BuildFastLiteral(boilerplate);
|
| + AllocationSiteContext site_context(isolate(), false);
|
| + AllocationSiteUsageScope site_scope(&site_context, site, boilerplate);
|
| + literal = BuildFastLiteral(boilerplate, &site_context);
|
| } else {
|
| NoObservableSideEffectsScope no_effects(this);
|
| Handle<FixedArray> closure_literals(closure->literals(), isolate());
|
| @@ -4463,8 +4467,12 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
|
| return Bailout(kArrayBoilerplateCreationFailed);
|
| }
|
|
|
| - site = isolate()->factory()->NewAllocationSite();
|
| - site->set_transition_info(*raw_boilerplate);
|
| + AllocationSiteContext site_context(isolate(), true);
|
| + AllocationSiteCreationScope site_scope(&site_context);
|
| + Handle<Object> same = JSObject::DeepWalk(
|
| + Handle<JSObject>::cast(raw_boilerplate), &site_context);
|
| + site = site_context.top();
|
| + site->set_transition_info(*same);
|
| literals->set(expr->literal_index(), *site);
|
|
|
| if (JSObject::cast(*raw_boilerplate)->elements()->map() ==
|
| @@ -4485,14 +4493,15 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
|
| ElementsKind boilerplate_elements_kind =
|
| Handle<JSObject>::cast(boilerplate_object)->GetElementsKind();
|
|
|
| - ASSERT(AllocationSite::CanTrack(boilerplate_object->map()->instance_type()));
|
| -
|
| // Check whether to use fast or slow deep-copying for boilerplate.
|
| int max_properties = kMaxFastLiteralProperties;
|
| if (IsFastLiteral(boilerplate_object,
|
| kMaxFastLiteralDepth,
|
| &max_properties)) {
|
| - literal = BuildFastLiteral(boilerplate_object);
|
| + AllocationSiteContext site_context(isolate(), false);
|
| + AllocationSiteUsageScope site_scope(&site_context, site,
|
| + boilerplate_object);
|
| + literal = BuildFastLiteral(boilerplate_object, &site_context);
|
| } else {
|
| NoObservableSideEffectsScope no_effects(this);
|
| // Boilerplate already exists and constant elements are never accessed,
|
| @@ -8413,7 +8422,8 @@ HInstruction* HOptimizedGraphBuilder::BuildThisFunction() {
|
|
|
|
|
| HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
|
| - Handle<JSObject> boilerplate_object) {
|
| + Handle<JSObject> boilerplate_object,
|
| + AllocationSiteContext* site_context) {
|
| NoObservableSideEffectsScope no_effects(this);
|
| InstanceType instance_type = boilerplate_object->map()->instance_type();
|
| ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE);
|
| @@ -8445,15 +8455,15 @@ HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
|
| }
|
| BuildInitElementsInObjectHeader(boilerplate_object, object, object_elements);
|
|
|
| -
|
| // Copy object elements if non-COW.
|
| if (object_elements != NULL) {
|
| - BuildEmitElements(boilerplate_object, elements, object_elements);
|
| + BuildEmitElements(boilerplate_object, elements, object_elements,
|
| + site_context);
|
| }
|
|
|
| // Copy in-object properties.
|
| if (boilerplate_object->map()->NumberOfFields() != 0) {
|
| - BuildEmitInObjectProperties(boilerplate_object, object);
|
| + BuildEmitInObjectProperties(boilerplate_object, object, site_context);
|
| }
|
| return object;
|
| }
|
| @@ -8505,7 +8515,8 @@ void HOptimizedGraphBuilder::BuildInitElementsInObjectHeader(
|
|
|
| void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
|
| Handle<JSObject> boilerplate_object,
|
| - HInstruction* object) {
|
| + HInstruction* object,
|
| + AllocationSiteContext* site_context) {
|
| Handle<DescriptorArray> descriptors(
|
| boilerplate_object->map()->instance_descriptors());
|
| int limit = boilerplate_object->map()->NumberOfOwnDescriptors();
|
| @@ -8528,8 +8539,10 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
|
| HObjectAccess::ForJSObjectOffset(property_offset);
|
|
|
| if (value->IsJSObject()) {
|
| + AllocationSiteUsageScope site_scope(site_context, value);
|
| Handle<JSObject> value_object = Handle<JSObject>::cast(value);
|
| - HInstruction* result = BuildFastLiteral(value_object);
|
| + HInstruction* result =
|
| + BuildFastLiteral(value_object, site_context);
|
| Add<HStoreNamedField>(object, access, result);
|
| } else {
|
| Representation representation = details.representation();
|
| @@ -8538,6 +8551,12 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
|
| if (representation.IsDouble()) {
|
| // Allocate a HeapNumber box and store the value into it.
|
| HValue* heap_number_constant = Add<HConstant>(HeapNumber::kSize);
|
| + // TODO(mvstanton): This heap number alloc does not have a corresponding
|
| + // AllocationSite. That is okay because
|
| + // 1) it's a child object of another object with a valid allocation site
|
| + // 2) we can just use the mode of the parent object for pretenuring
|
| + // The todo is replace GetPretenureMode() with
|
| + // site_context->top()->GetPretenureMode().
|
| HInstruction* double_box =
|
| Add<HAllocate>(heap_number_constant, HType::HeapNumber(),
|
| isolate()->heap()->GetPretenureMode(), HEAP_NUMBER_TYPE);
|
| @@ -8567,7 +8586,8 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
|
| void HOptimizedGraphBuilder::BuildEmitElements(
|
| Handle<JSObject> boilerplate_object,
|
| Handle<FixedArrayBase> elements,
|
| - HValue* object_elements) {
|
| + HValue* object_elements,
|
| + AllocationSiteContext* site_context) {
|
| ElementsKind kind = boilerplate_object->map()->elements_kind();
|
| int elements_length = elements->length();
|
| HValue* object_elements_length = Add<HConstant>(elements_length);
|
| @@ -8577,7 +8597,8 @@ void HOptimizedGraphBuilder::BuildEmitElements(
|
| if (elements->IsFixedDoubleArray()) {
|
| BuildEmitFixedDoubleArray(elements, kind, object_elements);
|
| } else if (elements->IsFixedArray()) {
|
| - BuildEmitFixedArray(elements, kind, object_elements);
|
| + BuildEmitFixedArray(elements, kind, object_elements,
|
| + site_context);
|
| } else {
|
| UNREACHABLE();
|
| }
|
| @@ -8606,7 +8627,8 @@ void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray(
|
| void HOptimizedGraphBuilder::BuildEmitFixedArray(
|
| Handle<FixedArrayBase> elements,
|
| ElementsKind kind,
|
| - HValue* object_elements) {
|
| + HValue* object_elements,
|
| + AllocationSiteContext* site_context) {
|
| HInstruction* boilerplate_elements = Add<HConstant>(elements);
|
| int elements_length = elements->length();
|
| Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements);
|
| @@ -8614,8 +8636,10 @@ void HOptimizedGraphBuilder::BuildEmitFixedArray(
|
| Handle<Object> value(fast_elements->get(i), isolate());
|
| HValue* key_constant = Add<HConstant>(i);
|
| if (value->IsJSObject()) {
|
| + AllocationSiteUsageScope site_scope(site_context, value);
|
| Handle<JSObject> value_object = Handle<JSObject>::cast(value);
|
| - HInstruction* result = BuildFastLiteral(value_object);
|
| + HInstruction* result =
|
| + BuildFastLiteral(value_object, site_context);
|
| Add<HStoreKeyed>(object_elements, key_constant, result, kind);
|
| } else {
|
| HInstruction* value_instruction =
|
|
|