| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index 0875f29112247f6288472a2c9430fbd4fc1c82ab..e34688051d53f9fa75691d6db382ddcc18795c6c 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -44,7 +44,6 @@
|
| #include "hydrogen-infer-representation.h"
|
| #include "hydrogen-infer-types.h"
|
| #include "hydrogen-gvn.h"
|
| -#include "hydrogen-mark-deoptimize.h"
|
| #include "hydrogen-minus-zero.h"
|
| #include "hydrogen-osr.h"
|
| #include "hydrogen-range-analysis.h"
|
| @@ -987,19 +986,6 @@ HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
|
| }
|
|
|
|
|
| -void HGraphBuilder::AddIncrementCounter(StatsCounter* counter,
|
| - HValue* context) {
|
| - if (FLAG_native_code_counters && counter->Enabled()) {
|
| - HValue* reference = Add<HConstant>(ExternalReference(counter));
|
| - HValue* old_value = AddLoad(reference, HObjectAccess::ForCounter(), NULL);
|
| - HValue* new_value = AddInstruction(
|
| - HAdd::New(zone(), context, old_value, graph()->GetConstant1()));
|
| - new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow
|
| - AddStore(reference, HObjectAccess::ForCounter(), new_value);
|
| - }
|
| -}
|
| -
|
| -
|
| HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) {
|
| HBasicBlock* b = graph()->CreateBasicBlock();
|
| b->SetInitialEnvironment(env);
|
| @@ -1092,16 +1078,8 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object,
|
|
|
| HValue* context = environment()->LookupContext();
|
|
|
| - 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);
|
| @@ -1359,9 +1337,6 @@ 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;
|
| @@ -1499,6 +1474,7 @@ 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));
|
| @@ -1521,6 +1497,8 @@ 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);
|
| }
|
|
|
| @@ -1949,14 +1927,6 @@ 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,
|
| @@ -2515,6 +2485,38 @@ void HGraph::CollectPhis() {
|
| }
|
|
|
|
|
| +void HGraph::RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi* phi) {
|
| + if (!phi->CheckFlag(HValue::kAllowUndefinedAsNaN)) return;
|
| + phi->ClearFlag(HValue::kAllowUndefinedAsNaN);
|
| + for (int i = 0; i < phi->OperandCount(); ++i) {
|
| + HValue* input = phi->OperandAt(i);
|
| + if (input->IsPhi()) {
|
| + RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi::cast(input));
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +void HGraph::MarkDeoptimizeOnUndefined() {
|
| + HPhase phase("H_MarkDeoptimizeOnUndefined", this);
|
| + // Compute DeoptimizeOnUndefined flag for phis. Any phi that can reach a use
|
| + // with DeoptimizeOnUndefined set must have DeoptimizeOnUndefined set.
|
| + // Currently only HCompareNumericAndBranch, with double input representation,
|
| + // has this flag set. The flag is used by HChange tagged->double, which must
|
| + // deoptimize if one of its uses has this flag set.
|
| + for (int i = 0; i < phi_list()->length(); i++) {
|
| + HPhi* phi = phi_list()->at(i);
|
| + for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) {
|
| + HValue* use_value = it.value();
|
| + if (!use_value->CheckFlag(HValue::kAllowUndefinedAsNaN)) {
|
| + RecursivelyMarkPhiDeoptimizeOnUndefined(phi);
|
| + break;
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| // Implementation of utility class to encapsulate the translation state for
|
| // a (possibly inlined) function.
|
| FunctionState::FunctionState(HOptimizedGraphBuilder* owner,
|
| @@ -2987,7 +2989,7 @@ bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) {
|
| // This must happen after inferring representations.
|
| Run<HMergeRemovableSimulatesPhase>();
|
|
|
| - Run<HMarkDeoptimizeOnUndefinedPhase>();
|
| + MarkDeoptimizeOnUndefined();
|
| Run<HRepresentationChangesPhase>();
|
|
|
| Run<HInferTypesPhase>();
|
|
|