Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(420)

Unified Diff: src/hydrogen.cc

Issue 61463005: Supported folding of constant size allocation followed by dynamic size allocation. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Allocation folding of const + dynamic sizes case. Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 33586f347ef85a5911c5315a963c23e3f2c55188..32b64a128728e505ace39b78914c9ce709bc91ab 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -1909,29 +1909,43 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
}
-HValue* HGraphBuilder::BuildAllocateElements(ElementsKind kind,
- HValue* capacity) {
- int elements_size;
- InstanceType instance_type;
+HValue* HGraphBuilder::BuildCalculateElementsSize(ElementsKind kind,
+ HValue* capacity) {
+ HValue* actual_capacity = capacity->ActualValue();
+
+ if (actual_capacity->IsInteger32Constant()) {
+ int length = HConstant::cast(actual_capacity)->GetInteger32Constant();
+ int base_size = IsFastDoubleElementsKind(kind)
+ ? FixedDoubleArray::SizeFor(length)
+ : FixedArray::SizeFor(length);
+
+ return Add<HConstant>(base_size);
- if (IsFastDoubleElementsKind(kind)) {
- elements_size = kDoubleSize;
- instance_type = FIXED_DOUBLE_ARRAY_TYPE;
} else {
- elements_size = kPointerSize;
- instance_type = FIXED_ARRAY_TYPE;
- }
+ int elements_size = IsFastDoubleElementsKind(kind)
mvstanton 2013/11/14 10:04:20 I just ran into a similar situation. Constant-fold
Igor Sheludko 2013/11/27 12:52:01 On 2013/11/14 10:04:20, mvstanton wrote: Ok, I rem
+ ? kDoubleSize
+ : kPointerSize;
+
+ HConstant* elements_size_value = Add<HConstant>(elements_size);
+ HValue* mul = Add<HMul>(capacity, elements_size_value);
+ mul->ClearFlag(HValue::kCanOverflow);
- HConstant* elements_size_value = Add<HConstant>(elements_size);
- HValue* mul = Add<HMul>(capacity, elements_size_value);
- mul->ClearFlag(HValue::kCanOverflow);
+ HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize);
+ HValue* total_size = Add<HAdd>(mul, header_size);
+ total_size->ClearFlag(HValue::kCanOverflow);
+ return total_size;
+ }
+}
- HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize);
- HValue* total_size = Add<HAdd>(mul, header_size);
- total_size->ClearFlag(HValue::kCanOverflow);
+HValue* HGraphBuilder::BuildAllocateElements(ElementsKind kind,
+ HValue* size_in_bytes,
+ PretenureFlag pretenure) {
+ InstanceType instance_type = IsFastDoubleElementsKind(kind)
+ ? FIXED_DOUBLE_ARRAY_TYPE
+ : FIXED_ARRAY_TYPE;
- return Add<HAllocate>(total_size, HType::JSArray(),
- isolate()->heap()->GetPretenureMode(), instance_type);
+ return Add<HAllocate>(size_in_bytes, HType::JSArray(),
+ pretenure, instance_type);
}
@@ -1955,43 +1969,39 @@ HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader(
// The HForceRepresentation is to prevent possible deopt on int-smi
// conversion after allocation but before the new object fields are set.
capacity = Add<HForceRepresentation>(capacity, Representation::Smi());
- HValue* new_elements = BuildAllocateElements(kind, capacity);
+ HValue* size_in_bytes = BuildCalculateElementsSize(kind, capacity);
+ HValue* new_elements = BuildAllocateElements(
+ kind, size_in_bytes, isolate()->heap()->GetPretenureMode());
BuildInitializeElementsHeader(new_elements, kind, capacity);
return new_elements;
}
-HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array,
- HValue* array_map,
- AllocationSiteMode mode,
- ElementsKind elements_kind,
- HValue* allocation_site_payload,
- HValue* length_field) {
-
+void HGraphBuilder::BuildJSArrayHeader(HValue* array,
+ HValue* array_map,
+ AllocationSiteMode mode,
+ ElementsKind elements_kind,
+ HValue* allocation_site_payload,
+ HValue* length_field) {
Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map);
HConstant* empty_fixed_array =
Add<HConstant>(isolate()->factory()->empty_fixed_array());
- HObjectAccess access = HObjectAccess::ForPropertiesPointer();
- Add<HStoreNamedField>(array, access, empty_fixed_array);
- Add<HStoreNamedField>(array, HObjectAccess::ForArrayLength(elements_kind),
- length_field);
+ Add<HStoreNamedField>(
+ array, HObjectAccess::ForPropertiesPointer(), empty_fixed_array);
+
+ Add<HStoreNamedField>(
+ array, HObjectAccess::ForElementsPointer(), empty_fixed_array);
+
+ Add<HStoreNamedField>(
+ array, HObjectAccess::ForArrayLength(elements_kind), length_field);
if (mode == TRACK_ALLOCATION_SITE) {
BuildCreateAllocationMemento(array,
JSArray::kSize,
allocation_site_payload);
}
-
- int elements_location = JSArray::kSize;
- if (mode == TRACK_ALLOCATION_SITE) {
- elements_location += AllocationMemento::kSize;
- }
-
- HValue* elements = Add<HInnerAllocatedObject>(array, elements_location);
- Add<HStoreNamedField>(array, HObjectAccess::ForElementsPointer(), elements);
- return static_cast<HInnerAllocatedObject*>(elements);
}
@@ -2406,66 +2416,26 @@ HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() {
}
-HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize(
- HValue* length_node) {
- ASSERT(length_node != NULL);
-
+HValue* HGraphBuilder::JSArrayBuilder::EstablishHeaderAllocationSize() {
int base_size = JSArray::kSize;
if (mode_ == TRACK_ALLOCATION_SITE) {
base_size += AllocationMemento::kSize;
}
-
- STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize);
- base_size += FixedArray::kHeaderSize;
-
- HInstruction* elements_size_value =
- builder()->Add<HConstant>(elements_size());
- HInstruction* mul = builder()->Add<HMul>(length_node, elements_size_value);
- mul->ClearFlag(HValue::kCanOverflow);
-
- HInstruction* base = builder()->Add<HConstant>(base_size);
- HInstruction* total_size = builder()->Add<HAdd>(base, mul);
- total_size->ClearFlag(HValue::kCanOverflow);
- return total_size;
-}
-
-
-HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() {
- int base_size = JSArray::kSize;
- if (mode_ == TRACK_ALLOCATION_SITE) {
- base_size += AllocationMemento::kSize;
- }
-
- base_size += IsFastDoubleElementsKind(kind_)
- ? FixedDoubleArray::SizeFor(initial_capacity())
- : FixedArray::SizeFor(initial_capacity());
-
return builder()->Add<HConstant>(base_size);
}
HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() {
- HValue* size_in_bytes = EstablishEmptyArrayAllocationSize();
HConstant* capacity = builder()->Add<HConstant>(initial_capacity());
- return AllocateArray(size_in_bytes,
- capacity,
- builder()->graph()->GetConstant0(),
- true);
+ return AllocateArray(capacity,
+ builder()->graph()->GetConstant0(),
+ true);
}
HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity,
HValue* length_field,
bool fill_with_hole) {
- HValue* size_in_bytes = EstablishAllocationSize(capacity);
- return AllocateArray(size_in_bytes, capacity, length_field, fill_with_hole);
-}
-
-
-HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
- HValue* capacity,
- HValue* length_field,
- bool fill_with_hole) {
// These HForceRepresentations are because we store these as fields in the
// objects we construct, and an int32-to-smi HChange could deopt. Accept
// the deopt possibility now, before allocation occurs.
@@ -2473,15 +2443,16 @@ HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
Representation::Smi());
length_field = builder()->Add<HForceRepresentation>(length_field,
Representation::Smi());
+
+ // Generate size calculation code here in order to make it dominate
+ // the JSArray allocation.
mvstanton 2013/11/14 10:04:20 Nice.
Igor Sheludko 2013/11/27 12:52:01 Done.
+ HValue* elms_size = builder()->BuildCalculateElementsSize(kind_, capacity);
+
// Allocate (dealing with failure appropriately)
- HAllocate* new_object = builder()->Add<HAllocate>(size_in_bytes,
+ HValue* array_object_size = EstablishHeaderAllocationSize();
+ HAllocate* array_object = builder()->Add<HAllocate>(array_object_size,
HType::JSArray(), NOT_TENURED, JS_ARRAY_TYPE);
- // Folded array allocation should be aligned if it has fast double elements.
- if (IsFastDoubleElementsKind(kind_)) {
- new_object->MakeDoubleAligned();
mvstanton 2013/11/14 10:04:20 Why was this removed, is it handled during the fol
Igor Sheludko 2013/11/27 12:52:01 This flag is set in the constructor of the HAlloca
- }
-
// Fill in the fields: map, properties, length
HValue* map;
if (allocation_site_payload_ == NULL) {
@@ -2489,22 +2460,30 @@ HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
} else {
map = EmitMapCode();
}
- elements_location_ = builder()->BuildJSArrayHeader(new_object,
- map,
- mode_,
- kind_,
- allocation_site_payload_,
- length_field);
- // Initialize the elements
+ builder()->BuildJSArrayHeader(array_object,
+ map,
+ mode_,
+ kind_,
+ allocation_site_payload_,
+ length_field);
+
+ // Allocate and initialize the elements
+ elements_location_ =
+ builder()->BuildAllocateElements(kind_, elms_size, NOT_TENURED);
+
builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity);
+ // Set the elements
+ builder()->Add<HStoreNamedField>(
+ array_object, HObjectAccess::ForElementsPointer(), elements_location_);
+
mvstanton 2013/11/14 10:04:20 Can you verify that a write barrier isn't used for
Igor Sheludko 2013/11/27 12:52:01 If two allocations folds together then the second
if (fill_with_hole) {
builder()->BuildFillElementsWithHole(elements_location_, kind_,
graph()->GetConstant0(), capacity);
}
- return new_object;
+ return array_object;
}
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | src/hydrogen-instructions.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698