| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index 33557a29f2e77314f0730606c1a0af671648984c..71590aea79f043d88537fd06f7ff0bb590da61c0 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -9946,28 +9946,46 @@ HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
|
| int pointer_size,
|
| AllocationSiteMode mode) {
|
| Zone* zone = this->zone();
|
| - int total_size = data_size + pointer_size;
|
| -
|
| NoObservableSideEffectsScope no_effects(this);
|
|
|
| - HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE;
|
| - // TODO(hpayer): add support for old data space
|
| - if (isolate()->heap()->ShouldGloballyPretenure() &&
|
| - data_size == 0) {
|
| - flags = static_cast<HAllocate::Flags>(
|
| - flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE);
|
| + HInstruction* target = NULL;
|
| + HInstruction* data_target = NULL;
|
| +
|
| + HAllocate::Flags flags = HAllocate::DefaultFlags();
|
| +
|
| + if (isolate()->heap()->ShouldGloballyPretenure()) {
|
| + if (data_size != 0) {
|
| + HAllocate::Flags data_flags =
|
| + static_cast<HAllocate::Flags>(HAllocate::DefaultFlags() |
|
| + HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE);
|
| + HValue* size_in_bytes = AddInstruction(new(zone) HConstant(data_size));
|
| + data_target = AddInstruction(new(zone) HAllocate(
|
| + context, size_in_bytes, HType::JSObject(), data_flags));
|
| + Handle<Map> free_space_map = isolate()->factory()->free_space_map();
|
| + AddStoreMapConstant(data_target, free_space_map);
|
| + HObjectAccess access =
|
| + HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset);
|
| + AddStore(data_target, access, size_in_bytes);
|
| + }
|
| + if (pointer_size != 0) {
|
| + flags = static_cast<HAllocate::Flags>(
|
| + flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE);
|
| + HValue* size_in_bytes = AddInstruction(new(zone) HConstant(pointer_size));
|
| + target = AddInstruction(new(zone) HAllocate(context,
|
| + size_in_bytes, HType::JSObject(), flags));
|
| + }
|
| + } else {
|
| + HValue* size_in_bytes =
|
| + AddInstruction(new(zone) HConstant(data_size + pointer_size));
|
| + target = AddInstruction(new(zone) HAllocate(context, size_in_bytes,
|
| + HType::JSObject(), flags));
|
| }
|
|
|
| - HValue* size_in_bytes = AddInstruction(new(zone) HConstant(total_size));
|
| - HInstruction* result =
|
| - AddInstruction(new(zone) HAllocate(context,
|
| - size_in_bytes,
|
| - HType::JSObject(),
|
| - flags));
|
| int offset = 0;
|
| - BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object, result,
|
| - &offset, mode);
|
| - return result;
|
| + int data_offset = 0;
|
| + BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object, target,
|
| + &offset, data_target, &data_offset, mode);
|
| + return target;
|
| }
|
|
|
|
|
| @@ -9976,6 +9994,8 @@ void HOptimizedGraphBuilder::BuildEmitDeepCopy(
|
| Handle<JSObject> original_boilerplate_object,
|
| HInstruction* target,
|
| int* offset,
|
| + HInstruction* data_target,
|
| + int* data_offset,
|
| AllocationSiteMode mode) {
|
| Zone* zone = this->zone();
|
|
|
| @@ -9984,30 +10004,38 @@ void HOptimizedGraphBuilder::BuildEmitDeepCopy(
|
| original_boilerplate_object->elements());
|
| ElementsKind kind = boilerplate_object->map()->elements_kind();
|
|
|
| - // Increase the offset so that subsequent objects end up right after
|
| - // this object and its backing store.
|
| int object_offset = *offset;
|
| int object_size = boilerplate_object->map()->instance_size();
|
| int elements_size = (elements->length() > 0 &&
|
| elements->map() != isolate()->heap()->fixed_cow_array_map()) ?
|
| elements->Size() : 0;
|
| - int elements_offset = *offset + object_size;
|
| + int elements_offset = 0;
|
|
|
| - *offset += object_size + elements_size;
|
| + if (data_target != NULL && boilerplate_object->HasFastDoubleElements()) {
|
| + elements_offset = *data_offset;
|
| + *data_offset += elements_size;
|
| + } else {
|
| + // Place elements right after this object.
|
| + elements_offset = *offset + object_size;
|
| + *offset += elements_size;
|
| + }
|
| + // Increase the offset so that subsequent objects end up right after this
|
| + // object (and it's elements if they are allocated in the same space).
|
| + *offset += object_size;
|
|
|
| // Copy object elements if non-COW.
|
| HValue* object_elements = BuildEmitObjectHeader(boilerplate_object, target,
|
| - object_offset, elements_offset, elements_size);
|
| + data_target, object_offset, elements_offset, elements_size);
|
| if (object_elements != NULL) {
|
| BuildEmitElements(elements, original_elements, kind, object_elements,
|
| - target, offset);
|
| + target, offset, data_target, data_offset);
|
| }
|
|
|
| // Copy in-object properties.
|
| HValue* object_properties =
|
| AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset));
|
| BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object,
|
| - object_properties, target, offset);
|
| + object_properties, target, offset, data_target, data_offset);
|
|
|
| // Create allocation site info.
|
| if (mode == TRACK_ALLOCATION_SITE &&
|
| @@ -10024,6 +10052,7 @@ void HOptimizedGraphBuilder::BuildEmitDeepCopy(
|
| HValue* HOptimizedGraphBuilder::BuildEmitObjectHeader(
|
| Handle<JSObject> boilerplate_object,
|
| HInstruction* target,
|
| + HInstruction* data_target,
|
| int object_offset,
|
| int elements_offset,
|
| int elements_size) {
|
| @@ -10042,8 +10071,13 @@ HValue* HOptimizedGraphBuilder::BuildEmitObjectHeader(
|
| Handle<Object>(boilerplate_object->elements(), isolate());
|
| elements = AddInstruction(new(zone) HConstant(elements_field));
|
| } else {
|
| - elements = AddInstruction(new(zone) HInnerAllocatedObject(
|
| - target, elements_offset));
|
| + if (data_target != NULL && boilerplate_object->HasFastDoubleElements()) {
|
| + elements = AddInstruction(new(zone) HInnerAllocatedObject(
|
| + data_target, elements_offset));
|
| + } else {
|
| + elements = AddInstruction(new(zone) HInnerAllocatedObject(
|
| + target, elements_offset));
|
| + }
|
| result = elements;
|
| }
|
| AddStore(object_header, HObjectAccess::ForElementsPointer(), elements);
|
| @@ -10080,7 +10114,9 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
|
| Handle<JSObject> original_boilerplate_object,
|
| HValue* object_properties,
|
| HInstruction* target,
|
| - int* offset) {
|
| + int* offset,
|
| + HInstruction* data_target,
|
| + int* data_offset) {
|
| Zone* zone = this->zone();
|
| Handle<DescriptorArray> descriptors(
|
| boilerplate_object->map()->instance_descriptors());
|
| @@ -10114,7 +10150,7 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
|
| AddStore(object_properties, access, value_instruction);
|
|
|
| BuildEmitDeepCopy(value_object, original_value_object, target,
|
| - offset, DONT_TRACK_ALLOCATION_SITE);
|
| + offset, data_target, data_offset, DONT_TRACK_ALLOCATION_SITE);
|
| } else {
|
| Representation representation = details.representation();
|
| HInstruction* value_instruction =
|
| @@ -10122,14 +10158,21 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
|
|
|
| if (representation.IsDouble()) {
|
| // Allocate a HeapNumber box and store the value into it.
|
| - HInstruction* double_box =
|
| - AddInstruction(new(zone) HInnerAllocatedObject(target, *offset));
|
| + HInstruction* double_box;
|
| + if (data_target != NULL) {
|
| + double_box = AddInstruction(new(zone) HInnerAllocatedObject(
|
| + data_target, *data_offset));
|
| + *data_offset += HeapNumber::kSize;
|
| + } else {
|
| + double_box = AddInstruction(new(zone) HInnerAllocatedObject(
|
| + target, *offset));
|
| + *offset += HeapNumber::kSize;
|
| + }
|
| AddStoreMapConstant(double_box,
|
| isolate()->factory()->heap_number_map());
|
| AddStore(double_box, HObjectAccess::ForHeapNumberValue(),
|
| value_instruction, Representation::Double());
|
| value_instruction = double_box;
|
| - *offset += HeapNumber::kSize;
|
| }
|
|
|
| AddStore(object_properties, access, value_instruction);
|
| @@ -10154,7 +10197,9 @@ void HOptimizedGraphBuilder::BuildEmitElements(
|
| ElementsKind kind,
|
| HValue* object_elements,
|
| HInstruction* target,
|
| - int* offset) {
|
| + int* offset,
|
| + HInstruction* data_target,
|
| + int* data_offset) {
|
| Zone* zone = this->zone();
|
|
|
| int elements_length = elements->length();
|
| @@ -10168,7 +10213,7 @@ void HOptimizedGraphBuilder::BuildEmitElements(
|
| BuildEmitFixedDoubleArray(elements, kind, object_elements);
|
| } else if (elements->IsFixedArray()) {
|
| BuildEmitFixedArray(elements, original_elements, kind, object_elements,
|
| - target, offset);
|
| + target, offset, data_target, data_offset);
|
| } else {
|
| UNREACHABLE();
|
| }
|
| @@ -10201,7 +10246,9 @@ void HOptimizedGraphBuilder::BuildEmitFixedArray(
|
| ElementsKind kind,
|
| HValue* object_elements,
|
| HInstruction* target,
|
| - int* offset) {
|
| + int* offset,
|
| + HInstruction* data_target,
|
| + int* data_offset) {
|
| Zone* zone = this->zone();
|
| HInstruction* boilerplate_elements =
|
| AddInstruction(new(zone) HConstant(elements));
|
| @@ -10221,7 +10268,7 @@ void HOptimizedGraphBuilder::BuildEmitFixedArray(
|
| AddInstruction(new(zone) HStoreKeyed(
|
| object_elements, key_constant, value_instruction, kind));
|
| BuildEmitDeepCopy(value_object, original_value_object, target,
|
| - offset, DONT_TRACK_ALLOCATION_SITE);
|
| + offset, data_target, data_offset, DONT_TRACK_ALLOCATION_SITE);
|
| } else {
|
| HInstruction* value_instruction =
|
| AddInstruction(new(zone) HLoadKeyed(
|
|
|