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

Unified Diff: src/hydrogen.cc

Issue 20726002: Fix for V8 issue 2795: Check fails with deopt for mjsunit/array-store-and-grow (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Removed overkillin' wrapper Created 7 years, 5 months 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
« no previous file with comments | « no previous file | src/hydrogen-instructions.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index e34688051d53f9fa75691d6db382ddcc18795c6c..4084ea669989d5f5d34c856447d88e718dd594fe 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -1078,8 +1078,16 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object,
HValue* context = environment()->LookupContext();
- HValue* new_capacity = BuildNewElementsCapacity(context, key);
+ HValue* max_gap = Add<HConstant>(static_cast<int32_t>(JSObject::kMaxGap));
+ HValue* max_capacity = AddInstruction(
+ HAdd::New(zone, context, current_capacity, max_gap));
+ IfBuilder key_checker(this);
+ key_checker.If<HCompareNumericAndBranch>(key, max_capacity, Token::LT);
+ key_checker.Then();
+ key_checker.ElseDeopt();
+ key_checker.End();
+ HValue* new_capacity = BuildNewElementsCapacity(context, key);
HValue* new_elements = BuildGrowElementsCapacity(object, elements,
kind, kind, length,
new_capacity);
@@ -1337,6 +1345,9 @@ HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader(
HValue* context,
ElementsKind kind,
HValue* capacity) {
+ // 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(context, kind, capacity);
BuildInitializeElementsHeader(new_elements, kind, capacity);
return new_elements;
@@ -1474,7 +1485,6 @@ HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context,
HValue* half_old_capacity =
AddInstruction(HShr::New(zone, context, old_capacity,
graph_->GetConstant1()));
- half_old_capacity->ClearFlag(HValue::kCanOverflow);
HValue* new_capacity = AddInstruction(
HAdd::New(zone, context, half_old_capacity, old_capacity));
@@ -1497,8 +1507,6 @@ void HGraphBuilder::BuildNewSpaceArrayCheck(HValue* length, ElementsKind kind) {
int max_size = heap->MaxRegularSpaceAllocationSize() / element_size;
max_size -= JSArray::kSize / element_size;
HConstant* max_size_constant = Add<HConstant>(max_size);
- // Since we're forcing Integer32 representation for this HBoundsCheck,
- // there's no need to Smi-check the index.
Add<HBoundsCheck>(length, max_size_constant);
}
@@ -1927,6 +1935,14 @@ HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
bool fill_with_hole) {
HValue* context = builder()->environment()->LookupContext();
+ // 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.
+ capacity = builder()->Add<HForceRepresentation>(capacity,
+ Representation::Smi());
+ length_field = builder()->Add<HForceRepresentation>(length_field,
+ Representation::Smi());
+
// Allocate (dealing with failure appropriately)
HAllocate::Flags flags = HAllocate::DefaultFlags(kind_);
HAllocate* new_object = builder()->Add<HAllocate>(context, size_in_bytes,
« no previous file with comments | « no previous file | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698