Reviewers: Hannes Payer,
Message:
PTAL
Description:
Propagation of allocation size's upper bound to allocation folding.
Please review this at https://codereview.chromium.org/85493002/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+61, -14 lines):
M src/hydrogen-instructions.h
M src/hydrogen.h
M src/hydrogen.cc
Index: src/hydrogen-instructions.h
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index
fba23fa0ca4ae113b424d9f45b3bd17027e37c20..94ef410f40a7e86e48c9f3476d2da69d7ff274e7
100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -5443,6 +5443,10 @@ class HAllocate V8_FINAL : public
HTemplateInstruction<2> {
HValue* context() { return OperandAt(0); }
HValue* size() { return OperandAt(1); }
+ bool has_size_upper_bound() { return size_upper_bound_ != NULL; }
+ HConstant* size_upper_bound() { return size_upper_bound_; }
+ void set_size_upper_bound(HConstant* value) { size_upper_bound_ = value;
}
+
virtual Representation RequiredInputRepresentation(int index)
V8_OVERRIDE {
if (index == 0) {
return Representation::Tagged();
@@ -5511,9 +5515,10 @@ class HAllocate V8_FINAL : public
HTemplateInstruction<2> {
: HTemplateInstruction<2>(type),
dominating_allocate_(NULL),
filler_free_space_size_(NULL),
+ size_upper_bound_(NULL),
clear_next_map_word_(false) {
SetOperandAt(0, context);
- SetOperandAt(1, size);
+ UpdateSize(size);
set_representation(Representation::Tagged());
SetFlag(kTrackSideEffectDominators);
SetGVNFlag(kChangesNewSpacePromotion);
@@ -5539,6 +5544,11 @@ class HAllocate V8_FINAL : public
HTemplateInstruction<2> {
void UpdateSize(HValue* size) {
SetOperandAt(1, size);
+ if (size->IsInteger32Constant()) {
+ size_upper_bound_ = HConstant::cast(size);
+ } else {
+ size_upper_bound_ = NULL;
+ }
}
HAllocate* GetFoldableDominator(HAllocate* dominator);
@@ -5560,6 +5570,7 @@ class HAllocate V8_FINAL : public
HTemplateInstruction<2> {
Handle<Map> known_initial_map_;
HAllocate* dominating_allocate_;
HStoreNamedField* filler_free_space_size_;
+ HConstant* size_upper_bound_;
bool clear_next_map_word_;
};
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index
3e08b69c6fcc06d14ab6128a928a4ff940cca523..70258a7d5910e0d69b23601b73b53ce853c918cc
100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -2163,7 +2163,7 @@ HValue* HGraphBuilder::BuildAllocateArrayFromLength(
// Figure out total size
HValue* length = Pop();
HValue* capacity = Pop();
- return array_builder->AllocateArray(capacity, length);
+ return array_builder->AllocateArray(capacity, max_alloc_length, length);
}
HValue* HGraphBuilder::BuildAllocateElements(ElementsKind kind,
@@ -2692,24 +2692,26 @@ HValue*
HGraphBuilder::JSArrayBuilder::EstablishAllocationSize(
}
-HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize()
{
+HConstant* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize(
+ int capacity) {
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());
+ ? FixedDoubleArray::SizeFor(capacity)
+ : FixedArray::SizeFor(capacity);
return builder()->Add<HConstant>(base_size);
}
HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() {
- HValue* size_in_bytes = EstablishEmptyArrayAllocationSize();
+ HValue* size_in_bytes = EstablishAllocationSize(initial_capacity());
HConstant* capacity = builder()->Add<HConstant>(initial_capacity());
return AllocateArray(size_in_bytes,
+ NULL,
capacity,
builder()->graph()->GetConstant0());
}
@@ -2718,15 +2720,35 @@ HValue*
HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() {
HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity,
HValue* length_field,
FillMode fill_mode) {
+ return AllocateArray(capacity, NULL, length_field, fill_mode);
+}
+
+
+HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(
+ HValue* capacity,
+ HConstant* capacity_upper_bound,
+ HValue* length_field,
+ FillMode fill_mode) {
HValue* size_in_bytes = EstablishAllocationSize(capacity);
- return AllocateArray(size_in_bytes, capacity, length_field, fill_mode);
+
+ HConstant* size_in_bytes_upper_bound = NULL;
+ if (!size_in_bytes->IsConstant() && (capacity_upper_bound != NULL)) {
+ ASSERT(capacity_upper_bound->IsInteger32Constant());
+ // Propagate upper bound further only if |size_in_bytes| is not
constant.
+ size_in_bytes_upper_bound =
+
EstablishAllocationSize(capacity_upper_bound->GetInteger32Constant());
+ }
+ return AllocateArray(size_in_bytes, size_in_bytes_upper_bound,
+ capacity, length_field, fill_mode);
}
-HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
- HValue* capacity,
- HValue* length_field,
- FillMode fill_mode) {
+HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(
+ HValue* size_in_bytes,
+ HConstant* size_in_bytes_upper_bound,
+ HValue* capacity,
+ HValue* length_field,
+ FillMode fill_mode) {
// 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.
@@ -2739,6 +2761,9 @@ HValue*
HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
// Allocate (dealing with failure appropriately)
HAllocate* new_object = builder()->Add<HAllocate>(size_in_bytes,
HType::JSArray(), NOT_TENURED, JS_ARRAY_TYPE);
+ if (size_in_bytes_upper_bound != NULL) {
+ new_object->set_size_upper_bound(size_in_bytes_upper_bound);
+ }
// Folded array allocation should be aligned if it has fast double
elements.
if (IsFastDoubleElementsKind(kind_)) {
Index: src/hydrogen.h
diff --git a/src/hydrogen.h b/src/hydrogen.h
index
e0c50662f2d2e5401c2636d2fd6809532f6f2a3b..543a04a33f7a9ec0e262648ae508c149fc88f67e
100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -1630,7 +1630,16 @@ class HGraphBuilder {
ElementsKind kind() { return kind_; }
HValue* AllocateEmptyArray();
- HValue* AllocateArray(HValue* capacity, HValue* length_field,
+ HValue* AllocateArray(HValue* capacity,
+ HValue* length_field,
+ FillMode fill_mode = FILL_WITH_HOLE);
+ // Use this allocator when capacity could be unknown at compile time
+ // but its limit is known. For constant |capacity| the value of
+ // |capacity_upper_bound| is ignored and the actual |capacity|
+ // value is used as an upper bound.
+ HValue* AllocateArray(HValue* capacity,
+ HConstant* capacity_upper_bound,
+ HValue* length_field,
FillMode fill_mode = FILL_WITH_HOLE);
HValue* GetElementsLocation() { return elements_location_; }
HValue* EmitMapCode();
@@ -1648,9 +1657,11 @@ class HGraphBuilder {
}
HValue* EmitInternalMapCode();
- HValue* EstablishEmptyArrayAllocationSize();
+ HConstant* EstablishAllocationSize(int capacity);
HValue* EstablishAllocationSize(HValue* length_node);
- HValue* AllocateArray(HValue* size_in_bytes, HValue* capacity,
+ HValue* AllocateArray(HValue* size_in_bytes,
+ HConstant* size_in_bytes_upper_bound,
+ HValue* capacity,
HValue* length_field,
FillMode fill_mode = FILL_WITH_HOLE);
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.