Chromium Code Reviews| Index: src/hydrogen.cc |
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
| index 8d3a0ac813a90a6014ac6185473406c2ca5e8927..dfbd9021fbc6308ecde4d99ec1445e8c05f00b8d 100644 |
| --- a/src/hydrogen.cc |
| +++ b/src/hydrogen.cc |
| @@ -989,13 +989,6 @@ void HGraphBuilder::AddSimulate(BailoutId id, |
| } |
| -HBoundsCheck* HGraphBuilder::AddBoundsCheck(HValue* index, HValue* length) { |
| - HBoundsCheck* result = new(graph()->zone()) HBoundsCheck(index, length); |
| - AddInstruction(result); |
| - return result; |
| -} |
| - |
| - |
| HReturn* HGraphBuilder::AddReturn(HValue* value) { |
| HValue* context = environment()->LookupContext(); |
| int num_parameters = graph()->info()->num_parameters(); |
| @@ -1175,7 +1168,7 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, |
| length_checker.Else(); |
| - AddBoundsCheck(key, length); |
| + Add<HBoundsCheck>(key, length); |
| environment()->Push(elements); |
| length_checker.End(); |
| @@ -1280,7 +1273,7 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( |
| return result; |
| } else { |
| ASSERT(store_mode == STANDARD_STORE); |
| - checked_key = AddBoundsCheck(key, length); |
| + checked_key = Add<HBoundsCheck>(key, length); |
| HLoadExternalArrayPointer* external_elements = |
| new(zone) HLoadExternalArrayPointer(elements); |
| AddInstruction(external_elements); |
| @@ -1308,7 +1301,7 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( |
| length, key, is_js_array); |
| checked_key = key; |
| } else { |
| - checked_key = AddBoundsCheck(key, length); |
| + checked_key = Add<HBoundsCheck>(key, length); |
| if (is_store && (fast_elements || fast_smi_only_elements)) { |
| if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) { |
| @@ -4657,9 +4650,9 @@ void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) { |
| } |
| -void HOptimizedGraphBuilder::AddSoftDeoptimize() { |
| +void HOptimizedGraphBuilder::AddSoftDeoptimize(SoftDeoptimizeMode mode) { |
| isolate()->counters()->soft_deopts_requested()->Increment(); |
| - if (FLAG_always_opt) return; |
| + if (FLAG_always_opt && mode == CAN_OMIT_SOFT_DEOPT) return; |
| if (current_block()->IsDeoptimizing()) return; |
| AddInstruction(new(zone()) HSoftDeoptimize()); |
| isolate()->counters()->soft_deopts_inserted()->Increment(); |
| @@ -5627,9 +5620,16 @@ void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
| if (type == kUseCell) { |
| Handle<GlobalObject> global(current_info()->global_object()); |
| Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); |
| - HLoadGlobalCell* instr = |
| - new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails()); |
| - return ast_context()->ReturnInstruction(instr, expr->id()); |
| + if (cell->type()->IsConstant()) { |
| + cell->AddDependentCompilationInfo(top_info()); |
| + HConstant* constant = |
| + new(zone()) HConstant(cell->type()->AsConstant()); |
| + return ast_context()->ReturnInstruction(constant, expr->id()); |
| + } else { |
| + HLoadGlobalCell* instr = |
| + new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails()); |
| + return ast_context()->ReturnInstruction(instr, expr->id()); |
| + } |
| } else { |
| HValue* context = environment()->LookupContext(); |
| HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
| @@ -6552,6 +6552,15 @@ void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( |
| if (type == kUseCell) { |
| Handle<GlobalObject> global(current_info()->global_object()); |
| Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); |
| + if (cell->type()->IsConstant()) { |
| + IfBuilder builder(this); |
| + HValue* constant = Add<HConstant>(cell->type()->AsConstant()); |
| + builder.If<HCompareObjectEqAndBranch>(value, constant); |
| + builder.Then(); |
| + builder.Else(); |
| + AddSoftDeoptimize(MUST_EMIT_SOFT_DEOPT); |
|
rossberg
2013/06/25 10:47:38
I'm a bit at a loss why this flag is needed.
danno
2013/06/28 13:56:05
Most soft deopts are only for performance. Without
|
| + builder.End(); |
| + } |
| HInstruction* instr = |
| new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); |
| instr->set_position(position); |
| @@ -7290,7 +7299,7 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( |
| && todo_external_array) { |
| HInstruction* length = |
| AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
| - checked_key = AddBoundsCheck(key, length); |
| + checked_key = Add<HBoundsCheck>(key, length); |
| external_elements = new(zone()) HLoadExternalArrayPointer(elements); |
| AddInstruction(external_elements); |
| } |
| @@ -7333,7 +7342,7 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( |
| typecheck, Representation::Smi()); |
| length->set_type(HType::Smi()); |
| - checked_key = AddBoundsCheck(key, length); |
| + checked_key = Add<HBoundsCheck>(key, length); |
| access = AddInstruction(BuildFastElementAccess( |
| elements, checked_key, val, elements_kind_branch, |
| elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); |
| @@ -7351,7 +7360,7 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( |
| set_current_block(if_fastobject); |
| length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
| - checked_key = AddBoundsCheck(key, length); |
| + checked_key = Add<HBoundsCheck>(key, length); |
| access = AddInstruction(BuildFastElementAccess( |
| elements, checked_key, val, elements_kind_branch, |
| elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); |
| @@ -7503,7 +7512,7 @@ bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) { |
| new(zone()) HArgumentsElements(false)); |
| HInstruction* length = AddInstruction( |
| new(zone()) HArgumentsLength(elements)); |
| - HInstruction* checked_key = AddBoundsCheck(key, length); |
| + HInstruction* checked_key = Add<HBoundsCheck>(key, length); |
| result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); |
| } else { |
| EnsureArgumentsArePushedForAccess(); |
| @@ -7514,7 +7523,7 @@ bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) { |
| arguments_environment()->parameter_count() - 1; |
| HInstruction* length = AddInstruction(new(zone()) HConstant( |
| argument_count)); |
| - HInstruction* checked_key = AddBoundsCheck(key, length); |
| + HInstruction* checked_key = Add<HBoundsCheck>(key, length); |
| result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); |
| } |
| } |
| @@ -8893,7 +8902,7 @@ void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { |
| Handle<Cell> cell = expr->allocation_info_cell(); |
| AddInstruction(new(zone()) HCheckFunction(constructor, array_function)); |
| call = new(zone()) HCallNewArray(context, constructor, argument_count, |
| - cell); |
| + cell, expr->elements_kind()); |
| } else { |
| call = new(zone()) HCallNew(context, constructor, argument_count); |
| } |
| @@ -9343,7 +9352,7 @@ HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt( |
| AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
| HInstruction* length = HStringLength::New(zone(), string); |
| AddInstruction(length); |
| - HInstruction* checked_index = AddBoundsCheck(index, length); |
| + HInstruction* checked_index = Add<HBoundsCheck>(index, length); |
| return new(zone()) HStringCharCodeAt(context, string, checked_index); |
| } |
| @@ -9998,10 +10007,22 @@ void HOptimizedGraphBuilder::BuildEmitDeepCopy( |
| } |
| // Copy in-object properties. |
| - HValue* object_properties = |
| - AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); |
| - BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object, |
| - object_properties, target, offset); |
| + Handle<DescriptorArray> descriptors( |
| + boilerplate_object->map()->instance_descriptors()); |
| + int descriptor_count = boilerplate_object->map()->NumberOfOwnDescriptors(); |
| + bool has_field = false; |
| + for (int i = 0; i < descriptor_count; i++) { |
| + PropertyDetails details = descriptors->GetDetails(i); |
| + if (details.type() != FIELD) continue; |
| + has_field = true; |
| + } |
| + |
| + if (has_field) { |
| + HValue* object_properties = |
| + AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); |
| + BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object, |
| + object_properties, target, offset); |
| + } |
| // Create allocation site info. |
| if (mode == TRACK_ALLOCATION_SITE && |
| @@ -10510,7 +10531,7 @@ void HOptimizedGraphBuilder::GenerateArguments(CallRuntime* call) { |
| HInstruction* elements = AddInstruction( |
| new(zone()) HArgumentsElements(false)); |
| HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements)); |
| - HInstruction* checked_index = AddBoundsCheck(index, length); |
| + HInstruction* checked_index = Add<HBoundsCheck>(index, length); |
| HAccessArgumentsAt* result = |
| new(zone()) HAccessArgumentsAt(elements, length, checked_index); |
| return ast_context()->ReturnInstruction(result, call->id()); |